Skip to content

Commit 0811e8b

Browse files
Raymarching 3D sierpinski fractal.
1 parent 2535964 commit 0811e8b

File tree

1 file changed

+127
-0
lines changed

1 file changed

+127
-0
lines changed

Diff for: sierpinski.shader

+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
//In Unity3D editor, add quad to Main Camera. Set quad position (0.0;0.0;0.4) and camera position(0,0,-2). Bind material with shader to the quad. Add fly script to the camera. Play.
2+
//source : https://www.shadertoy.com/view/4dl3Wl
3+
Shader "Sierpinski"
4+
{
5+
Subshader
6+
{
7+
Pass
8+
{
9+
CGPROGRAM
10+
#pragma vertex vertex_shader
11+
#pragma fragment pixel_shader
12+
#pragma target 3.0
13+
14+
static const float3 va = float3( 0.0, 0.57735, 0.0 );
15+
static const float3 vb = float3( 0.0, -1.0, 1.15470 );
16+
static const float3 vc = float3( 1.0, -1.0, -0.57735 );
17+
static const float3 vd = float3( -1.0, -1.0, -0.57735 );
18+
static const float precis = 0.0002;
19+
20+
struct custom_type
21+
{
22+
float4 screen_vertex : SV_POSITION;
23+
float3 world_vertex : TEXCOORD1;
24+
};
25+
26+
float2 map( float3 p )
27+
{
28+
float a = 0.0;
29+
float s = 1.0;
30+
float r = 1.0;
31+
float dm;
32+
float3 v;
33+
for( int i=0; i<8; i++ )
34+
{
35+
float d, t;
36+
d = dot(p-va,p-va); v=va; dm=d; t=0.0;
37+
d = dot(p-vb,p-vb); if( d<dm ) { v=vb; dm=d; t=1.0; }
38+
d = dot(p-vc,p-vc); if( d<dm ) { v=vc; dm=d; t=2.0; }
39+
d = dot(p-vd,p-vd); if( d<dm ) { v=vd; dm=d; t=3.0; }
40+
p = v + 2.0*(p - v); r*= 2.0;
41+
a = t + 4.0*a; s*= 4.0;
42+
}
43+
return float2( (sqrt(dm)-1.0)/r, a/s );
44+
}
45+
46+
float3 intersect( in float3 ro, in float3 rd )
47+
{
48+
float3 res = float3( 1e20, 0.0, 0.0 );
49+
float maxd = 5.0;
50+
float h = 1.0;
51+
float t = 0.5;
52+
float m = 0.0;
53+
float2 r;
54+
for( int i=0; i<100; i++ )
55+
{
56+
r = map( ro+rd*t );
57+
if( r.x<precis || t>maxd ) break;
58+
m = r.y;
59+
t += r.x;
60+
}
61+
if( t<maxd && r.x<precis ) res = float3( t, 2.0, m );
62+
return res;
63+
}
64+
65+
float3 calcNormal( in float3 pos )
66+
{
67+
float3 eps = float3(precis,0.0,0.0);
68+
return normalize( float3(
69+
map(pos+eps.xyy).x - map(pos-eps.xyy).x,
70+
map(pos+eps.yxy).x - map(pos-eps.yxy).x,
71+
map(pos+eps.yyx).x - map(pos-eps.yyx).x ) );
72+
}
73+
74+
float calcOcclusion( in float3 pos, in float3 nor )
75+
{
76+
float ao = 0.0;
77+
float sca = 1.0;
78+
for( int i=0; i<8; i++ )
79+
{
80+
float h = 0.001 + 0.5*pow(float(i)/7.0,1.5);
81+
float d = map( pos + h*nor ).x;
82+
ao += -(d-h)*sca;
83+
sca *= 0.95;
84+
}
85+
return clamp( 1.0 - 0.8*ao, 0.0, 1.0 );
86+
}
87+
88+
float3 render( in float3 ro, in float3 rd )
89+
{
90+
float3 col = float3(0.0,0.0,0.0);
91+
float3 lig = normalize(float3(1.0,0.7,0.9));
92+
float3 tm = intersect(ro,rd);
93+
if( tm.y>0.5 )
94+
{
95+
float3 pos = ro + tm.x*rd;
96+
float3 nor = calcNormal( pos );
97+
float3 maa = float3( 0.0,0.0,0.0 );
98+
maa = 0.5 + 0.5*cos( 6.2831*tm.z + float3(0.0,1.0,2.0) );
99+
float occ = calcOcclusion( pos, nor );
100+
float amb = (0.5 + 0.5*nor.y);
101+
float dif = max(dot(nor,lig),0.0);
102+
float3 lin = 1.5*amb*float3(1.0,1.0,1.0) * occ;
103+
col = maa * lin;
104+
}
105+
return col;
106+
}
107+
108+
custom_type vertex_shader (float4 vertex : POSITION)
109+
{
110+
custom_type vs;
111+
vs.screen_vertex = UnityObjectToClipPos (vertex);
112+
vs.world_vertex = mul (unity_ObjectToWorld, vertex);
113+
return vs;
114+
}
115+
116+
float4 pixel_shader (custom_type ps ) : SV_TARGET
117+
{
118+
float3 worldPosition = ps.world_vertex;
119+
float3 viewDirection = normalize(ps.world_vertex - _WorldSpaceCameraPos.xyz);
120+
return float4(render (worldPosition,viewDirection),1.0);
121+
}
122+
123+
ENDCG
124+
125+
}
126+
}
127+
}

0 commit comments

Comments
 (0)