awsm-renderer 0.3.2

awsm-renderer
Documentation
//***** MAIN *****
struct VertexInput {
    @builtin(vertex_index) vertex_index: u32,
    @location(0) position: vec3<f32>,      // Model-space position
    @location(1) normal: vec3<f32>,        // Model-space normal
    @location(2) tangent: vec4<f32>,       // Model-space tangent (w = handedness)
    {% if instancing_transforms %}
    // instance transform matrix
    @location(3) instance_transform_row_0: vec4<f32>,
    @location(4) instance_transform_row_1: vec4<f32>,
    @location(5) instance_transform_row_2: vec4<f32>,
    @location(6) instance_transform_row_3: vec4<f32>,
    {% endif %}

    {% for i in 0..color_sets %}
        @location({{ in_color_set_start + i }}) color_{{ i }}: vec4<f32>,
    {% endfor %}

    {% for i in 0..uv_sets %}
        @location({{ in_uv_set_start + i }}) uv_{{ i }}: vec2<f32>,
    {% endfor %}
};

struct VertexOutput {
    @builtin(position) clip_position: vec4<f32>,
    @location(0) world_position: vec3<f32>,     // Transformed world position
    @location(1) world_normal: vec3<f32>,     // Transformed world-space normal
    @location(2) world_tangent: vec4<f32>,    // Transformed world-space tangent (w = handedness)
    // Per-fragment instance_id, plumbed through for the Stage-3b per-instance
    // tint applied at the end of fs_main. `INSTANCE_ATTR_NONE` (`u32::MAX`)
    // means "non-instanced" → identity tint.
    @location(3) @interpolate(flat) instance_id: u32,

    {% for i in 0..color_sets %}
        @location({{ out_color_set_start + i }}) color_{{ i }}: vec4<f32>,
    {% endfor %}

    {% for i in 0..uv_sets %}
        @location({{ out_uv_set_start + i }}) uv_{{ i }}: vec2<f32>,
    {% endfor %}
}

@vertex
fn vert_main(
    input: VertexInput,
    @builtin(instance_index) instance_index: u32,
) -> VertexOutput {
    var out: VertexOutput;

    let camera = camera_from_raw(camera_raw);
    let frame_globals = frame_globals_from_raw(frame_globals_raw);

    // Per-fragment instance_id derived from geometry_mesh_meta.instance_attr_base
    // + the GPU's @builtin(instance_index). Non-instanced meshes carry the
    // sentinel through unchanged so the fragment side branches identically
    // to the opaque path's MSAA helper. Computed before `apply_vertex` so the
    // custom-vertex hook can receive it.
    let base = geometry_mesh_meta.instance_attr_base;
    var instance_id: u32;
    if (base == INSTANCE_ATTR_NONE) {
        instance_id = INSTANCE_ATTR_NONE;
    } else {
        instance_id = base + instance_index;
    }

    {% if has_custom_vertex %}
    // Build the per-vertex UV array from this pass's REAL per-mesh uv
    // attributes (the transparent pass has them directly — no
    // `_mask_uv_per_vertex` reconstruction needed). Sets beyond `uv_sets` are
    // (0,0); `uv_count = uv_sets`.
    var _cv_uv: array<vec2<f32>, 4>;
    {% for i in 0..4 %}
        {% if i < uv_sets %}
            _cv_uv[{{ i }}] = input.uv_{{ i }};
        {% else %}
            _cv_uv[{{ i }}] = vec2<f32>(0.0, 0.0);
        {% endif %}
    {% endfor %}
    let _cv_uv_count = {{ uv_sets }}u;
    {% endif %}

    let applied = apply_vertex(ApplyVertexInput(
        input.vertex_index,
        input.position,
        input.normal,
        input.tangent,
        {% if instancing_transforms %}
            input.instance_transform_row_0,
            input.instance_transform_row_1,
            input.instance_transform_row_2,
            input.instance_transform_row_3,
        {% endif %}
    ), camera {% if has_custom_vertex %}, _cv_uv, _cv_uv_count, instance_id, frame_globals {% endif %});

    out.clip_position = applied.clip_position;
    out.world_position = applied.world_position;
    out.world_normal = applied.world_normal;
    out.world_tangent = applied.world_tangent;

    out.instance_id = instance_id;

    {% for i in 0..color_sets %}
        out.color_{{ i }} = input.color_{{ i }};
    {% endfor %}

    {% for i in 0..uv_sets %}
        out.uv_{{ i }} = input.uv_{{ i }};
    {% endfor %}

    return out;
}