ConstantBuffer sig : register(b0); /* ========================== * * Vertex shader * ========================== */ Struct(VsInput) { Semantic(u32, SV_InstanceID); Semantic(u32, SV_VertexID); }; Struct(VSOutput) { nointerpolation Semantic(u32, tex_nurid); nointerpolation Semantic(u32, grid_id); Semantic(Vec2, uv); Semantic(Vec4, tint_lin); Semantic(Vec4, emittance_lin); Semantic(Vec4, SV_Position); }; K_ENTRY VSOutput vs(VsInput input) { static const Vec2 unit_quad_verts[4] = { Vec2(-0.5f, -0.5f), Vec2(0.5f, -0.5f), Vec2(0.5f, 0.5f), Vec2(-0.5f, 0.5f) }; StructuredBuffer instances = GpuResourceFromUrid(sig.instances_urid); K_MaterialInstance instance = instances[input.SV_InstanceID]; Vec2 vert = unit_quad_verts[input.SV_VertexID]; Vec2 world_pos = mul(instance.xf, Vec3(vert, 1)).xy; VSOutput output; output.SV_Position = mul(sig.projection, Vec4(world_pos, 0, 1)); output.tex_nurid = instance.tex_nurid; output.grid_id = instance.grid_id; output.uv = instance.uv0 + ((vert + 0.5) * (instance.uv1 - instance.uv0)); output.tint_lin = LinearFromSrgbU32(instance.tint_srgb); output.emittance_lin = LinearFromSrgbVec4(Vec4(instance.light_emittance_srgb, instance.is_light)); return output; } /* ========================== * * Pixel shader * ========================== */ Struct(PsInput) { VSOutput vs; }; Struct(PSOutput) { Semantic(Vec4, SV_Target0); /* Albedo */ Semantic(Vec4, SV_Target1); /* Emittance */ }; K_ENTRY PSOutput ps(PsInput input) { PSOutput output; Vec4 albedo = input.vs.tint_lin; /* Texture */ if (input.vs.tex_nurid < 0xFFFFFFFF) { Texture2D tex = GpuResourceFromNurid(input.vs.tex_nurid); albedo *= tex.Sample(s_point_clamp, input.vs.uv); } /* Grid */ if (input.vs.grid_id < 0xFFFFFFFF) { StructuredBuffer grids = GpuResourceFromUrid(sig.grids_urid); K_MaterialGrid grid = grids[input.vs.grid_id]; Vec2 grid_pos = input.vs.SV_Position.xy + grid.offset; float half_thickness = grid.line_thickness / 2; float spacing = grid.line_spacing; u32 color_srgb = grid.bg0_srgb; Vec2 v = abs(round(grid_pos / spacing) * spacing - grid_pos); float dist = min(v.x, v.y); if (grid_pos.y <= half_thickness && grid_pos.y >= -half_thickness) { color_srgb = grid.x_srgb; } else if (grid_pos.x <= half_thickness && grid_pos.x >= -half_thickness) { color_srgb = grid.y_srgb; } else if (dist < half_thickness) { color_srgb = grid.line_srgb; } else { bool checker = 0; u32 cell_x = (u32)(abs(grid_pos.x) / spacing) + (grid_pos.x < 0); u32 cell_y = (u32)(abs(grid_pos.y) / spacing) + (grid_pos.y < 0); if (cell_x % 2 == 0) { checker = cell_y % 2 == 0; } else { checker = cell_y % 2 == 1; } if (checker) { color_srgb = grid.bg1_srgb; } } albedo = LinearFromSrgbU32(color_srgb); } Vec4 emittance = input.vs.emittance_lin * albedo.a; output.SV_Target0 = albedo; output.SV_Target1 = emittance; return output; }