summaryrefslogtreecommitdiff
path: root/shader.wgsl
blob: ac43a4443935f63319e72deab424bcf5654602df (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
struct VertexInput {
    @location(0) position: vec3<f32>,
    @location(1) normal: vec3<f32>,
    @location(2) uv: vec2<f32>,
    @location(3) block: vec3<f32>,
    @location(4) material: f32,
};

struct VertexOutput {
    @builtin(position) position: vec4<f32>,
    @location(0) tint: vec3<f32>,
    @location(1) uv: vec2<f32>,
    @location(2) visibility: f32,
    @location(3) material: f32,
};

struct Uniforms {
    proj: mat4x4<f32>,
    view: mat4x4<f32>,
    skyColor: vec3<f32>,
    cameraPos: vec3<f32>,
    raycast: vec3<f32>,
    renderDistance: f32,
};

@group(0) @binding(0) var<uniform> uniforms: Uniforms;
@group(1) @binding(0) var<uniform> tran: mat4x4<f32>;

@vertex
fn vs_main(input: VertexInput) -> VertexOutput {
    var output: VertexOutput;
    var worldPosition = tran * vec4<f32>(input.position, 1.0);
    output.position = uniforms.proj * uniforms.view * worldPosition;
    output.tint = vec3(dot(abs(input.normal), vec3(0.8, 0.9, 0.75)));
    output.uv = input.uv;
    output.material = input.material;

    var dist = distance(uniforms.cameraPos.xz, worldPosition.xz);
    var visibility = 1.0;
    var fogDepth = 16.0;
    if (dist / fogDepth > uniforms.renderDistance - 2) {
        visibility = 1 - (dist - (fogDepth * (uniforms.renderDistance - 2))) / fogDepth;
    }
    output.visibility = clamp(visibility, 0.0, 1.0);

    if (all(uniforms.raycast == input.block)) {
        output.tint = vec3(1.2);
    }

    return output;
}

@group(0) @binding(1) var texSampler: sampler;
@group(0) @binding(2) var texture: texture_2d_array<f32>;

@fragment
fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {
    var color = vec4(input.tint, 1.0) * textureSample(texture, texSampler, input.uv, i32(input.material));
    var skyColor = vec4(uniforms.skyColor, 1.0);
    return mix(skyColor, color, input.visibility);
}