treesummaryrefslogcommitdiff
path: root/src/shaders/main.glsl
blob: 784176f4cd8ba80fb217242caffbfbd763c6330f (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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//------------------------------------------------------------------------------
//  shaders for offscreen-sapp sample
//------------------------------------------------------------------------------
@header const m = @import("../math.zig")
@ctype mat4 m.Mat4

// 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