treesummaryrefslogcommitdiff
path: root/src/shaders/main.glsl
blob: 68a1e7e2f8edb5ffe70babd6c388665a29ff8cc1 (plain)
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
// offscreen rendering shaders
@vs vs_screen
in vec2 vpos;
out vec2 fpos;

void main() {
    gl_Position = vec4(vpos, 0, 1);
    fpos = (vpos + 1) * 0.5;
}
@end

@fs fs_raymarch
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

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 raymarch vs_screen fs_raymarch


@fs fs_nearest
layout(binding=0) uniform texture2D scr_tex;
layout(binding=0) uniform sampler scr_smp;

in vec2 fpos;

out vec4 frag_color;

void main() {
    vec4 t = texture(sampler2D(scr_tex, scr_smp), fpos);
    frag_color = vec4(fpos.x, fpos.y, 0, 1) + t;
}
@end

@program nearest vs_screen fs_nearest