diff options
| author | HampusM <hampus@hampusmat.com> | 2026-03-20 14:22:19 +0100 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-03-20 14:22:19 +0100 |
| commit | f285f82072b491b1f3cc92db8e08485f26779d5a (patch) | |
| tree | bf6c6c61cdfb3a12550e55966c8552957ade9e71 /engine/res/default_shader.slang | |
| parent | 0546d575c11d3668d0f95933697ae4f670fe2a55 (diff) | |
Diffstat (limited to 'engine/res/default_shader.slang')
| -rw-r--r-- | engine/res/default_shader.slang | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/engine/res/default_shader.slang b/engine/res/default_shader.slang new file mode 100644 index 0000000..dd6a6a9 --- /dev/null +++ b/engine/res/default_shader.slang @@ -0,0 +1,289 @@ +#define MAX_LIGHT_CNT 64 + + +struct Material +{ + float3 ambient; + float3 diffuse; + float3 specular; + // Sampler2D ambient_map; + // Sampler2D diffuse_map; + // Sampler2D specular_map; + float shininess; +}; + +struct LightPhong +{ + float3 diffuse; + float3 specular; +}; + +struct AttenuationProperties +{ + float constant; + float linear; + float quadratic; +}; + +struct PointLight +{ + LightPhong phong; + float3 position; + AttenuationProperties attenuation_props; +}; + +struct DirectionalLight +{ + LightPhong phong; + float3 direction; +}; + +struct CalculatedLight +{ + float3 diffuse; + float3 specular; +}; + +struct BlinnPhongLighting +{ + float3 view_pos; + Material material; + + DirectionalLight directional_lights[MAX_LIGHT_CNT]; + uint directional_light_cnt; + + PointLight point_lights[MAX_LIGHT_CNT]; + uint point_light_cnt; + + float4 evaluate(in VertexData vertex_data) + { + float3 ambient_light = + this.calc_ambient_light(vertex_data.texture_coords); + + float3 directional_light_sum = this.calc_dir_light_sum(vertex_data); + float3 point_light_sum = this.calc_point_light_sum(vertex_data); + + return float4((ambient_light + directional_light_sum + point_light_sum), 1.0); + } + + float3 calc_dir_light_sum(in VertexData vertex_data) + { + float3 directional_light_sum = float3(0.0, 0.0, 0.0); + + for (uint index = 0; index < this.directional_light_cnt; index++) + { + CalculatedLight calculated_dir_light; + + this.calc_light( + // Negated since we want the light to point from the light direction + normalize(-this.directional_lights[index].direction), + this.directional_lights[index].phong, + vertex_data, + calculated_dir_light); + + directional_light_sum += + calculated_dir_light.diffuse + calculated_dir_light.specular; + } + + return directional_light_sum; + } + + float3 calc_point_light_sum(in VertexData vertex_data) + { + float3 point_light_sum = float3(0.0, 0.0, 0.0); + + for (uint index = 0; index < this.point_light_cnt; index++) + { + float3 light_direction = + normalize(this.point_lights[index].position - vertex_data.world_space_pos); + + CalculatedLight calculated_point_light; + + this.calc_light( + light_direction, + this.point_lights[index].phong, + vertex_data, + calculated_point_light); + + float attenuation = + this.calc_attenuation(this.point_lights[index], vertex_data.world_space_pos); + + calculated_point_light.diffuse *= attenuation; + calculated_point_light.specular *= attenuation; + + point_light_sum += + calculated_point_light.diffuse + calculated_point_light.specular; + } + + return point_light_sum; + } + + void calc_light( + in float3 light_direction, + in LightPhong light_phong, + in VertexData vertex_data, + out CalculatedLight calculated_light) + { + float3 norm = normalize(vertex_data.world_space_normal); + + calculated_light.diffuse = this.calc_diffuse_light( + light_phong, + light_direction, + norm, + vertex_data.texture_coords); + + calculated_light.specular = this.calc_specular_light( + light_phong, + light_direction, + norm, + vertex_data.world_space_pos, + vertex_data.texture_coords); + } + + float3 calc_ambient_light(in float2 texture_coords) + { + return ambient_map.Sample(texture_coords).xyz * this.material.ambient; + // return this.material.ambient_map.Sample(texture_coords).xyz * this.material.ambient; + } + + float3 calc_diffuse_light( + in LightPhong light_phong, + in float3 light_dir, + in float3 norm, + in float2 texture_coords) + { + float diff = max(dot(norm, light_dir), 0.0); + + return light_phong.diffuse * (diff * (diffuse_map.Sample(texture_coords).xyz * this.material.diffuse)); + // return light_phong.diffuse * (diff * (this.material.diffuse_map.Sample(texture_coords).xyz * this.material.diffuse)); + } + + float3 calc_specular_light( + in LightPhong light_phong, + in float3 light_dir, + in float3 norm, + in float3 frag_pos, + in float2 texture_coords) + { + float3 view_direction = normalize(this.view_pos - frag_pos); + + float3 halfway_direction = normalize(light_dir + view_direction); + + float spec = + pow(max(dot(norm, halfway_direction), 0.0), this.material.shininess); + + return light_phong.specular * (spec * (specular_map.Sample(texture_coords).xyz * this.material.specular)); + // return light_phong.specular * (spec * (this.material.specular_map.Sample(texture_coords).xyz * this.material.specular)); + } + + float calc_attenuation(in PointLight point_light, in float3 position) + { + float light_distance = length(point_light.position - position); + + return 1.0 / (point_light.attenuation_props.constant + point_light.attenuation_props.linear * light_distance + point_light.attenuation_props.quadratic * pow(light_distance, 2)); + } +}; + +struct Model3D +{ + float4x4 model; + float4x4 model_inverted; + float4x4 view; + float4x4 projection; +} + +// ParameterBlock<BlinnPhongLighting> blinn_phong_lighting; + +// ConstantBuffer<BlinnPhongLighting> blinn_phong_lighting; + +// ConstantBuffer<Model3D> model_3d; + +// ParameterBlock<Model3D> model_3d; + +cbuffer Uniforms { + Model3D model_3d; + BlinnPhongLighting lighting; +} + +Sampler2D ambient_map; +Sampler2D diffuse_map; +Sampler2D specular_map; + + +struct VertexData +{ + float2 texture_coords; + float3 world_space_pos; + float3 world_space_normal; +}; + +struct VertexStageOutput +{ + VertexData vertex_data : VertexData; + float4 sv_position : SV_Position; +}; + +struct Vertex +{ + float3 pos; + float2 texture_coords; + float3 normal; +}; + +struct Fragment +{ + float4 color; +}; + +[shader("vertex")] +VertexStageOutput vertex_main( + Vertex vertex, + // uniform ConstantBuffer<Model3D> model_3d +) +{ + VertexStageOutput stage_output; + + // TODO: Investigate why mul arguments need to be ordered this way. + // The mul arguments are reordered in the GLSL output + + // float4x4 proj_view = mul(model_3d.projection, model_3d.view); + float4x4 proj_view = mul(model_3d.view, model_3d.projection); + + // float4x4 proj_view_model = + // mul(proj_view, model_3d.model); + + float4x4 proj_view_model = + mul(model_3d.model, proj_view); + + // stage_output.sv_position = mul(proj_view_model, float4(vertex.pos, 1.0)); + + stage_output.sv_position = mul(float4(vertex.pos, 1.0), proj_view_model); + + float4 vertex_pos = float4(vertex.pos, 1.0); + + stage_output.vertex_data.world_space_pos = + float3(mul(model_3d.model, vertex_pos).xyz); + + stage_output.vertex_data.texture_coords = vertex.texture_coords; + + stage_output.vertex_data.world_space_normal = + mul(float3x3(transpose(model_3d.model_inverted)), vertex.normal); + + return stage_output; +} + +[shader("fragment")] +Fragment fragment_main( + VertexData vertex_data: VertexData, + // uniform ConstantBuffer<BlinnPhongLighting> lighting +) : SV_Target +{ + Fragment fragment; + + fragment.color = lighting.evaluate(vertex_data); + + // fragment.color = float4(1.0, 1.0, 1.0, 1.0); + + return fragment; +} + |
