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
|
// offscreen rendering shaders
@vs vs_offscreen
layout(binding=0) uniform vs_params {
vec2 position;
};
in vec2 vpos;
out vec2 fpos;
void main() {
gl_Position = vec4(vpos + position, 0, 1);
fpos = (vpos + 1) * 0.5;
}
@end
@fs fs_offscreen
layout(binding=1) uniform texture2D off_tex;
layout(binding=1) uniform sampler off_smp;
layout(binding=1) uniform fs_params {
vec2 resolution;
int rayCount;
int maxSteps;
float size;
};
in vec2 fpos;
out vec4 frag_color;
bool outOfBounds(vec2 uv) {
return uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0;
}
#define TAU 6.28318530718
// #define RAYCOUNT 16
// #define MAXSTEPS 8
float rand(vec2 seed)
{
return fract(sin(dot(seed.xy, vec2(12.9898, 78.233))) * 43758.5453);
}
vec4 raymarch() {
vec2 scale = resolution.xy / resolution.xy;
// sample texture at pixel
vec4 light = textureLod(sampler2D(off_tex, off_smp), fpos * scale, 0);
// if it is a light source, color that pixel in this color
if (light.a > 0.1)
{
return light;
}
float oneOverRayCount = 1.0 / float(rayCount);
float tauOverRayCount = TAU * oneOverRayCount;
float noise = rand(fpos);
vec4 radiance = vec4(0.0);
for (int i = 0; i < rayCount; i++)
{
float angle = tauOverRayCount * (float(i) + noise);
vec2 rayDirectionUv = vec2(cos(angle), -sin(angle)) / size;
vec2 sampleUv = fpos + rayDirectionUv;
for (int step = 0; step < maxSteps; step++)
{
if (outOfBounds(sampleUv))
break;
vec4 sampleLight = textureLod(sampler2D(off_tex, off_smp), sampleUv, 0);
if (sampleLight.a > 0.1)
{
radiance += sampleLight;
break;
}
sampleUv += rayDirectionUv;
}
}
return radiance * oneOverRayCount;
}
void main() {
frag_color = raymarch();
}
@end
@program offscreen vs_offscreen fs_offscreen
// default-pass shaders
@vs vs_default
in vec2 vpos;
out vec2 fpos;
void main() {
gl_Position = vec4(vpos, 0, 1);
fpos = (vpos + 1) * 0.5;
}
@end
@fs fs_default
layout(binding=0) uniform texture2D scr_tex;
layout(binding=0) uniform sampler scr_smp;
in vec2 fpos;
out vec4 frag_color;
void main() {
frag_color = texture(sampler2D(scr_tex, scr_smp), fpos);
}
@end
@program default vs_default fs_default
|