depth_normal.slang

cross platform rendering playground

src/passes/depth_pre/depth_normal.slang

1.81 KB
#include "shared.h"
#include "renderer_types.h"

[[vk::push_constant]]
FwdDrawPushConstants pc;

[shader("vertex")]
VtxOut vsMain(u32 vertexID: SV_VertexID, u32 drawID: SV_DrawIndex, u32 instanceID: SV_InstanceID) {
    VtxOut o;

    FrameUBO frame = *pc.frame;

    u32 item_idx = pc.visible_items[drawID].id;
    RenderItemGPU item = frame.render_items[item_idx];
    SubmeshGPU submesh = frame.submeshes[item.submesh_index];
    TransformGPU xform = frame.transforms[item.instance_id];

    Vertex v = pc.vertex[vertexID + submesh.base_vertex];
    mat3 world3x3 = (mat3)xform.world;
    mat3 normalMat = (mat3)transpose(xform.normal_world);

    vec3 N = v.normal * normalMat;
    vec3 T = v.tangent.xyz * world3x3;
    vec4 worldPos = vec4(v.pos, 1.0) * xform.world;

    o.view_pos = worldPos * frame.view;
    o.clip_pos = o.view_pos * frame.proj;
    o.world_pos = worldPos.xyz;
    o.clip_debug = o.clip_pos;
    o.normal = N;
    o.tangent = vec4(T, v.tangent.w);
    o.uv = v.uv;
    o.material_index = item.material_index;

    return o;
}

[shader("fragment")]
vec4 fsMain(VtxOut input) : SV_Target {
    FrameUBO frame = *pc.frame;

    MaterialGPU material = frame.materials[input.material_index];
    Texture2D albedoTex = material.albedo;
    Texture2D normalTex = material.normal;
    SamplerState sampler = frame.aniso_wrap_mips;

    vec4 albedo = albedoTex.Sample(sampler, input.uv) * material.base_color;
    f32 alpha = albedo.a;

    if (alpha < 0.5) {
        discard;
    }

    vec3 N = normalize(input.normal);
    vec3 T = normalize(input.tangent.xyz);
    T = normalize(T - N * dot(N, T));
    vec3 B = cross(N, T) * input.tangent.w;
    mat3 TBN = mat3(T, B, N);
    vec3 normalTS = normalTex.Sample(sampler, input.uv).xyz * 2.0 - 1.0;
    vec3 normalWS = normalize(normalTS * TBN);

    return vec4(normalWS, 1.0);
}