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