//////////////////////////////////////////////////////////// //~ Backdrop shader ComputeShader2D(V_BackdropCS, 8, 8) { V_DParams params = G_Dereference(V_ShaderConst_Params)[0]; RWTexture2D target = G_Dereference(params.target_rw); Texture2D tiles = G_Dereference(params.tiles); const Vec4 background_color_a = LinearFromSrgb(Vec4(0.30, 0.30, 0.30, 1)); const Vec4 background_color_b = LinearFromSrgb(Vec4(0.15, 0.15, 0.15, 1)); const Vec4 grid_color = LinearFromSrgb(Vec4(0, 0, 0, 1)); const Vec4 x_axis_color = LinearFromSrgb(Vec4(0.75, 0, 0, 1)); const Vec4 y_axis_color = LinearFromSrgb(Vec4(0, 0.75, 0, 1)); const Vec4 bounds_color = LinearFromSrgb(Vec4(0.75, 0.75, 0, 1)); Vec2 screen_pos = Vec2(SV_DispatchThreadID) + Vec2(0.5, 0.5); if (screen_pos.x < params.target_size.x && screen_pos.y < params.target_size.y) { Vec4 result = Vec4(0.025, 0.025, 0.025, 1); Vec2 world_pos = mul(params.draw_to_world_xf, Vec3(screen_pos, 1)); Vec2I32 tile_pos = S_TilePosFromWorldPos(world_pos); f32 half_thickness = 1; f32 half_bounds_size = params.world_size * 0.5; Vec2 bounds_screen_p0 = mul(params.world_to_draw_xf, Vec3(-half_bounds_size, -half_bounds_size, 1)); Vec2 bounds_screen_p1 = mul(params.world_to_draw_xf, Vec3(half_bounds_size, half_bounds_size, 1)); b32 is_in_bounds = screen_pos.x > (bounds_screen_p0.x - half_thickness) && screen_pos.y > (bounds_screen_p0.y - half_thickness) && screen_pos.x < (bounds_screen_p1.x + half_thickness) && screen_pos.y < (bounds_screen_p1.y + half_thickness); if (is_in_bounds) { /* Grid checker */ { i32 color_idx = 0; Vec4 colors[2] = { background_color_a, background_color_b }; const f32 checker_size = 0.5; Vec2 world_pos_modded = fmod(abs(world_pos), Vec2(checker_size * 2, checker_size * 2)); if (world_pos_modded.x < checker_size) { color_idx = !color_idx; } if (world_pos_modded.y < checker_size) { color_idx = !color_idx; } if (world_pos.x < 0) { color_idx = !color_idx; } if (world_pos.y < 0) { color_idx = !color_idx; } result = colors[color_idx]; } /* Grid outline */ { Vec2 grid_screen_p0 = mul(params.world_to_draw_xf, Vec3(floor(world_pos), 1)); Vec2 grid_screen_p1 = mul(params.world_to_draw_xf, Vec3(ceil(world_pos), 1)); f32 grid_dist = 100000; grid_dist = min(grid_dist, abs(screen_pos.x - grid_screen_p0.x)); grid_dist = min(grid_dist, abs(screen_pos.x - grid_screen_p1.x)); grid_dist = min(grid_dist, abs(screen_pos.y - grid_screen_p0.y)); grid_dist = min(grid_dist, abs(screen_pos.y - grid_screen_p1.y)); if (grid_dist <= half_thickness) { result = grid_color; } } /* Tile */ { S_TileKind tile = (S_TileKind)tiles.Load(Vec3I32(tile_pos, 0)); switch (tile) { default: break; case S_TileKind_Floor: { result = Color_Blue; } break; case S_TileKind_Wall: { result = Color_Red; } break; } } /* Axis */ { Vec2 zero_screen = mul(params.world_to_draw_xf, Vec3(0, 0, 1)); f32 x_dist = abs(screen_pos.x - zero_screen.x); f32 y_dist = abs(screen_pos.y - zero_screen.y); if (y_dist <= half_thickness) { result = x_axis_color; } else if (x_dist <= half_thickness) { result = y_axis_color; } } /* World bounds */ { f32 bounds_dist = 100000; bounds_dist = min(bounds_dist, abs(screen_pos.x - bounds_screen_p0.x)); bounds_dist = min(bounds_dist, abs(screen_pos.x - bounds_screen_p1.x)); bounds_dist = min(bounds_dist, abs(screen_pos.y - bounds_screen_p0.y)); bounds_dist = min(bounds_dist, abs(screen_pos.y - bounds_screen_p1.y)); if (bounds_dist <= half_thickness) { result = bounds_color; } } } target[trunc(screen_pos)] = result; } } //////////////////////////////////////////////////////////// //~ Quad shader ////////////////////////////// //- Vertex shader VertexShader(V_DQuadVS, V_DQuadPSInput) { V_DParams params = G_Dereference(V_ShaderConst_Params)[0]; StructuredBuffer quads = G_Dereference(params.quads); RWTexture2D target = G_Dereference(params.target_rw); V_DQuad quad = quads[SV_InstanceID]; Vec2 rect_uv = RectUvFromVertexId(SV_VertexID); // Vec2 tex_uv = lerp(quad.tex_uv0, quad.tex_uv1, rect_uv); // Vec2 target_pos = lerp(quad.p0, quad.p1, rect_uv); Vec2 target_pos = 0; V_DQuadPSInput result; result.sv_position = Vec4(NdcFromPos(target_pos, countof(target)).xy, 0, 1); result.quad_idx = SV_InstanceID; return result; } ////////////////////////////// //- Pixel shader PixelShader(V_DQuadPS, V_DQuadPSOutput, V_DQuadPSInput input) { V_DParams params = G_Dereference(V_ShaderConst_Params)[0]; StructuredBuffer quads = G_Dereference(params.quads); V_DQuad quad = quads[input.quad_idx]; Vec4 final_color = 0; V_DQuadPSOutput output; output.sv_target0 = final_color; return output; } //////////////////////////////////////////////////////////// //~ Shape shader ////////////////////////////// //- Vertex shader VertexShader(V_DVertVS, V_DVertPSInput) { V_DParams params = G_Dereference(V_ShaderConst_Params)[0]; StructuredBuffer verts = G_Dereference(params.shape_verts); RWTexture2D target = G_Dereference(params.target_rw); V_DVert vert = verts[SV_VertexID]; Vec2 target_pos = vert.pos; V_DVertPSInput result; result.sv_position = Vec4(NdcFromPos(target_pos, countof(target)).xy, 0, 1); result.color_lin = vert.color_lin; return result; } ////////////////////////////// //- Pixel shader PixelShader(V_DVertPS, V_DVertPSOutput, V_DVertPSInput input) { V_DVertPSOutput output; output.sv_target0 = input.color_lin; return output; } //////////////////////////////////////////////////////////// //~ Overlay shader ////////////////////////////// //- Vertex shader VertexShader(V_OverlayVS, V_OverlayPSInput) { Vec2 uv = RectUvFromVertexId(SV_VertexID); V_OverlayPSInput result; result.sv_position = Vec4(NdcFromUv(uv).xy, 0, 1); return result; } ////////////////////////////// //- Pixel shader PixelShader(V_OverlayPS, V_OverlayPSOutput, V_OverlayPSInput input) { V_DParams params = G_Dereference(V_ShaderConst_Params)[0]; Texture2D tiles = G_Dereference(params.tiles); Vec2 screen_pos = input.sv_position.xy; Vec4 result = 0; Vec2 world_pos = mul(params.draw_to_world_xf, Vec3(screen_pos, 1)); Vec2I32 tile_pos = S_TilePosFromWorldPos(world_pos); S_TileKind equipped_tile = params.equipped_tile; f32 half_thickness = 1; Vec4 border_color = LinearFromSrgb(Vec4(1, 1, 1, 1)); // Vec4 inner_color = LinearFromSrgb(Vec4(0.4, 0.4, 0.4, 0.25)); Vec4 inner_color = LinearFromSrgb(Vec4(0.4, 0.8, 0.4, 0.6)); Rng2 screen_selection = params.draw_selection; Rng2 world_selection = params.world_selection; Rng2I32 tile_selection; tile_selection.p0 = S_TilePosFromWorldPos(world_selection.p0); tile_selection.p1 = S_TilePosFromWorldPos(world_selection.p1); if (params.selection_mode == V_SelectionMode_Tile) { f32 dist = 100000000; dist = min(dist, screen_pos.x - screen_selection.p0.x); dist = min(dist, screen_pos.y - screen_selection.p0.y); dist = min(dist, screen_selection.p1.x - screen_pos.x); dist = min(dist, screen_selection.p1.y - screen_pos.y); dist = -dist; // if (dist >= -half_thickness && dist <= half_thickness) // { // result = border_color; // } // else { if (world_pos.x > -(S_WorldSize / 2) && world_pos.y > -(S_WorldSize / 2) && world_pos.x < (S_WorldSize / 2) && world_pos.y < (S_WorldSize / 2) && tile_pos.x >= tile_selection.p0.x && tile_pos.x <= tile_selection.p1.x && tile_pos.y >= tile_selection.p0.y && tile_pos.y <= tile_selection.p1.y) { result = inner_color; } } } V_OverlayPSOutput output; output.sv_target0 = result; return output; }