107 lines
3.4 KiB
ReStructuredText
107 lines
3.4 KiB
ReStructuredText
#include "kernel.h"
|
|
|
|
ConstantBuffer<struct k_material_sig> sig : register(b0);
|
|
|
|
/* ========================== *
|
|
* Vertex shader
|
|
* ========================== */
|
|
|
|
struct vs_input {
|
|
DECLS(uint, SV_InstanceID);
|
|
DECLS(uint, SV_VertexID);
|
|
};
|
|
|
|
struct vs_output {
|
|
nointerpolation DECLS(uint, tex_nurid);
|
|
nointerpolation DECLS(uint, grid_id);
|
|
DECLS(float2, uv);
|
|
DECLS(float4, tint_lin);
|
|
DECLS(float4, emittance_lin);
|
|
DECLS(float4, SV_Position);
|
|
};
|
|
|
|
K_ENTRY 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)
|
|
};
|
|
StructuredBuffer<struct k_material_instance> instances = resource_from_urid(sig.instances_urid);
|
|
struct k_material_instance instance = 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(sig.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);
|
|
output.emittance_lin = linear_from_srgb(float4(instance.light_emittance_srgb, instance.is_light));
|
|
return output;
|
|
}
|
|
|
|
/* ========================== *
|
|
* Pixel shader
|
|
* ========================== */
|
|
|
|
struct ps_input {
|
|
struct vs_output vs;
|
|
};
|
|
|
|
struct ps_output {
|
|
DECLS(float4, SV_Target0); /* Albedo */
|
|
DECLS(float4, SV_Target1); /* Emittance */
|
|
};
|
|
|
|
K_ENTRY struct ps_output ps(struct ps_input input)
|
|
{
|
|
struct ps_output output;
|
|
float4 albedo = input.vs.tint_lin;
|
|
|
|
/* Texture */
|
|
if (input.vs.tex_nurid < 0xFFFFFFFF) {
|
|
Texture2D<float4> tex = resource_from_nurid(input.vs.tex_nurid);
|
|
albedo *= tex.Sample(s_point_clamp, input.vs.uv);
|
|
}
|
|
|
|
/* Grid */
|
|
if (input.vs.grid_id < 0xFFFFFFFF) {
|
|
StructuredBuffer<struct k_material_grid> grids = resource_from_urid(sig.grids_urid);
|
|
struct k_material_grid grid = 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;
|
|
}
|
|
}
|
|
albedo = linear_from_srgb32(color_srgb);
|
|
}
|
|
|
|
float4 emittance = input.vs.emittance_lin * albedo.a;
|
|
|
|
output.SV_Target0 = albedo;
|
|
output.SV_Target1 = emittance;
|
|
return output;
|
|
}
|