1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
typedef float2 vec2;
typedef float3 vec3;
typedef float4 vec4;
#define sin native_sin
#define cos native_cos
#define tan native_tan
#define normalize fast_normalize
#define length fast_length
#define mod fmod
#define time 1.f
vec3 reflect(vec3 I, vec3 N) {
return I - 2.0f * dot(N, I) * N;
}
uint pack_fp4(float4 u4) {
uint u;
u = (((uint) u4.x)) |
(((uint) u4.y) << 8) |
(((uint) u4.z) << 16);
return u;
}
#define OUTPUT do {\
const vec4 final = 255.f * max(min(gl_FragColor, (vec4)(1.f)), (vec4)(0.f)); \
dst[get_global_id(0) + get_global_id(1) * w] = pack_fp4(final); \
} while (0)
float jinteresct(vec3 rO, vec3 rD, vec4 c, float *ao)
{
float mz2,md2,dist,t;
float res=1000.0f;
vec4 z,nz;
int update_ao = 1;
*ao = 0.0f;
for(t=0.0f;t<6.0f;t+=dist)
{
if (update_ao) *ao += 1.0f;
vec3 p=rO+t*rD;
// calc distance
z=(vec4)(p,(c.y+c.x)*.3f);
md2=1.0f;
mz2=dot(z,z);
for(int i=0;i<9;i++)
{
// |dz|^2 -> 4*|dz|^2
//if (mz2 <= 4.0f)
{
md2*=4.0f*mz2;
// z -> z2 + c
nz.x=z.x*z.x-dot(z.yzw,z.yzw);
nz.yzw=2.0f*z.x*z.yzw;
z=nz+c;
mz2=dot(z,z);
}
if(mz2>4.0f)
break;
}
dist=0.25f*sqrt(mz2/md2)*log(mz2);
if(dist<0.0005f)
{
res=t;
break;
}
t+= dist;
}
return res;
}
#if 1
vec3 calcNormal(vec3 p, vec4 c)
{
vec4 nz,ndz,dz[4];
vec4 z=(vec4)(p,(c.y+c.x)*.3f);
dz[0]=(vec4)(1.0f,0.0f,0.0f,0.0f);
dz[1]=(vec4)(0.0f,1.0f,0.0f,0.0f);
dz[2]=(vec4)(0.0f,0.0f,1.0f,0.0f);
//dz[3]=(vec4)(0.0f,0.0f,0.0f,1.0f);
for(int i=0;i<9;i++)
{
vec4 mz = (vec4)(z.x,-z.y,-z.z,-z.w);
// derivative
dz[0]=(vec4)(dot(mz,dz[0]),z.x*dz[0].yzw+dz[0].x*z.yzw);
dz[1]=(vec4)(dot(mz,dz[1]),z.x*dz[1].yzw+dz[1].x*z.yzw);
dz[2]=(vec4)(dot(mz,dz[2]),z.x*dz[2].yzw+dz[2].x*z.yzw);
//dz[3]=(vec4)(dot(mz,dz[3]),z.x*dz[3].yzw+dz[3].x*z.yzw);
// z = z2 + c
nz.x=dot(z, mz);
nz.yzw=2.0f*z.x*z.yzw;
z=nz+c;
if(dot(z,z)>4.0f)
break;
}
return normalize((vec3)(dot(z,dz[0]),dot(z,dz[1]),dot(z,dz[2])));
}
#endif
__kernel void compiler_julia(__global uint *dst, float resx, float resy, int w)
{
vec2 gl_FragCoord = (vec2)(get_global_id(0), get_global_id(1));
vec2 p=-1.0f+2.0f*gl_FragCoord.xy/(vec2)(resx,resy);
vec3 color = (vec3)(0.0f);
vec4 cccc = (vec4)( .7f*cos(.5f*time), .7f*sin(.3f*time), .7f*cos(1.0f*time), 0.0f );
vec3 edir = normalize((vec3)(p,1.0f));
vec3 wori = (vec3)(0.0f,0.0f,-2.0f);
float ao;
float t = jinteresct(wori,edir,cccc,&ao);
if(t<100.0f)
{
#if 1
vec3 inter = wori + t*edir;
vec3 nor = calcNormal(inter,cccc);
float dif = .5f + .5f*dot( nor, (vec3)(0.57703f) );
ao = max( 1.0f-ao*0.005f, 0.0f);
color = (vec3)(1.0f,.9f,.5f)*dif*ao + .5f*(vec3)(.6f,.7f,.8f)*ao;
#else
color = (vec3)(0.5f,0.0f,0.0f);
#endif
}
else
{
color = (vec3)(0.5f,0.51f,0.52f)+(vec3)(0.5f,0.47f,0.45f)*p.y;
}
vec4 gl_FragColor = (vec4)(color,1.0f);
OUTPUT;
}
|