90 lines
2.4 KiB
Plaintext
90 lines
2.4 KiB
Plaintext
#include "common.slang"
|
|
|
|
struct VertexShaderInput {
|
|
// Per Vertex
|
|
uint vertex_id : SV_VertexID;
|
|
float3 pos;
|
|
|
|
// Per Instance
|
|
uint instance_id : SV_InstanceID;
|
|
uint tile_info;
|
|
};
|
|
|
|
struct VertexShaderOutput {
|
|
float4 pos : SV_POSITION;
|
|
float2 uv;
|
|
uint tile;
|
|
};
|
|
|
|
struct PixelShaderOutput {
|
|
float4 color : SV_TARGET;
|
|
};
|
|
|
|
[[vk::binding(0, 0)]]
|
|
StructuredBuffer<float4> tile_infos;
|
|
|
|
[shader("vertex")]
|
|
VertexShaderOutput main_vertex(VertexShaderInput input) {
|
|
VertexShaderOutput output;
|
|
float2 tile_pos = float2(input.instance_id % map_width, float(input.instance_id / map_width));
|
|
tile_pos -= float2(0.5, 0.5);
|
|
|
|
uint tile_type = input.tile_info & 0xffff;
|
|
uint rotation = (input.tile_info >> 16) & 0x3;
|
|
|
|
output.tile = tile_type;
|
|
output.pos = mul(view_projection_matrix, float4(tile_pos + input.pos.xy, 0, 1));
|
|
|
|
float4 uv_min_max = tile_infos.Load(tile_type);
|
|
|
|
switch (rotation) {
|
|
case 0: switch (input.vertex_id) {
|
|
case 0: output.uv = uv_min_max.xy; break;
|
|
case 1: output.uv = uv_min_max.zy; break;
|
|
case 2: output.uv = uv_min_max.zw; break;
|
|
case 3: output.uv = uv_min_max.xw; break;
|
|
} break;
|
|
|
|
case 1: switch (input.vertex_id) {
|
|
case 0: output.uv = uv_min_max.zy; break;
|
|
case 1: output.uv = uv_min_max.zw; break;
|
|
case 2: output.uv = uv_min_max.xw; break;
|
|
case 3: output.uv = uv_min_max.xy; break;
|
|
} break;
|
|
|
|
case 2: switch (input.vertex_id) {
|
|
case 0: output.uv = uv_min_max.zw; break;
|
|
case 1: output.uv = uv_min_max.xw; break;
|
|
case 2: output.uv = uv_min_max.xy; break;
|
|
case 3: output.uv = uv_min_max.zy; break;
|
|
} break;
|
|
|
|
case 3: switch (input.vertex_id) {
|
|
case 0: output.uv = uv_min_max.xw; break;
|
|
case 1: output.uv = uv_min_max.xy; break;
|
|
case 2: output.uv = uv_min_max.zy; break;
|
|
case 3: output.uv = uv_min_max.zw; break;
|
|
} break;
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
[[vk::binding(0, 2)]]
|
|
Sampler2DArray<float4> tex1;
|
|
|
|
[[vk::binding(0, 3)]]
|
|
cbuffer fragment_constants {
|
|
float3 tint;
|
|
}
|
|
|
|
[shader("fragment")]
|
|
PixelShaderOutput main_fragment(VertexShaderOutput input) {
|
|
PixelShaderOutput output;
|
|
|
|
output.color = tex1.PixelArtSample(float3(input.uv, input.tile));
|
|
output.color.rgb *= tint.rgb;
|
|
|
|
return output;
|
|
}
|