Skip to content

Commit 287a0fc

Browse files
Mandelbulb 3D fractal.
1 parent d4303fa commit 287a0fc

File tree

1 file changed

+203
-0
lines changed

1 file changed

+203
-0
lines changed

Diff for: mandelbulb.shader

+203
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
//original source: https://www.shadertoy.com/view/MdXSWn
2+
//Licence Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)
3+
//translated from GLSL to HLSL by Przemyslaw Zaworski
4+
//https://github.com/przemyslawzaworski/Unity3D-CG-programming
5+
//Enable _isFullscreen for Graphics.Blit or disable for usage in a scene game object (like quad etc.)
6+
7+
Shader "Mandelbulb"
8+
{
9+
Properties
10+
{
11+
[Toggle] _isFullscreen("Is fullscreen?", Float) = 1
12+
}
13+
Subshader
14+
{
15+
Pass
16+
{
17+
CGPROGRAM
18+
#pragma vertex vertex_shader
19+
#pragma fragment pixel_shader
20+
#pragma target 3.0
21+
22+
struct structure
23+
{
24+
float4 screen_vertex : SV_POSITION;
25+
float2 uv : TEXCOORD0;
26+
};
27+
28+
float _isFullscreen,stime, ctime;
29+
float pixel_size = 0.0;
30+
31+
void ry(inout float3 p, float a)
32+
{
33+
float c,s;float3 q=p;
34+
c = cos(a); s = sin(a);
35+
p.x = c * q.x + s * q.z;
36+
p.z = -s * q.x + c * q.z;
37+
}
38+
39+
float3 mb(float3 p)
40+
{
41+
p.xyz = p.xzy;
42+
float3 z = p;
43+
float3 dz=float3(0,0,0);
44+
float power = 8.0;
45+
float r, theta, phi;
46+
float dr = 1.0;
47+
float t0 = 1.0;
48+
for(int i = 0; i < 7; ++i)
49+
{
50+
r = length(z);
51+
if(r > 2.0) continue;
52+
theta = atan(z.y / z.x);
53+
phi = asin(z.z / r);
54+
dr = pow(r, power - 1.0) * dr * power + 1.0;
55+
r = pow(r, power);
56+
theta = theta * power;
57+
phi = phi * power;
58+
z = r * float3(cos(theta)*cos(phi),sin(theta)*cos(phi),sin(phi))+p;
59+
t0 = min(t0, r);
60+
}
61+
return float3(0.5 * log(r) * r / dr, t0, 0.0);
62+
}
63+
64+
float3 f(float3 p)
65+
{
66+
ry(p, _Time.g*0.2);
67+
return mb(p);
68+
}
69+
70+
float softshadow(float3 ro, float3 rd, float k )
71+
{
72+
float akuma=1.0,h=0.0;
73+
float t = 0.01;
74+
for(int i=0; i < 50; ++i)
75+
{
76+
h=f(ro+rd*t).x;
77+
if(h<0.001)return 0.02;
78+
akuma=min(akuma, k*h/t);
79+
t+=clamp(h,0.01,2.0);
80+
}
81+
return akuma;
82+
}
83+
84+
float3 nor( in float3 pos )
85+
{
86+
float3 eps = float3(0.001,0.0,0.0);
87+
return normalize( float3(
88+
f(pos+eps.xyy).x - f(pos-eps.xyy).x,
89+
f(pos+eps.yxy).x - f(pos-eps.yxy).x,
90+
f(pos+eps.yyx).x - f(pos-eps.yyx).x ) );
91+
}
92+
93+
float3 intersect( in float3 ro, in float3 rd )
94+
{
95+
float t = 1.0;
96+
float res_t = 0.0;
97+
float res_d = 1000.0;
98+
float3 c, res_c;
99+
float max_error = 1000.0;
100+
float d = 1.0;
101+
float pd = 100.0;
102+
float os = 0.0;
103+
float step = 0.0;
104+
float error = 1000.0;
105+
for( int i=0; i<48; i++ )
106+
{
107+
if( error < pixel_size*0.5 || t > 20.0 )
108+
{
109+
}
110+
else
111+
{
112+
c = f(ro + rd*t);
113+
d = c.x;
114+
if(d > os)
115+
{
116+
os = 0.4 * d*d/pd;
117+
step = d + os;
118+
pd = d;
119+
}
120+
else
121+
{
122+
step =-os; os = 0.0; pd = 100.0; d = 1.0;
123+
}
124+
error = d / t;
125+
if(error < max_error)
126+
{
127+
max_error = error;
128+
res_t = t;
129+
res_c = c;
130+
}
131+
t += step;
132+
}
133+
}
134+
if( t>20.0/* || max_error > pixel_size*/ ) res_t=-1.0;
135+
return float3(res_t, res_c.y, res_c.z);
136+
}
137+
138+
structure vertex_shader (float4 vertex:POSITION,float2 uv:TEXCOORD0)
139+
{
140+
structure vs;
141+
vs.screen_vertex = UnityObjectToClipPos (vertex);
142+
vs.uv=uv;
143+
return vs;
144+
}
145+
146+
float4 pixel_shader (structure ps ) : SV_TARGET
147+
{
148+
float2 resolution;
149+
if (_isFullscreen)
150+
resolution = _ScreenParams.xy;
151+
else
152+
resolution = float2(1024,1024);
153+
float2 fragCoord = ps.uv*resolution;
154+
float2 q=fragCoord.xy/resolution.xy;
155+
float2 uv = -1.0 + 2.0*q;
156+
uv.x*=resolution.x/resolution.y;
157+
pixel_size = 1.0/(resolution.x * 3.0);
158+
stime=0.7+0.3*sin(_Time.g*0.4);
159+
ctime=0.7+0.3*cos(_Time.g*0.4);
160+
float3 ta=float3(0.0,0.0,0.0);
161+
float3 ro = float3(0.0, 3.*stime*ctime, 3.*(1.-stime*ctime));;
162+
float3 cf = normalize(ta-ro);
163+
float3 cs = normalize(cross(cf,float3(0.0,1.0,0.0)));
164+
float3 cu = normalize(cross(cs,cf));
165+
float3 rd = normalize(uv.x*cs + uv.y*cu + 3.0*cf);
166+
float3 sundir = normalize(float3(0.1, 0.8, 0.6));
167+
float3 sun = float3(1.64, 1.27, 0.99);
168+
float3 skycolor = float3(0.6, 1.5, 1.0);
169+
float3 bg = exp(uv.y-2.0)*float3(0.4, 1.6, 1.0);
170+
float halo=clamp(dot(normalize(float3(-ro.x, -ro.y, -ro.z)), rd), 0.0, 1.0);
171+
float3 col=bg+float3(1.0,0.8,0.4)*pow(halo,17.0);
172+
float t=0.0;
173+
float3 p=ro;
174+
float3 res = intersect(ro, rd);
175+
if(res.x > 0.0)
176+
{
177+
p = ro + res.x * rd;
178+
float3 n=nor(p);
179+
float shadow = softshadow(p, sundir, 10.0 );
180+
float dif = max(0.0, dot(n, sundir));
181+
float sky = 0.6 + 0.4 * max(0.0, dot(n, float3(0.0, 1.0, 0.0)));
182+
float bac = max(0.3 + 0.7 * dot(float3(-sundir.x, -1.0, -sundir.z), n), 0.0);
183+
float spe = max(0.0, pow(clamp(dot(sundir, reflect(rd, n)), 0.0, 1.0), 10.0));
184+
float3 lin = 4.5 * sun * dif * shadow;
185+
lin += 0.8 * bac * sun;
186+
lin += 0.6 * sky * skycolor;
187+
lin += 3.0 * spe;
188+
res.y = pow(clamp(res.y, 0.0, 1.0), 0.55);
189+
float3 tc0 = 0.5 + 0.5 * sin(3.0 + 4.2 * res.y + float3(0.0,0.5,1.0));
190+
col = lin *float3(0.9, 0.8, 0.6) * 0.2 * tc0;
191+
col=lerp(col,bg, 1.0-exp(-0.001*res.x*res.x));
192+
}
193+
col=pow(clamp(col,0.0,1.0),float3(0.45,0.45,0.45));
194+
col=col*0.6+0.4*col*col*(3.0-2.0*col);
195+
float w = dot(col, float3(0.33,0.33,0.33));
196+
col=lerp(col, float3(w,w,w), -0.5);
197+
col*=0.5+0.5*pow(16.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.7);
198+
return float4(col.xyz, 1.0);
199+
}
200+
ENDCG
201+
}
202+
}
203+
}

0 commit comments

Comments
 (0)