power_play/res/fx/material.hlsl
2025-06-08 20:18:03 -05:00

86 lines
2.0 KiB
HLSL

#include "fx/common.hlsl"
struct fx_material_constant {
float4x4 projection;
uint instance_offset;
};
struct fx_material_instance {
float2x3 xf;
float2 uv0;
float2 uv1;
uint tint_srgb;
float emittance;
};
/* ========================== *
* Root Signature
* ========================== */
#define ROOTSIG \
"CBV(b0), " \
"DescriptorTable(SRV(t0), SRV(t1)), " \
"DescriptorTable(Sampler(s0))"
cbuffer cbuff : register(b0)
{
struct fx_material_constant g_constant;
};
StructuredBuffer<struct fx_material_instance> g_instances : register(t0);
Texture2D g_texture : register(t1);
SamplerState g_sampler : register(s0);
/* ========================== *
* Vertex shader
* ========================== */
static const float2 g_quad_verts[4] = {
float2(-0.5f, -0.5f),
float2( 0.5f, -0.5f),
float2( 0.5f, 0.5f),
float2(-0.5f, 0.5f)
};
static const int2 g_uv_factors[4] = {
int2(0, 0),
int2(1, 0),
int2(1, 1),
int2(0, 1)
};
struct vs_output {
DESV(float4, screen_pos, SV_POSITION);
DECL(float2, uv);
DECL(float4, tint_lin);
};
[RootSignature(ROOTSIG)]
struct vs_output fx_material_vs(uint instance_id : SV_InstanceID, uint vertex_id : SV_VertexID)
{
struct fx_material_instance instance = g_instances[g_constant.instance_offset + instance_id];
float2 vert = g_quad_verts[vertex_id];
float2 uv_factor = g_uv_factors[vertex_id];
float2 world_pos = mul(instance.xf, float3(vert, 1)).xy;
struct vs_output output;
output.screen_pos = mul(g_constant.projection, float4(world_pos, 0, 1));
output.uv = instance.uv0 + uv_factor * (instance.uv1 - instance.uv0);
output.tint_lin = linear_from_srgb32(instance.tint_srgb);
return output;
}
/* ========================== *
* Pixel shader
* ========================== */
[RootSignature(ROOTSIG)]
float4 fx_material_ps(struct vs_output input) : SV_TARGET
{
float4 color = g_texture.Sample(g_sampler, input.uv) * input.tint_lin;
return color;
}