274 lines
8.3 KiB
Plaintext
274 lines
8.3 KiB
Plaintext
////////////////////////////////////////////////////////////
|
|
//~ Backdrop shader
|
|
|
|
ComputeShader2D(V_BackdropCS, 8, 8)
|
|
{
|
|
V_DParams params = G_Dereference<V_DParams>(V_ShaderConst_Params)[0];
|
|
RWTexture2D<Vec4> target = G_Dereference<Vec4>(params.target_rw);
|
|
Texture2D<uint> tiles = G_Dereference<uint>(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_DParams>(V_ShaderConst_Params)[0];
|
|
StructuredBuffer<V_DQuad> quads = G_Dereference<V_DQuad>(params.quads);
|
|
RWTexture2D<Vec4> target = G_Dereference<Vec4>(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_DParams>(V_ShaderConst_Params)[0];
|
|
StructuredBuffer<V_DQuad> quads = G_Dereference<V_DQuad>(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_DParams>(V_ShaderConst_Params)[0];
|
|
StructuredBuffer<V_DVert> verts = G_Dereference<V_DVert>(params.shape_verts);
|
|
RWTexture2D<Vec4> target = G_Dereference<Vec4>(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_DParams>(V_ShaderConst_Params)[0];
|
|
Texture2D<uint> tiles = G_Dereference<uint>(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;
|
|
}
|