#include "sh/common.hlsl" /* ========================== * * Root signature * ========================== */ #define ROOTSIG \ "RootConstants(num32BitConstants = 16, b0), " \ "DescriptorTable(SRV(t0, space = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \ "SRV(t0, space = 1), " \ "SRV(t0, space = 2), " \ \ "StaticSampler(s0, " \ "filter = FILTER_MIN_MAG_MIP_POINT, " \ "addressU = TEXTURE_ADDRESS_CLAMP, " \ "addressV = TEXTURE_ADDRESS_CLAMP, " \ "addressW = TEXTURE_ADDRESS_CLAMP, " \ "maxAnisotropy = 1)" ConstantBuffer g_constants : register(b0); Texture2D g_textures[] : register(t0, space0); StructuredBuffer g_instances : register(t0, space1); StructuredBuffer g_grids : register(t0, space2); SamplerState g_sampler : register(s0); /* ========================== * * Vertex shader * ========================== */ struct vs_input { DECLS(uint, SV_InstanceID); DECLS(uint, SV_VertexID); }; struct vs_output { nointerpolation DECLS(int, tex_nurid); nointerpolation DECLS(int, grid_id); DECLS(float2, uv); DECLS(float4, tint_lin); DECLS(float4, SV_Position); }; SH_ENTRY(ROOTSIG) struct vs_output vs(struct vs_input input) { static const float2 unit_quad_verts[4] = { float2(-0.5f, -0.5f), float2(0.5f, -0.5f), float2(0.5f, 0.5f), float2(-0.5f, 0.5f) }; struct sh_material_instance instance = g_instances[input.SV_InstanceID]; float2 vert = unit_quad_verts[input.SV_VertexID]; float2 world_pos = mul(instance.xf, float3(vert, 1)).xy; struct vs_output output; output.SV_Position = mul(g_constants.projection, float4(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 = linear_from_srgb32(instance.tint_srgb); return output; } /* ========================== * * Pixel shader * ========================== */ struct ps_input { struct vs_output vs; }; struct ps_output { DECLS(float4, SV_Target); }; SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input) { struct ps_output output; output.SV_Target = input.vs.tint_lin; /* Texture */ if (input.vs.tex_nurid >= 0) { output.SV_Target *= g_textures[NURID(input.vs.tex_nurid)].Sample(g_sampler, input.vs.uv); } /* Grid */ if (input.vs.grid_id >= 0) { struct sh_material_grid grid = g_grids[input.vs.grid_id]; float2 grid_pos = input.vs.SV_Position.xy + grid.offset; float half_thickness = grid.line_thickness / 2; float spacing = grid.line_spacing; uint color_srgb = grid.bg0_srgb; float2 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; uint cell_x = (uint)(abs(grid_pos.x) / spacing) + (grid_pos.x < 0); uint cell_y = (uint)(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; } } output.SV_Target *= linear_from_srgb32(color_srgb); } return output; }