struct VertexShaderInput { // Per Vertex uint vertex_id : SV_VertexID; float3 pos; // Per Instance float4 pos_size; float4 uv0uv1; float4 uv2uv3; }; struct VertexShaderOutput { float4 pos : SV_POSITION; float2 uv; }; struct PixelShaderOutput { float4 color : SV_TARGET; }; [[vk::binding(0, 1)]] cbuffer constants { float aspect_ratio; float fovy_degrees; float camera_x; float camera_y; float camera_z; uint map_width; }; float4x4 projection(float fovy, float aspect, float near) { float g = 1.0 / tan(fovy * 0.5); return { g / aspect, 0, 0, 0, 0, g, 0, 0, 0, 0, 0, near, 0, 0, 1, 0, }; } float4x4 view(float3 pos) { return { 1, 0, 0, -pos.x, 0, 1, 0, -pos.y, 0, 0, 1, -pos.z, 0, 0, 0, 1, }; } [shader("vertex")] VertexShaderOutput main_vertex(VertexShaderInput input) { VertexShaderOutput output; float fovy = radians(fovy_degrees); float4x4 view_matrix = view(float3(camera_x, -camera_y, camera_z)); float4x4 projection_matrix = projection(fovy, aspect_ratio, 0.001); float4x4 view_projection_matrix = mul(projection_matrix, view_matrix); output.pos = mul(view_projection_matrix, float4(input.pos_size.xy * float2(1, -1) + input.pos.xy, 0, 1)); switch(input.vertex_id) { case 0: output.uv = input.uv0uv1.xy; break; case 1: output.uv = input.uv0uv1.zw; break; case 2: output.uv = input.uv2uv3.xy; break; case 3: output.uv = input.uv2uv3.zw; break; } return output; } [[vk::binding(0, 2)]] Sampler2D tex1; [shader("pixel")] PixelShaderOutput main_fragment(VertexShaderOutput input) { PixelShaderOutput output; output.color = tex1.Sample(float2(input.uv)); return output; }