From dc1bb22cd22c2d86c668affadb5bafd615d1a315 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Thu, 26 Feb 2026 13:57:27 +0100 Subject: [PATCH 1/6] Refactor PBR shader tests : fix PBRBasic_frag --- shaders/compiled/PbrBasic.frag.json | 205 +++++++------------ shaders/compiled/PbrBasic.frag.msl | 177 ++++++++-------- shaders/compiled/PbrBasic.frag.spv | Bin 10564 -> 9984 bytes shaders/compiled/PbrBasic.vert.msl | 5 +- shaders/compiled/PbrTransparent.frag.json | 239 +++++++--------------- shaders/compiled/PbrTransparent.frag.msl | 67 +++--- shaders/compiled/PbrTransparent.frag.spv | Bin 6032 -> 5628 bytes shaders/src/PbrBasic.frag.slang | 26 +-- shaders/src/PbrTransparent.frag.slang | 31 +-- shaders/src/pbr_lighting.slang | 10 + src/candlewick/multibody/RobotScene.cpp | 30 +-- src/candlewick/multibody/RobotScene.h | 5 +- tests/TestShaderMetadata.cpp | 2 +- 13 files changed, 305 insertions(+), 492 deletions(-) diff --git a/shaders/compiled/PbrBasic.frag.json b/shaders/compiled/PbrBasic.frag.json index eaf8f6b8..0dcd447d 100644 --- a/shaders/compiled/PbrBasic.frag.json +++ b/shaders/compiled/PbrBasic.frag.json @@ -7,53 +7,43 @@ "kind": "constantBuffer", "elementType": { "kind": "struct", - "name": "MaterialBlock", + "name": "PbrMaterial", "fields": [ { - "name": "material", + "name": "baseColor", "type": { - "kind": "struct", - "name": "PbrMaterial", - "fields": [ - { - "name": "baseColor", - "type": { - "kind": "vector", - "elementCount": 4, - "elementType": { - "kind": "scalar", - "scalarType": "float32" - } - }, - "binding": {"kind": "uniform", "offset": 0, "size": 16, "elementStride": 4} - }, - { - "name": "metalness", - "type": { - "kind": "scalar", - "scalarType": "float32" - }, - "binding": {"kind": "uniform", "offset": 16, "size": 4, "elementStride": 0} - }, - { - "name": "roughness", - "type": { - "kind": "scalar", - "scalarType": "float32" - }, - "binding": {"kind": "uniform", "offset": 20, "size": 4, "elementStride": 0} - }, - { - "name": "ao", - "type": { - "kind": "scalar", - "scalarType": "float32" - }, - "binding": {"kind": "uniform", "offset": 24, "size": 4, "elementStride": 0} - } - ] + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } }, - "binding": {"kind": "uniform", "offset": 0, "size": 32, "elementStride": 0} + "binding": {"kind": "uniform", "offset": 0, "size": 16, "elementStride": 4} + }, + { + "name": "metalness", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 16, "size": 4, "elementStride": 0} + }, + { + "name": "roughness", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 20, "size": 4, "elementStride": 0} + }, + { + "name": "ao", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 24, "size": 4, "elementStride": 0} } ] }, @@ -63,53 +53,43 @@ "elementVarLayout": { "type": { "kind": "struct", - "name": "MaterialBlock", + "name": "PbrMaterial", "fields": [ { - "name": "material", + "name": "baseColor", "type": { - "kind": "struct", - "name": "PbrMaterial", - "fields": [ - { - "name": "baseColor", - "type": { - "kind": "vector", - "elementCount": 4, - "elementType": { - "kind": "scalar", - "scalarType": "float32" - } - }, - "binding": {"kind": "uniform", "offset": 0, "size": 16, "elementStride": 4} - }, - { - "name": "metalness", - "type": { - "kind": "scalar", - "scalarType": "float32" - }, - "binding": {"kind": "uniform", "offset": 16, "size": 4, "elementStride": 0} - }, - { - "name": "roughness", - "type": { - "kind": "scalar", - "scalarType": "float32" - }, - "binding": {"kind": "uniform", "offset": 20, "size": 4, "elementStride": 0} - }, - { - "name": "ao", - "type": { - "kind": "scalar", - "scalarType": "float32" - }, - "binding": {"kind": "uniform", "offset": 24, "size": 4, "elementStride": 0} - } - ] + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 0, "size": 16, "elementStride": 4} + }, + { + "name": "metalness", + "type": { + "kind": "scalar", + "scalarType": "float32" }, - "binding": {"kind": "uniform", "offset": 0, "size": 32, "elementStride": 0} + "binding": {"kind": "uniform", "offset": 16, "size": 4, "elementStride": 0} + }, + { + "name": "roughness", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 20, "size": 4, "elementStride": 0} + }, + { + "name": "ao", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 24, "size": 4, "elementStride": 0} } ] }, @@ -180,6 +160,14 @@ "scalarType": "int32" }, "binding": {"kind": "uniform", "offset": 192, "size": 4, "elementStride": 0} + }, + { + "name": "useSsao", + "type": { + "kind": "scalar", + "scalarType": "uint32" + }, + "binding": {"kind": "uniform", "offset": 196, "size": 4, "elementStride": 0} } ] }, @@ -245,57 +233,24 @@ "scalarType": "int32" }, "binding": {"kind": "uniform", "offset": 192, "size": 4, "elementStride": 0} - } - ] - }, - "binding": {"kind": "uniform", "offset": 0, "size": 208, "elementStride": 0} - } - } - }, - { - "name": "params", - "binding": {"kind": "descriptorTableSlot", "space": 3, "index": 2}, - "type": { - "kind": "constantBuffer", - "elementType": { - "kind": "struct", - "name": "EffectParams", - "fields": [ - { - "name": "useSsao", - "type": { - "kind": "scalar", - "scalarType": "uint32" }, - "binding": {"kind": "uniform", "offset": 0, "size": 4, "elementStride": 0} - } - ] - }, - "containerVarLayout": { - "binding": {"kind": "descriptorTableSlot", "index": 0} - }, - "elementVarLayout": { - "type": { - "kind": "struct", - "name": "EffectParams", - "fields": [ { "name": "useSsao", "type": { "kind": "scalar", "scalarType": "uint32" }, - "binding": {"kind": "uniform", "offset": 0, "size": 4, "elementStride": 0} + "binding": {"kind": "uniform", "offset": 196, "size": 4, "elementStride": 0} } ] }, - "binding": {"kind": "uniform", "offset": 0, "size": 16, "elementStride": 0} + "binding": {"kind": "uniform", "offset": 0, "size": 208, "elementStride": 0} } } }, { "name": "shadowAtlas", - "binding": {"kind": "descriptorTableSlot", "space": 3, "index": 3}, + "binding": {"kind": "descriptorTableSlot", "space": 3, "index": 2}, "type": { "kind": "constantBuffer", "elementType": { @@ -511,13 +466,9 @@ "name": "light", "binding": {"kind": "descriptorTableSlot", "space": 3, "index": 1, "used": 1} }, - { - "name": "params", - "binding": {"kind": "descriptorTableSlot", "space": 3, "index": 2, "used": 1} - }, { "name": "shadowAtlas", - "binding": {"kind": "descriptorTableSlot", "space": 3, "index": 3, "used": 1} + "binding": {"kind": "descriptorTableSlot", "space": 3, "index": 2, "used": 1} }, { "name": "shadowMap", diff --git a/shaders/compiled/PbrBasic.frag.msl b/shaders/compiled/PbrBasic.frag.msl index 392627c1..9289d6d8 100644 --- a/shaders/compiled/PbrBasic.frag.msl +++ b/shaders/compiled/PbrBasic.frag.msl @@ -3,11 +3,11 @@ #include using namespace metal; -#line 17 "shaders/src/pbr_lighting.slang" +#line 27 "shaders/src/pbr_lighting.slang" float distributionGGX_0(float3 normal_0, float3 H_0, float roughness_0) { -#line 18 +#line 28 float a_0 = roughness_0 * roughness_0; float a2_0 = a_0 * a_0; float _S1 = max(dot(normal_0, H_0), 0.0); @@ -23,7 +23,7 @@ float distributionGGX_0(float3 normal_0, float3 H_0, float roughness_0) float geometrySchlickGGX_0(float NdotV_0, float roughness_1) { -#line 31 +#line 41 float r_0 = roughness_1 + 1.0; float k_0 = r_0 * r_0 / 8.0; return NdotV_0 / (NdotV_0 * (1.0 - k_0) + k_0); @@ -38,16 +38,16 @@ float geometrySmith_0(float3 normal_1, float3 V_0, float3 L_0, float roughness_2 } -#line 12 +#line 22 float3 fresnelSchlick_0(float cosTheta_0, float3 F0_0) { -#line 13 +#line 23 return F0_0 + (float3(1.0) - F0_0) * float3(pow(clamp(1.0 - cosTheta_0, 0.0, 1.0), 5.0)) ; } -#line 1 +#line 11 struct PbrMaterial_0 { float4 baseColor_0; @@ -57,11 +57,11 @@ struct PbrMaterial_0 }; -#line 46 +#line 56 float3 calculatePbrLighting_0(float3 normal_2, float3 V_1, float3 lightDir_0, const PbrMaterial_0 constant* material_0, float3 lightColor_0, float lightIntensity_0) { -#line 54 +#line 64 float3 H_1 = normalize(lightDir_0 + V_1); float3 _S2 = material_0->baseColor_0.xyz; @@ -72,7 +72,7 @@ float3 calculatePbrLighting_0(float3 normal_2, float3 V_1, float3 lightDir_0, co float _S3 = dot(normal_2, lightDir_0); -#line 72 +#line 82 return ((float3(1.0) - F_0) * float3((1.0 - material_0->metalness_0)) * _S2 / float3(3.14159274101257324) + float3((distributionGGX_0(normal_2, H_1, material_0->roughness_3) * geometrySmith_0(normal_2, V_1, lightDir_0, material_0->roughness_3))) * F_0 / float3((4.0 * max(dot(normal_2, V_1), _S3) + 0.00009999999747379)) ) * (float3(lightIntensity_0) * lightColor_0) * float3(max(_S3, 0.0)) ; } @@ -178,53 +178,38 @@ bool isCoordsInRange_0(float3 uv_0) } -#line 10 "shaders/src/PbrBasic.frag.slang" -struct MaterialBlock_0 -{ - PbrMaterial_0 material_1; -}; - - -#line 14 +#line 3 "shaders/src/pbr_lighting.slang" struct LightBlock_0 { array direction_0; array color_0; array intensity_0; int numLights_0; + uint useSsao_0; }; - - +#line 10 "shaders/src/PbrBasic.frag.slang" struct ShadowAtlasInfo_0 { array lightRegions_0; }; -#line 21 -struct EffectParams_0 -{ - uint useSsao_0; -}; - - -#line 21 +#line 10 struct KernelContext_0 { depth2d shadowMap_texture_0; sampler shadowMap_sampler_0; - MaterialBlock_0 constant* materialBlock_0; + PbrMaterial_0 constant* materialBlock_0; LightBlock_0 constant* light_0; ShadowAtlasInfo_0 constant* shadowAtlas_0; - EffectParams_0 constant* params_0; texture2d ssaoTex_texture_0; sampler ssaoTex_sampler_0; }; -#line 50 +#line 34 float calcShadowmap_0(int lightIndex_0, float NdotL_0, int2 atlasSize_0, const array thread* fragLightPos_0, KernelContext_0 thread* kernelContext_0) { @@ -236,23 +221,23 @@ float calcShadowmap_0(int lightIndex_0, float NdotL_0, int2 atlasSize_0, const a if(!isCoordsInRange_0(float3(uv_1, depthRef_0))) { -#line 59 +#line 43 return 1.0; } int2 _S6 = kernelContext_0->shadowAtlas_0->lightRegions_0[lightIndex_0].xy; -#line 63 +#line 47 float2 _S7 = float2(_S6); -#line 63 +#line 47 int2 _S8 = kernelContext_0->shadowAtlas_0->lightRegions_0[lightIndex_0].zw; -#line 63 +#line 47 float2 _S9 = float2(atlasSize_0); -#line 63 +#line 47 uv_1 = (_S7 + uv_1 * float2(_S8)) / _S9; float2 _S10 = _S7 / _S9; float2 _S11 = float2(_S6 + _S8) / _S9; @@ -262,70 +247,70 @@ float calcShadowmap_0(int lightIndex_0, float NdotL_0, int2 atlasSize_0, const a float _S13 = 1.0 / pow(3.0, 2.0); -#line 70 +#line 54 int i_0 = int(-1); -#line 70 +#line 54 float value_0 = 0.0; for(;;) { -#line 71 +#line 55 if(i_0 <= int(1)) { } else { -#line 71 +#line 55 break; } -#line 71 +#line 55 int j_0 = int(-1); for(;;) { -#line 72 +#line 56 if(j_0 <= int(1)) { } else { -#line 72 +#line 56 break; } -#line 73 +#line 57 float2 offUV_0 = clamp(uv_1 + float2(float(i_0), float(j_0)) * _S12, _S10, _S11); ; -#line 74 +#line 58 ; -#line 74 +#line 58 float _S14 = kernelContext_0->shadowMap_texture_0.sample_compare(kernelContext_0->shadowMap_sampler_0, offUV_0, depthRef_0); -#line 74 +#line 58 float value_1 = value_0 + _S13 * _S14; -#line 72 +#line 56 j_0 = j_0 + int(1); -#line 72 +#line 56 value_0 = value_1; -#line 72 +#line 56 } -#line 71 +#line 55 i_0 = i_0 + int(1); -#line 71 +#line 55 } -#line 77 +#line 61 return value_0; } @@ -351,7 +336,7 @@ float3 uncharted2ToneMapping_0(float3 color_2) } -#line 41 "shaders/src/PbrBasic.frag.slang" +#line 25 "shaders/src/PbrBasic.frag.slang" struct FSOutput_0 { float4 fragColor_0 [[color(0)]]; @@ -360,7 +345,7 @@ struct FSOutput_0 }; -#line 41 +#line 25 struct pixelInput_0 { float3 fragViewPos_0 [[user(_SLANG_ATTR)]]; @@ -369,35 +354,32 @@ struct pixelInput_0 }; -#line 82 -[[fragment]] FSOutput_0 main_0(pixelInput_0 _S16 [[stage_in]], float4 fragCoord_0 [[position]], bool isFrontFacing_0 [[front_facing]], depth2d shadowMap_texture_1 [[texture(0)]], sampler shadowMap_sampler_1 [[sampler(0)]], MaterialBlock_0 constant* materialBlock_1 [[buffer(0)]], LightBlock_0 constant* light_1 [[buffer(1)]], ShadowAtlasInfo_0 constant* shadowAtlas_1 [[buffer(3)]], EffectParams_0 constant* params_1 [[buffer(2)]], texture2d ssaoTex_texture_1 [[texture(1)]], sampler ssaoTex_sampler_1 [[sampler(1)]]) +#line 66 +[[fragment]] FSOutput_0 main_0(pixelInput_0 _S16 [[stage_in]], float4 fragCoord_0 [[position]], bool isFrontFacing_0 [[front_facing]], depth2d shadowMap_texture_1 [[texture(0)]], sampler shadowMap_sampler_1 [[sampler(0)]], PbrMaterial_0 constant* materialBlock_1 [[buffer(0)]], LightBlock_0 constant* light_1 [[buffer(1)]], ShadowAtlasInfo_0 constant* shadowAtlas_1 [[buffer(2)]], texture2d ssaoTex_texture_1 [[texture(1)]], sampler ssaoTex_sampler_1 [[sampler(1)]]) { thread KernelContext_0 kernelContext_1; -#line 86 +#line 70 (&kernelContext_1)->shadowMap_texture_0 = shadowMap_texture_1; -#line 86 +#line 70 (&kernelContext_1)->shadowMap_sampler_0 = shadowMap_sampler_1; -#line 86 +#line 70 (&kernelContext_1)->materialBlock_0 = materialBlock_1; -#line 86 +#line 70 (&kernelContext_1)->light_0 = light_1; -#line 86 +#line 70 (&kernelContext_1)->shadowAtlas_0 = shadowAtlas_1; -#line 86 - (&kernelContext_1)->params_0 = params_1; - -#line 86 +#line 70 (&kernelContext_1)->ssaoTex_texture_0 = ssaoTex_texture_1; -#line 86 +#line 70 (&kernelContext_1)->ssaoTex_sampler_0 = ssaoTex_sampler_1; float3 normal_3 = normalize(_S16.fragViewNormal_0); float3 _S17 = normalize(- _S16.fragViewPos_0); @@ -405,126 +387,126 @@ struct pixelInput_0 thread uint smW_0; -#line 91 +#line 75 thread uint smH_0; -#line 91 +#line 75 (*((shadowMap_sampler_1)) = (shadowMap_texture_1).get_width(0)),(*((&smW_0)) = (shadowMap_texture_1).get_height(0)); int2 _S18 = int2(int(smW_0), int(smH_0)); -#line 93 +#line 77 float3 normal_4; if(!isFrontFacing_0) { -#line 96 +#line 80 normal_4 = - normal_3; -#line 96 +#line 80 } else { -#line 96 +#line 80 normal_4 = normal_3; -#line 96 +#line 80 } - PbrMaterial_0 mat_0 = (&kernelContext_1)->materialBlock_0->material_1; + PbrMaterial_0 mat_0 = *(&kernelContext_1)->materialBlock_0; float3 _S19 = float3(int3(int(0)) ); -#line 102 +#line 86 int i_1 = int(0); -#line 102 +#line 86 float3 Lo_0 = _S19; for(;;) { -#line 103 +#line 87 if(i_1 < ((&kernelContext_1)->light_0->numLights_0)) { } else { -#line 103 +#line 87 break; } -#line 104 +#line 88 float3 lightDir_1 = normalize(- (&kernelContext_1)->light_0->direction_0[i_1]); -#line 104 - float3 _S20 = calculatePbrLighting_0(normal_4, _S17, lightDir_1, &(&kernelContext_1)->materialBlock_0->material_1, (&kernelContext_1)->light_0->color_0[i_1], (&kernelContext_1)->light_0->intensity_0[i_1]); +#line 88 + float3 _S20 = calculatePbrLighting_0(normal_4, _S17, lightDir_1, (&kernelContext_1)->materialBlock_0, (&kernelContext_1)->light_0->color_0[i_1], (&kernelContext_1)->light_0->intensity_0[i_1]); float _S21 = max(dot(normal_4, lightDir_1), 0.0); -#line 108 +#line 92 thread array _S22 = _S16.fragLightPos_1; -#line 108 +#line 92 float _S23 = calcShadowmap_0(i_1, _S21, _S18, &_S22, &kernelContext_1); float3 Lo_1 = Lo_0 + _S20 * float3(_S23) ; -#line 103 +#line 87 i_1 = i_1 + int(1); -#line 103 +#line 87 Lo_0 = Lo_1; -#line 103 +#line 87 } -#line 114 +#line 98 float3 ambient_0 = float3(0.10000000149011612) * mat_0.baseColor_0.xyz * float3(mat_0.ao_0) ; -#line 114 +#line 98 float3 ambient_1; - if(((&kernelContext_1)->params_0->useSsao_0) == 1U) + if(((&kernelContext_1)->light_0->useSsao_0) != 0U) { -#line 117 +#line 101 texture2d _S24 = (&kernelContext_1)->ssaoTex_texture_0; thread uint ssaoW_0; -#line 118 +#line 102 thread uint ssaoH_0; -#line 118 +#line 102 (*(((&kernelContext_1)->ssaoTex_sampler_0)) = (_S24).get_width(0)),(*((&ssaoW_0)) = (_S24).get_height(0)); float2 ssaoUV_0 = fragCoord_0.xy / float2(float(ssaoW_0), float(ssaoH_0)); ; -#line 121 +#line 105 ambient_1 = ambient_0 * float3((((&kernelContext_1)->ssaoTex_texture_0).sample(((&kernelContext_1)->ssaoTex_sampler_0), (ssaoUV_0))).x) ; -#line 117 +#line 101 } else { -#line 117 +#line 101 ambient_1 = ambient_0; -#line 117 +#line 101 } -#line 129 +#line 113 thread FSOutput_0 output_0; (&output_0)->fragColor_0 = float4(pow(uncharted2ToneMapping_0(ambient_1 + Lo_0), float3(0.45454543828964233) ), mat_0.baseColor_0.w); @@ -533,3 +515,4 @@ struct pixelInput_0 return output_0; } + diff --git a/shaders/compiled/PbrBasic.frag.spv b/shaders/compiled/PbrBasic.frag.spv index 338b61c5a5ed89381925945b7817d7e310437fb8..6232229b0ee62df654bb4bbee0ca033126917900 100644 GIT binary patch literal 9984 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 diff --git a/shaders/compiled/PbrBasic.vert.msl b/shaders/compiled/PbrBasic.vert.msl index 243de8e5..99d14b2d 100644 --- a/shaders/compiled/PbrBasic.vert.msl +++ b/shaders/compiled/PbrBasic.vert.msl @@ -44,14 +44,14 @@ struct TranformBlock_natural_0 }; -#line 5176 "core.meta.slang" +#line 993 "core" struct _Array_natural_matrixx3Cfloatx2C4x2C4x3E4_0 { array<_MatrixStorage_float4x4_ColMajornatural_0, int(4)> data_2; }; -#line 5176 +#line 993 struct LightBlockV_natural_0 { _Array_natural_matrixx3Cfloatx2C4x2C4x3E4_0 mvp_1; @@ -160,3 +160,4 @@ struct KernelContext_0 #line 37 return _S3; } + diff --git a/shaders/compiled/PbrTransparent.frag.json b/shaders/compiled/PbrTransparent.frag.json index 112b7f1e..afcd5797 100644 --- a/shaders/compiled/PbrTransparent.frag.json +++ b/shaders/compiled/PbrTransparent.frag.json @@ -7,53 +7,43 @@ "kind": "constantBuffer", "elementType": { "kind": "struct", - "name": "MaterialBlock", + "name": "PbrMaterial", "fields": [ { - "name": "material", + "name": "baseColor", "type": { - "kind": "struct", - "name": "PbrMaterial", - "fields": [ - { - "name": "baseColor", - "type": { - "kind": "vector", - "elementCount": 4, - "elementType": { - "kind": "scalar", - "scalarType": "float32" - } - }, - "binding": {"kind": "uniform", "offset": 0, "size": 16, "elementStride": 4} - }, - { - "name": "metalness", - "type": { - "kind": "scalar", - "scalarType": "float32" - }, - "binding": {"kind": "uniform", "offset": 16, "size": 4, "elementStride": 0} - }, - { - "name": "roughness", - "type": { - "kind": "scalar", - "scalarType": "float32" - }, - "binding": {"kind": "uniform", "offset": 20, "size": 4, "elementStride": 0} - }, - { - "name": "ao", - "type": { - "kind": "scalar", - "scalarType": "float32" - }, - "binding": {"kind": "uniform", "offset": 24, "size": 4, "elementStride": 0} - } - ] + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 0, "size": 16, "elementStride": 4} + }, + { + "name": "metalness", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 16, "size": 4, "elementStride": 0} + }, + { + "name": "roughness", + "type": { + "kind": "scalar", + "scalarType": "float32" }, - "binding": {"kind": "uniform", "offset": 0, "size": 32, "elementStride": 0} + "binding": {"kind": "uniform", "offset": 20, "size": 4, "elementStride": 0} + }, + { + "name": "ao", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 24, "size": 4, "elementStride": 0} } ] }, @@ -63,53 +53,43 @@ "elementVarLayout": { "type": { "kind": "struct", - "name": "MaterialBlock", + "name": "PbrMaterial", "fields": [ { - "name": "material", + "name": "baseColor", "type": { - "kind": "struct", - "name": "PbrMaterial", - "fields": [ - { - "name": "baseColor", - "type": { - "kind": "vector", - "elementCount": 4, - "elementType": { - "kind": "scalar", - "scalarType": "float32" - } - }, - "binding": {"kind": "uniform", "offset": 0, "size": 16, "elementStride": 4} - }, - { - "name": "metalness", - "type": { - "kind": "scalar", - "scalarType": "float32" - }, - "binding": {"kind": "uniform", "offset": 16, "size": 4, "elementStride": 0} - }, - { - "name": "roughness", - "type": { - "kind": "scalar", - "scalarType": "float32" - }, - "binding": {"kind": "uniform", "offset": 20, "size": 4, "elementStride": 0} - }, - { - "name": "ao", - "type": { - "kind": "scalar", - "scalarType": "float32" - }, - "binding": {"kind": "uniform", "offset": 24, "size": 4, "elementStride": 0} - } - ] + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 0, "size": 16, "elementStride": 4} + }, + { + "name": "metalness", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 16, "size": 4, "elementStride": 0} + }, + { + "name": "roughness", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 20, "size": 4, "elementStride": 0} + }, + { + "name": "ao", + "type": { + "kind": "scalar", + "scalarType": "float32" }, - "binding": {"kind": "uniform", "offset": 0, "size": 32, "elementStride": 0} + "binding": {"kind": "uniform", "offset": 24, "size": 4, "elementStride": 0} } ] }, @@ -180,6 +160,14 @@ "scalarType": "int32" }, "binding": {"kind": "uniform", "offset": 192, "size": 4, "elementStride": 0} + }, + { + "name": "useSsao", + "type": { + "kind": "scalar", + "scalarType": "uint32" + }, + "binding": {"kind": "uniform", "offset": 196, "size": 4, "elementStride": 0} } ] }, @@ -245,81 +233,18 @@ "scalarType": "int32" }, "binding": {"kind": "uniform", "offset": 192, "size": 4, "elementStride": 0} - } - ] - }, - "binding": {"kind": "uniform", "offset": 0, "size": 208, "elementStride": 0} - } - } - }, - { - "name": "params", - "binding": {"kind": "descriptorTableSlot", "space": 3, "index": 2}, - "type": { - "kind": "constantBuffer", - "elementType": { - "kind": "struct", - "name": "EffectParams", - "fields": [ - { - "name": "useSsao", - "type": { - "kind": "scalar", - "scalarType": "uint32" }, - "binding": {"kind": "uniform", "offset": 0, "size": 4, "elementStride": 0} - } - ] - }, - "containerVarLayout": { - "binding": {"kind": "descriptorTableSlot", "index": 0} - }, - "elementVarLayout": { - "type": { - "kind": "struct", - "name": "EffectParams", - "fields": [ { "name": "useSsao", "type": { "kind": "scalar", "scalarType": "uint32" }, - "binding": {"kind": "uniform", "offset": 0, "size": 4, "elementStride": 0} + "binding": {"kind": "uniform", "offset": 196, "size": 4, "elementStride": 0} } ] }, - "binding": {"kind": "uniform", "offset": 0, "size": 16, "elementStride": 0} - } - } - }, - { - "name": "shadowMap", - "binding": {"kind": "descriptorTableSlot", "space": 2, "index": 0}, - "type": { - "kind": "resource", - "baseShape": "texture2D", - "combined": true, - "resultType": { - "kind": "scalar", - "scalarType": "float32" - } - } - }, - { - "name": "ssaoTex", - "binding": {"kind": "descriptorTableSlot", "space": 2, "index": 1}, - "type": { - "kind": "resource", - "baseShape": "texture2D", - "combined": true, - "resultType": { - "kind": "vector", - "elementCount": 4, - "elementType": { - "kind": "scalar", - "scalarType": "float32" - } + "binding": {"kind": "uniform", "offset": 0, "size": 208, "elementStride": 0} } } } @@ -424,18 +349,6 @@ { "name": "light", "binding": {"kind": "descriptorTableSlot", "space": 3, "index": 1, "used": 1} - }, - { - "name": "params", - "binding": {"kind": "descriptorTableSlot", "space": 3, "index": 2, "used": 0} - }, - { - "name": "shadowMap", - "binding": {"kind": "descriptorTableSlot", "space": 2, "index": 0, "used": 0} - }, - { - "name": "ssaoTex", - "binding": {"kind": "descriptorTableSlot", "space": 2, "index": 1, "used": 0} } ] } diff --git a/shaders/compiled/PbrTransparent.frag.msl b/shaders/compiled/PbrTransparent.frag.msl index ab3fdd86..3dd71f48 100644 --- a/shaders/compiled/PbrTransparent.frag.msl +++ b/shaders/compiled/PbrTransparent.frag.msl @@ -3,11 +3,11 @@ #include using namespace metal; -#line 17 "shaders/src/pbr_lighting.slang" +#line 27 "shaders/src/pbr_lighting.slang" float distributionGGX_0(float3 normal_0, float3 H_0, float roughness_0) { -#line 18 +#line 28 float a_0 = roughness_0 * roughness_0; float a2_0 = a_0 * a_0; float _S1 = max(dot(normal_0, H_0), 0.0); @@ -23,7 +23,7 @@ float distributionGGX_0(float3 normal_0, float3 H_0, float roughness_0) float geometrySchlickGGX_0(float NdotV_0, float roughness_1) { -#line 31 +#line 41 float r_0 = roughness_1 + 1.0; float k_0 = r_0 * r_0 / 8.0; return NdotV_0 / (NdotV_0 * (1.0 - k_0) + k_0); @@ -38,16 +38,16 @@ float geometrySmith_0(float3 normal_1, float3 V_0, float3 L_0, float roughness_2 } -#line 12 +#line 22 float3 fresnelSchlick_0(float cosTheta_0, float3 F0_0) { -#line 13 +#line 23 return F0_0 + (float3(1.0) - F0_0) * float3(pow(clamp(1.0 - cosTheta_0, 0.0, 1.0), 5.0)) ; } -#line 1 +#line 11 struct PbrMaterial_0 { float4 baseColor_0; @@ -57,11 +57,11 @@ struct PbrMaterial_0 }; -#line 46 +#line 56 float3 calculatePbrLighting_0(float3 normal_2, float3 V_1, float3 lightDir_0, const PbrMaterial_0 constant* material_0, float3 lightColor_0, float lightIntensity_0) { -#line 54 +#line 64 float3 H_1 = normalize(lightDir_0 + V_1); float3 _S2 = material_0->baseColor_0.xyz; @@ -72,7 +72,7 @@ float3 calculatePbrLighting_0(float3 normal_2, float3 V_1, float3 lightDir_0, co float _S3 = dot(normal_2, lightDir_0); -#line 72 +#line 82 return ((float3(1.0) - F_0) * float3((1.0 - material_0->metalness_0)) * _S2 / float3(3.14159274101257324) + float3((distributionGGX_0(normal_2, H_1, material_0->roughness_3) * geometrySmith_0(normal_2, V_1, lightDir_0, material_0->roughness_3))) * F_0 / float3((4.0 * max(dot(normal_2, V_1), _S3) + 0.00009999999747379)) ) * (float3(lightIntensity_0) * lightColor_0) * float3(max(_S3, 0.0)) ; } @@ -98,7 +98,7 @@ float3 uncharted2ToneMapping_0(float3 color_1) } -#line 35 "shaders/src/PbrTransparent.frag.slang" +#line 10 "shaders/src/PbrTransparent.frag.slang" struct FSOutput_0 { float4 accum_0 [[color(0)]]; @@ -106,7 +106,7 @@ struct FSOutput_0 }; -#line 35 +#line 10 struct pixelInput_0 { float3 fragViewPos_0 [[user(_SLANG_ATTR)]]; @@ -115,83 +115,77 @@ struct pixelInput_0 }; -#line 9 -struct MaterialBlock_0 -{ - PbrMaterial_0 material_1; -}; - - -#line 13 +#line 3 "shaders/src/pbr_lighting.slang" struct LightBlock_0 { array direction_0; array color_2; array intensity_0; int numLights_0; + uint useSsao_0; }; -#line 13 +#line 3 struct KernelContext_0 { - MaterialBlock_0 constant* materialBlock_0; + PbrMaterial_0 constant* materialBlock_0; LightBlock_0 constant* light_0; }; -#line 41 -[[fragment]] FSOutput_0 main_0(pixelInput_0 _S5 [[stage_in]], float4 fragCoord_0 [[position]], MaterialBlock_0 constant* materialBlock_1 [[buffer(0)]], LightBlock_0 constant* light_1 [[buffer(1)]]) +#line 16 "shaders/src/PbrTransparent.frag.slang" +[[fragment]] FSOutput_0 main_0(pixelInput_0 _S5 [[stage_in]], float4 fragCoord_0 [[position]], PbrMaterial_0 constant* materialBlock_1 [[buffer(0)]], LightBlock_0 constant* light_1 [[buffer(1)]]) { thread KernelContext_0 kernelContext_0; -#line 44 +#line 19 (&kernelContext_0)->materialBlock_0 = materialBlock_1; -#line 44 +#line 19 (&kernelContext_0)->light_0 = light_1; float3 _S6 = normalize(_S5.fragViewNormal_0); float3 _S7 = normalize(- _S5.fragViewPos_0); - PbrMaterial_0 mat_0 = materialBlock_1->material_1; + PbrMaterial_0 mat_0 = *materialBlock_1; float3 _S8 = float3(int3(int(0)) ); -#line 50 +#line 25 uint i_0 = 0U; -#line 50 +#line 25 float3 Lo_0 = _S8; for(;;) { -#line 51 +#line 26 if(i_0 < uint((&kernelContext_0)->light_0->numLights_0)) { } else { -#line 51 +#line 26 break; } -#line 51 - float3 _S9 = calculatePbrLighting_0(_S6, _S7, normalize(- (&kernelContext_0)->light_0->direction_0[i_0]), &materialBlock_1->material_1, (&kernelContext_0)->light_0->color_2[i_0], (&kernelContext_0)->light_0->intensity_0[i_0]); +#line 26 + float3 _S9 = calculatePbrLighting_0(_S6, _S7, normalize(- (&kernelContext_0)->light_0->direction_0[i_0]), (&kernelContext_0)->materialBlock_0, (&kernelContext_0)->light_0->color_2[i_0], (&kernelContext_0)->light_0->intensity_0[i_0]); float3 Lo_1 = Lo_0 + _S9; -#line 51 +#line 26 i_0 = i_0 + 1U; -#line 51 +#line 26 Lo_0 = Lo_1; -#line 51 +#line 26 } -#line 63 +#line 38 float alpha_0 = mat_0.baseColor_0.w; @@ -202,3 +196,4 @@ struct KernelContext_0 (&output_0)->reveal_0 = 1.0 - alpha_0 * weight_0; return output_0; } + diff --git a/shaders/compiled/PbrTransparent.frag.spv b/shaders/compiled/PbrTransparent.frag.spv index 96f27c0ccb0aec25b5ae71f7bfea607926adca11..5b8c2d139cae89c8e7f61e9dfaab1d5ab2b8c9de 100644 GIT binary patch literal 5628 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 diff --git a/shaders/src/PbrBasic.frag.slang b/shaders/src/PbrBasic.frag.slang index 4434805f..18926943 100644 --- a/shaders/src/PbrBasic.frag.slang +++ b/shaders/src/PbrBasic.frag.slang @@ -7,29 +7,13 @@ import tone_mapping; import pbr_lighting; import config; -struct MaterialBlock { - PbrMaterial material; -}; - -struct LightBlock { - float3 direction[MAX_NUM_LIGHTS]; - float3 color[MAX_NUM_LIGHTS]; - float intensity[MAX_NUM_LIGHTS]; - int numLights; -}; - -struct EffectParams { - uint useSsao; -}; - struct ShadowAtlasInfo { int4 lightRegions[MAX_NUM_LIGHTS]; }; -[vk::binding(0, 3)] ConstantBuffer materialBlock; -[vk::binding(1, 3)] ConstantBuffer light; -[vk::binding(2, 3)] ConstantBuffer params; -[vk::binding(3, 3)] ConstantBuffer shadowAtlas; +[vk::binding(0, 3)] ConstantBuffer materialBlock; +[vk::binding(1, 3)] ConstantBuffer light; +[vk::binding(2, 3)] ConstantBuffer shadowAtlas; #ifdef HAS_SHADOW_MAPS [vk::binding(0, 2)] Sampler2DShadow shadowMap; @@ -97,7 +81,7 @@ FSOutput main([vk::location(0)] float3 fragViewPos, normal = -normal; } - PbrMaterial mat = materialBlock.material; + PbrMaterial mat = materialBlock; float3 Lo = float3(0); for (int i = 0; i < light.numLights; i++) { @@ -114,7 +98,7 @@ FSOutput main([vk::location(0)] float3 fragViewPos, float3 ambient = float3(0.1) * mat.baseColor.rgb * mat.ao; #ifdef HAS_SSAO - if (params.useSsao == 1) { + if (light.useSsao != 0) { uint ssaoW, ssaoH; ssaoTex.GetDimensions(ssaoW, ssaoH); float2 ssaoUV = fragCoord.xy / float2(ssaoW, ssaoH); diff --git a/shaders/src/PbrTransparent.frag.slang b/shaders/src/PbrTransparent.frag.slang index 6d8ffe02..9fe8cb1e 100644 --- a/shaders/src/PbrTransparent.frag.slang +++ b/shaders/src/PbrTransparent.frag.slang @@ -1,36 +1,11 @@ #define HAS_WBOIT -#define HAS_SHADOW_MAPS -#define HAS_SSAO import tone_mapping; import pbr_lighting; import config; -struct MaterialBlock { - PbrMaterial material; -}; - -struct LightBlock { - float3 direction[MAX_NUM_LIGHTS]; - float3 color[MAX_NUM_LIGHTS]; - float intensity[MAX_NUM_LIGHTS]; - int numLights; -}; - -struct EffectParams { - uint useSsao; -}; - -[vk::binding(0, 3)] ConstantBuffer materialBlock; -[vk::binding(1, 3)] ConstantBuffer light; -[vk::binding(2, 3)] ConstantBuffer params; - -#ifdef HAS_SHADOW_MAPS - [vk::binding(0, 2)] Sampler2DShadow shadowMap; -#endif -#ifdef HAS_SSAO - [vk::binding(1, 2)] Sampler2D ssaoTex; -#endif +[vk::binding(0, 3)] ConstantBuffer materialBlock; +[vk::binding(1, 3)] ConstantBuffer light; struct FSOutput { float4 accum : SV_Target0; // R16G16B16A16 accumulation @@ -45,7 +20,7 @@ FSOutput main([vk::location(0)] float3 fragViewPos, float3 normal = normalize(fragViewNormal); float3 V = normalize(-fragViewPos); - PbrMaterial mat = materialBlock.material; + PbrMaterial mat = materialBlock; float3 Lo = float3(0); for (uint i = 0; i < uint(light.numLights); i++) { diff --git a/shaders/src/pbr_lighting.slang b/shaders/src/pbr_lighting.slang index 6be21715..bda3312d 100644 --- a/shaders/src/pbr_lighting.slang +++ b/shaders/src/pbr_lighting.slang @@ -1,3 +1,13 @@ +import config; + +struct LightBlock { + float3 direction[MAX_NUM_LIGHTS]; + float3 color[MAX_NUM_LIGHTS]; + float intensity[MAX_NUM_LIGHTS]; + int numLights; + uint useSsao; +}; + struct PbrMaterial { float4 baseColor; float metalness; diff --git a/src/candlewick/multibody/RobotScene.cpp b/src/candlewick/multibody/RobotScene.cpp index 42e287bc..33f52511 100644 --- a/src/candlewick/multibody/RobotScene.cpp +++ b/src/candlewick/multibody/RobotScene.cpp @@ -34,6 +34,7 @@ struct alignas(16) LightArrayUbo { GpuVec4 color[kNumLights]; GpuVec4 intensity[kNumLights]; Uint32 numLights; + Uint32 useSsao; }; static_assert(std::is_standard_layout_v); @@ -535,6 +536,7 @@ void RobotScene::renderPBRTriangleGeometry(CommandBuffer &command_buffer, // calculate light ubos LightArrayUbo lightUbo; lightUbo.numLights = numLights; + lightUbo.useSsao = m_config.enable_ssao ? 1u : 0u; for (size_t i = 0; i < lightUbo.numLights; i++) { auto &dl = directionalLight[i]; lightUbo.viewSpaceDir[i].head<3>() = camera.transformVector(dl.direction); @@ -565,23 +567,23 @@ void RobotScene::renderPBRTriangleGeometry(CommandBuffer &command_buffer, gBuffer); } - if (shadowsEnabled()) { - rend::bindFragmentSamplers(render_pass, SHADOW_MAP_SLOT, + command_buffer.pushFragmentUniform(FragmentUniformSlots::LIGHTING, lightUbo); + if (!transparent) { + if (shadowsEnabled()) { + rend::bindFragmentSamplers(render_pass, SHADOW_MAP_SLOT, + {{ + .texture = shadowPass.shadowMap, + .sampler = shadowPass.sampler, + }}); + } + rend::bindFragmentSamplers(render_pass, SSAO_SLOT, {{ - .texture = shadowPass.shadowMap, - .sampler = shadowPass.sampler, + .texture = ssaoPass.ssaoMap, + .sampler = ssaoPass.texSampler, }}); + command_buffer.pushFragmentUniform(FragmentUniformSlots::ATLAS_INFO, + shadowAtlasUbo); } - rend::bindFragmentSamplers(render_pass, SSAO_SLOT, - {{ - .texture = ssaoPass.ssaoMap, - .sampler = ssaoPass.texSampler, - }}); - int _useSsao = m_config.enable_ssao; - command_buffer // - .pushFragmentUniform(FragmentUniformSlots::LIGHTING, lightUbo) - .pushFragmentUniform(FragmentUniformSlots::SSAO_FLAG, _useSsao) - .pushFragmentUniform(FragmentUniformSlots::ATLAS_INFO, shadowAtlasUbo); auto view = m_registry.view Date: Thu, 26 Feb 2026 14:24:01 +0100 Subject: [PATCH 2/6] SSAO : move kernelSize to ssao params ubo --- shaders/compiled/PbrBasic.frag.msl | 1 - shaders/compiled/PbrBasic.vert.msl | 1 - shaders/compiled/PbrTransparent.frag.msl | 1 - shaders/compiled/SSAO.frag.json | 36 +++++++++++------------ shaders/compiled/SSAO.frag.msl | 6 ++-- shaders/compiled/SSAO.frag.spv | Bin 4648 -> 4632 bytes shaders/src/SSAO.frag.slang | 6 ++-- src/candlewick/posteffects/SSAO.cpp | 36 +++++++++++++---------- 8 files changed, 44 insertions(+), 43 deletions(-) diff --git a/shaders/compiled/PbrBasic.frag.msl b/shaders/compiled/PbrBasic.frag.msl index 9289d6d8..390e9c63 100644 --- a/shaders/compiled/PbrBasic.frag.msl +++ b/shaders/compiled/PbrBasic.frag.msl @@ -515,4 +515,3 @@ struct pixelInput_0 return output_0; } - diff --git a/shaders/compiled/PbrBasic.vert.msl b/shaders/compiled/PbrBasic.vert.msl index 99d14b2d..59dcbcde 100644 --- a/shaders/compiled/PbrBasic.vert.msl +++ b/shaders/compiled/PbrBasic.vert.msl @@ -160,4 +160,3 @@ struct KernelContext_0 #line 37 return _S3; } - diff --git a/shaders/compiled/PbrTransparent.frag.msl b/shaders/compiled/PbrTransparent.frag.msl index 3dd71f48..39687ca8 100644 --- a/shaders/compiled/PbrTransparent.frag.msl +++ b/shaders/compiled/PbrTransparent.frag.msl @@ -196,4 +196,3 @@ struct KernelContext_0 (&output_0)->reveal_0 = 1.0 - alpha_0 * weight_0; return output_0; } - diff --git a/shaders/compiled/SSAO.frag.json b/shaders/compiled/SSAO.frag.json index 97fbc994..91a379b6 100644 --- a/shaders/compiled/SSAO.frag.json +++ b/shaders/compiled/SSAO.frag.json @@ -76,6 +76,14 @@ "uniformStride": 16 }, "binding": {"kind": "uniform", "offset": 0, "size": 1024, "elementStride": 16} + }, + { + "name": "kernelSize", + "type": { + "kind": "scalar", + "scalarType": "uint32" + }, + "binding": {"kind": "uniform", "offset": 1024, "size": 4, "elementStride": 0} } ] }, @@ -103,10 +111,18 @@ "uniformStride": 16 }, "binding": {"kind": "uniform", "offset": 0, "size": 1024, "elementStride": 16} + }, + { + "name": "kernelSize", + "type": { + "kind": "scalar", + "scalarType": "uint32" + }, + "binding": {"kind": "uniform", "offset": 1024, "size": 4, "elementStride": 0} } ] }, - "binding": {"kind": "uniform", "offset": 0, "size": 1024, "elementStride": 0} + "binding": {"kind": "uniform", "offset": 0, "size": 1040, "elementStride": 0} } } }, @@ -144,14 +160,6 @@ } }, "binding": {"kind": "uniform", "offset": 64, "size": 64, "elementStride": 0} - }, - { - "name": "kernelSize", - "type": { - "kind": "scalar", - "scalarType": "uint32" - }, - "binding": {"kind": "uniform", "offset": 128, "size": 4, "elementStride": 0} } ] }, @@ -188,18 +196,10 @@ } }, "binding": {"kind": "uniform", "offset": 64, "size": 64, "elementStride": 0} - }, - { - "name": "kernelSize", - "type": { - "kind": "scalar", - "scalarType": "uint32" - }, - "binding": {"kind": "uniform", "offset": 128, "size": 4, "elementStride": 0} } ] }, - "binding": {"kind": "uniform", "offset": 0, "size": 144, "elementStride": 0} + "binding": {"kind": "uniform", "offset": 0, "size": 128, "elementStride": 0} } } } diff --git a/shaders/compiled/SSAO.frag.msl b/shaders/compiled/SSAO.frag.msl index 7f8bb833..2fe561c0 100644 --- a/shaders/compiled/SSAO.frag.msl +++ b/shaders/compiled/SSAO.frag.msl @@ -15,7 +15,6 @@ struct Camera_natural_0 { _MatrixStorage_float4x4_ColMajornatural_0 projection_0; _MatrixStorage_float4x4_ColMajornatural_0 projectionInverse_0; - uint kernelSize_0; }; @@ -23,6 +22,7 @@ struct Camera_natural_0 struct SSAOParams_0 { array samples_0; + uint kernelSize_0; }; @@ -103,7 +103,7 @@ float calculatePixelAO_0(float2 uv_2, KernelContext_0 thread* kernelContext_2) { #line 54 - if(i_0 < int(kernelContext_2->camera_0->kernelSize_0)) + if(i_0 < int(kernelContext_2->kernel_0->kernelSize_0)) { } else @@ -170,7 +170,7 @@ float calculatePixelAO_0(float2 uv_2, KernelContext_0 thread* kernelContext_2) } #line 70 - return 1.0 - occlusion_0 / float(kernelContext_2->camera_0->kernelSize_0) * 1.5; + return 1.0 - occlusion_0 / float(kernelContext_2->kernel_0->kernelSize_0) * 1.5; } diff --git a/shaders/compiled/SSAO.frag.spv b/shaders/compiled/SSAO.frag.spv index 8bd417e376c2b0e61cf05622e3cc1629f1c1be5a..caabe257dff7037e103b1941c37907dea0174e55 100644 GIT binary patch delta 833 zcmYjPO-~b16n(Gl3}V~RTF1tqjR*!wNsvTij6jElQ8NpMbY%!76PyL1L!fm7H6gCt zSYW)165|grA+8#iF8vWKT)A+`!nic?ocTz&&7F78Id|^In|_%(ojSR%Tj9*(VnZqA zz}Rn;&O5K5SZO)oQC-FG#9`%rH02@OK;VX zumEB)@jJjvh}o2U9rzkf8_q`5mvK_(JE`s>rdiN&Kgf%%3fxBM%Y;!qOtX){*zj9W zc@0%Kxf)jHHIU*h#Q`d z=Jm}M;4^pyQbCQVF~m0zx8&c|s&>W7Z(3Yn92~!q4PV4GzV!2RdLZBPD+YO2%7qH@ x?-kCXp=OcK>D}SaLL(DVVM5t5GxiG;7E5(JpOhLXvtRn7Z3)T^?aSA4?>_?9Zr}g_ delta 794 zcmYjPL2DCH5Pp+%x28!+Vq8OrEv*)6iBNj#L7VIrM1>XElLslwQhN{@5Zge`xZLk%X~B6ym>P(IbQg>@cy>M>C)=7Z;T0n z0WeDYMvrXh0o6&f&0J>)N%PHz}zez zia!T)TZE@W-iwUk8u%_f%6N zb;_F_U!ski56>4{!!%vpFE2}~r{yOOf5=Fs(m=geImw2)W9y^w_e!sjrBa&;v{n6y b3IA0)_+F~@(B?($uLQbL?@3ob*9ZRr;EiR> diff --git a/shaders/src/SSAO.frag.slang b/shaders/src/SSAO.frag.slang index 83a836b8..a6dbda9c 100644 --- a/shaders/src/SSAO.frag.slang +++ b/shaders/src/SSAO.frag.slang @@ -9,12 +9,12 @@ static const float SSAO_INTENSITY = 1.5; struct SSAOParams { float4 samples[SSAO_MAX_KERNEL_SIZE]; + uint kernelSize; }; struct Camera { float4x4 projection; float4x4 projectionInverse; - uint kernelSize; }; [vk::binding(0, 3)] ConstantBuffer kernel; @@ -51,7 +51,7 @@ float calculatePixelAO(float2 uv) { // to GLSL's mat3(tangent, bitangent, viewNormal) * v (column-major multiply) float occlusion = 0.0; - for (int i = 0; i < int(camera.kernelSize); i++) { + for (int i = 0; i < int(kernel.kernelSize); i++) { float3 samplePos = mul(kernel.samples[i].xyz, float3x3(tangent, bitangent, viewNormal)); samplePos = viewPos + samplePos * SSAO_RADIUS; @@ -66,7 +66,7 @@ float calculatePixelAO(float2 uv) { occlusion += (sampleViewPos.z >= samplePos.z + SSAO_BIAS ? 1.0 : 0.0) * rangeCheck; } - occlusion = 1.0 - (occlusion / float(camera.kernelSize)) * SSAO_INTENSITY; + occlusion = 1.0 - (occlusion / float(kernel.kernelSize)) * SSAO_INTENSITY; return occlusion; } diff --git a/src/candlewick/posteffects/SSAO.cpp b/src/candlewick/posteffects/SSAO.cpp index 99b2ed7c..091fed7f 100644 --- a/src/candlewick/posteffects/SSAO.cpp +++ b/src/candlewick/posteffects/SSAO.cpp @@ -17,7 +17,7 @@ namespace ssao { inline bool isPowerOfTwo(size_t n) { return (n > 0) && ((n & (n - 1)) == 0); } // https://sudonull.com/post/102169-Normal-oriented-Hemisphere-SSAO-for-Dummies - std::vector generateSsaoKernel(size_t kernelSize) { + template auto generateSsaoKernel() { if (!isPowerOfTwo(kernelSize)) terminate_with_message( "Kernel size must be a power of two. (Current: {:d})", kernelSize); @@ -26,13 +26,13 @@ namespace ssao { std::mt19937 gen{seed}; std::uniform_real_distribution rfloat{0., 1.}; - std::vector kernel; - kernel.resize(kernelSize); + std::array kernel; for (size_t i = 0; i < kernelSize; i++) { GpuVec3 sample; sample.setRandom(); - sample.head<2>() = 2.f * sample.head<2>() - GpuVec2::Ones(); + sample.template head<2>() = + 2.f * sample.template head<2>() - GpuVec2::Ones(); sample.normalize(); sample *= rfloat(gen); @@ -40,15 +40,22 @@ namespace ssao { scale = lerp(0.1f, 10.f, scale * scale); sample *= scale; - kernel[i].head<3>() = sample; + kernel[i].template head<3>() = sample; kernel[i].w() = 1.f; } return kernel; } + struct SsaoParamUbo { + std::array samples; + Uint32 kernelSize; + }; // Maximum-size kernel shared across all SsaoPass instances. - // Each pass uses only its configured kernelSize samples. - static const std::vector g_maxKernelSamples = generateSsaoKernel(64ul); + // Each pass only has to set the configured kernel size. + thread_local static SsaoParamUbo g_ssaoParam = { + generateSsaoKernel<64u>(), + 64u, + }; Texture create_noise_texture(const Device &device, Uint32 size) { return Texture{device, @@ -226,13 +233,13 @@ namespace ssao { void SsaoPass::render(CommandBuffer &cmdBuf, const Camera &camera) { // std140 layout: two mat4 (128 bytes) + uint (4 bytes) padded to 144 bytes. - struct CameraUniforms { + struct CameraUbo { GpuMat4 projection; GpuMat4 projectionInverse; - Uint32 kernelSize; - Uint32 _pad[3]; } cameraUniforms{ - camera.projection, camera.projection.inverse(), this->kernelSize, {}}; + camera.projection, + camera.projection.inverse(), + }; SDL_GPUColorTargetInfo color_info{ .texture = ssaoMap, .layer_or_depth_plane = 0, @@ -249,11 +256,8 @@ namespace ssao { {.texture = inNormalMap, .sampler = texSampler}, {.texture = ssaoNoise.tex, .sampler = ssaoNoise.sampler}, }); - auto SAMPLES_PAYLOAD_BYTES = - Uint32(g_maxKernelSamples.size() * sizeof(GpuVec4)); - cmdBuf - .pushFragmentUniformRaw(0, g_maxKernelSamples.data(), - SAMPLES_PAYLOAD_BYTES) + g_ssaoParam.kernelSize = this->kernelSize; + cmdBuf.pushFragmentUniform(0, g_ssaoParam) .pushFragmentUniform(1, cameraUniforms); pipeline.bind(render_pass); SDL_DrawGPUPrimitives(render_pass, 6, 1, 0, 0); From 447985f7025f7fb2eac6fff7348c68cb8a78e4d0 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Thu, 26 Feb 2026 14:31:14 +0100 Subject: [PATCH 3/6] posteffects : remove screen space shadows I never got to work --- shaders/compiled/ScreenSpaceShadows.frag.json | 195 -------------- shaders/compiled/ScreenSpaceShadows.frag.msl | 255 ------------------ shaders/compiled/ScreenSpaceShadows.frag.spv | Bin 3932 -> 0 bytes shaders/src/ScreenSpaceShadows.frag.slang | 66 ----- src/CMakeLists.txt | 1 - .../posteffects/ScreenSpaceShadows.cpp | 133 --------- .../posteffects/ScreenSpaceShadows.h | 42 --- 7 files changed, 692 deletions(-) delete mode 100644 shaders/compiled/ScreenSpaceShadows.frag.json delete mode 100644 shaders/compiled/ScreenSpaceShadows.frag.msl delete mode 100644 shaders/compiled/ScreenSpaceShadows.frag.spv delete mode 100644 shaders/src/ScreenSpaceShadows.frag.slang delete mode 100644 src/candlewick/posteffects/ScreenSpaceShadows.cpp delete mode 100644 src/candlewick/posteffects/ScreenSpaceShadows.h diff --git a/shaders/compiled/ScreenSpaceShadows.frag.json b/shaders/compiled/ScreenSpaceShadows.frag.json deleted file mode 100644 index 20c85418..00000000 --- a/shaders/compiled/ScreenSpaceShadows.frag.json +++ /dev/null @@ -1,195 +0,0 @@ -{ - "parameters": [ - { - "name": "depthTexture", - "binding": {"kind": "descriptorTableSlot", "space": 2, "index": 0}, - "type": { - "kind": "resource", - "baseShape": "texture2D", - "combined": true, - "resultType": { - "kind": "vector", - "elementCount": 4, - "elementType": { - "kind": "scalar", - "scalarType": "float32" - } - } - } - }, - { - "name": "shadow", - "binding": {"kind": "descriptorTableSlot", "space": 3, "index": 0}, - "type": { - "kind": "constantBuffer", - "elementType": { - "kind": "struct", - "name": "ShadowParams", - "fields": [ - { - "name": "projection", - "type": { - "kind": "matrix", - "rowCount": 4, - "columnCount": 4, - "elementType": { - "kind": "scalar", - "scalarType": "float32" - } - }, - "binding": {"kind": "uniform", "offset": 0, "size": 64, "elementStride": 0} - }, - { - "name": "invProjection", - "type": { - "kind": "matrix", - "rowCount": 4, - "columnCount": 4, - "elementType": { - "kind": "scalar", - "scalarType": "float32" - } - }, - "binding": {"kind": "uniform", "offset": 64, "size": 64, "elementStride": 0} - }, - { - "name": "lightDir", - "type": { - "kind": "vector", - "elementCount": 3, - "elementType": { - "kind": "scalar", - "scalarType": "float32" - } - }, - "binding": {"kind": "uniform", "offset": 128, "size": 12, "elementStride": 4} - }, - { - "name": "maxDistance", - "type": { - "kind": "scalar", - "scalarType": "float32" - }, - "binding": {"kind": "uniform", "offset": 140, "size": 4, "elementStride": 0} - }, - { - "name": "numSteps", - "type": { - "kind": "scalar", - "scalarType": "int32" - }, - "binding": {"kind": "uniform", "offset": 144, "size": 4, "elementStride": 0} - } - ] - }, - "containerVarLayout": { - "binding": {"kind": "descriptorTableSlot", "index": 0} - }, - "elementVarLayout": { - "type": { - "kind": "struct", - "name": "ShadowParams", - "fields": [ - { - "name": "projection", - "type": { - "kind": "matrix", - "rowCount": 4, - "columnCount": 4, - "elementType": { - "kind": "scalar", - "scalarType": "float32" - } - }, - "binding": {"kind": "uniform", "offset": 0, "size": 64, "elementStride": 0} - }, - { - "name": "invProjection", - "type": { - "kind": "matrix", - "rowCount": 4, - "columnCount": 4, - "elementType": { - "kind": "scalar", - "scalarType": "float32" - } - }, - "binding": {"kind": "uniform", "offset": 64, "size": 64, "elementStride": 0} - }, - { - "name": "lightDir", - "type": { - "kind": "vector", - "elementCount": 3, - "elementType": { - "kind": "scalar", - "scalarType": "float32" - } - }, - "binding": {"kind": "uniform", "offset": 128, "size": 12, "elementStride": 4} - }, - { - "name": "maxDistance", - "type": { - "kind": "scalar", - "scalarType": "float32" - }, - "binding": {"kind": "uniform", "offset": 140, "size": 4, "elementStride": 0} - }, - { - "name": "numSteps", - "type": { - "kind": "scalar", - "scalarType": "int32" - }, - "binding": {"kind": "uniform", "offset": 144, "size": 4, "elementStride": 0} - } - ] - }, - "binding": {"kind": "uniform", "offset": 0, "size": 160, "elementStride": 0} - } - } - } - ], - "entryPoints": [ - { - "name": "main", - "stage": "fragment", - "parameters": [ - { - "name": "fragUV", - "stage": "fragment", - "binding": {"kind": "varyingInput", "index": 0}, - "type": { - "kind": "vector", - "elementCount": 2, - "elementType": { - "kind": "scalar", - "scalarType": "float32" - } - } - } - ], - "result": { - "stage": "fragment", - "binding": {"kind": "varyingOutput", "index": 0}, - "semanticName": "SV_TARGET", - "type": { - "kind": "scalar", - "scalarType": "float32" - } - }, - "bindings": [ - { - "name": "depthTexture", - "binding": {"kind": "descriptorTableSlot", "space": 2, "index": 0, "used": 1} - }, - { - "name": "shadow", - "binding": {"kind": "descriptorTableSlot", "space": 3, "index": 0, "used": 1} - } - ] - } - ], - "bindlessSpaceIndex": 0 -} diff --git a/shaders/compiled/ScreenSpaceShadows.frag.msl b/shaders/compiled/ScreenSpaceShadows.frag.msl deleted file mode 100644 index db55690a..00000000 --- a/shaders/compiled/ScreenSpaceShadows.frag.msl +++ /dev/null @@ -1,255 +0,0 @@ -#include -#include -#include -using namespace metal; - -#line 90 "core" -struct _MatrixStorage_float4x4_ColMajornatural_0 -{ - array data_0; -}; - - -#line 90 -struct ShadowParams_natural_0 -{ - _MatrixStorage_float4x4_ColMajornatural_0 projection_0; - _MatrixStorage_float4x4_ColMajornatural_0 invProjection_0; - float3 lightDir_0; - float maxDistance_0; - int numSteps_0; -}; - - -#line 5176 "core.meta.slang" -struct KernelContext_0 -{ - texture2d depthTexture_texture_0; - sampler depthTexture_sampler_0; - ShadowParams_natural_0 constant* shadow_0; -}; - - -#line 18 "shaders/src/ScreenSpaceShadows.frag.slang" -float3 computeViewPos_0(float3 ndcPos_0, KernelContext_0 thread* kernelContext_0) -{ - -#line 19 - float4 viewPos_0 = (((float4(ndcPos_0, 1.0)) * (matrix (kernelContext_0->shadow_0->invProjection_0.data_0[int(0)][int(0)], kernelContext_0->shadow_0->invProjection_0.data_0[int(1)][int(0)], kernelContext_0->shadow_0->invProjection_0.data_0[int(2)][int(0)], kernelContext_0->shadow_0->invProjection_0.data_0[int(3)][int(0)], kernelContext_0->shadow_0->invProjection_0.data_0[int(0)][int(1)], kernelContext_0->shadow_0->invProjection_0.data_0[int(1)][int(1)], kernelContext_0->shadow_0->invProjection_0.data_0[int(2)][int(1)], kernelContext_0->shadow_0->invProjection_0.data_0[int(3)][int(1)], kernelContext_0->shadow_0->invProjection_0.data_0[int(0)][int(2)], kernelContext_0->shadow_0->invProjection_0.data_0[int(1)][int(2)], kernelContext_0->shadow_0->invProjection_0.data_0[int(2)][int(2)], kernelContext_0->shadow_0->invProjection_0.data_0[int(3)][int(2)], kernelContext_0->shadow_0->invProjection_0.data_0[int(0)][int(3)], kernelContext_0->shadow_0->invProjection_0.data_0[int(1)][int(3)], kernelContext_0->shadow_0->invProjection_0.data_0[int(2)][int(3)], kernelContext_0->shadow_0->invProjection_0.data_0[int(3)][int(3)])))); - return viewPos_0.xyz / float3(viewPos_0.w) ; -} - - -#line 7 "shaders/src/utils.slang" -bool isCoordsInRange_0(float2 uv_0) -{ - -#line 8 - float _S1 = uv_0.x; - -#line 8 - bool _S2; - -#line 8 - if(_S1 >= 0.0) - { - -#line 8 - _S2 = (uv_0.y) >= 0.0; - -#line 8 - } - else - { - -#line 8 - _S2 = false; - -#line 8 - } - -#line 8 - if(_S2) - { - -#line 8 - _S2 = _S1 <= 1.0; - -#line 8 - } - else - { - -#line 8 - _S2 = false; - -#line 8 - } - if(_S2) - { - -#line 9 - _S2 = (uv_0.y) <= 1.0; - -#line 9 - } - else - { - -#line 9 - _S2 = false; - -#line 9 - } - -#line 8 - return _S2; -} - - -#line 8 -struct pixelOutput_0 -{ - float output_0 [[color(0)]]; -}; - - -#line 8 -struct pixelInput_0 -{ - float2 fragUV_0 [[user(_SLANG_ATTR)]]; -}; - - -#line 24 "shaders/src/ScreenSpaceShadows.frag.slang" -[[fragment]] pixelOutput_0 main_0(pixelInput_0 _S3 [[stage_in]], texture2d depthTexture_texture_1 [[texture(0)]], sampler depthTexture_sampler_1 [[sampler(0)]], ShadowParams_natural_0 constant* shadow_1 [[buffer(0)]]) -{ - -#line 24 - thread KernelContext_0 kernelContext_1; - -#line 24 - (&kernelContext_1)->depthTexture_texture_0 = depthTexture_texture_1; - -#line 24 - (&kernelContext_1)->depthTexture_sampler_0 = depthTexture_sampler_1; - -#line 24 - (&kernelContext_1)->shadow_0 = shadow_1; - ; - -#line 25 - float depth_0 = (((&kernelContext_1)->depthTexture_texture_0).sample(((&kernelContext_1)->depthTexture_sampler_0), (_S3.fragUV_0))).x; - - if(depth_0 >= 1.0) - { - -#line 27 - pixelOutput_0 _S4 = { 1.0 }; - return _S4; - } - -#line 28 - float occlusion_0; - -#line 28 - float3 _S5 = computeViewPos_0(float3(_S3.fragUV_0 * float2(2.0) - float2(1.0) , depth_0), &kernelContext_1); - -#line 38 - float3 _S6 = normalize(- (&kernelContext_1)->shadow_0->lightDir_0) * float3((0.05000000074505806 / float((&kernelContext_1)->shadow_0->numSteps_0))) ; - -#line 38 - int i_0 = int(0); - -#line 38 - float3 rayPos_0 = _S5; - -#line 43 - for(;;) - { - -#line 43 - if(i_0 < ((&kernelContext_1)->shadow_0->numSteps_0)) - { - } - else - { - -#line 43 - occlusion_0 = 0.0; - -#line 43 - break; - } - -#line 44 - float3 rayPos_1 = rayPos_0 + _S6; - - float4 projectedPos_0 = (((float4(rayPos_1, 1.0)) * (matrix ((&kernelContext_1)->shadow_0->projection_0.data_0[int(0)][int(0)], (&kernelContext_1)->shadow_0->projection_0.data_0[int(1)][int(0)], (&kernelContext_1)->shadow_0->projection_0.data_0[int(2)][int(0)], (&kernelContext_1)->shadow_0->projection_0.data_0[int(3)][int(0)], (&kernelContext_1)->shadow_0->projection_0.data_0[int(0)][int(1)], (&kernelContext_1)->shadow_0->projection_0.data_0[int(1)][int(1)], (&kernelContext_1)->shadow_0->projection_0.data_0[int(2)][int(1)], (&kernelContext_1)->shadow_0->projection_0.data_0[int(3)][int(1)], (&kernelContext_1)->shadow_0->projection_0.data_0[int(0)][int(2)], (&kernelContext_1)->shadow_0->projection_0.data_0[int(1)][int(2)], (&kernelContext_1)->shadow_0->projection_0.data_0[int(2)][int(2)], (&kernelContext_1)->shadow_0->projection_0.data_0[int(3)][int(2)], (&kernelContext_1)->shadow_0->projection_0.data_0[int(0)][int(3)], (&kernelContext_1)->shadow_0->projection_0.data_0[int(1)][int(3)], (&kernelContext_1)->shadow_0->projection_0.data_0[int(2)][int(3)], (&kernelContext_1)->shadow_0->projection_0.data_0[int(3)][int(3)])))); - float3 screenPos_0 = projectedPos_0.xyz / float3(projectedPos_0.w) ; - -#line 47 - float2 _S7 = float2(0.5) ; - - float2 rayUV_0 = _S7 + screenPos_0.xy * _S7; - float rayDepth_0 = screenPos_0.z; - ; - -#line 51 - float sceneDepth_0 = (((&kernelContext_1)->depthTexture_texture_0).sample(((&kernelContext_1)->depthTexture_sampler_0), (rayUV_0))).x; - - if(!isCoordsInRange_0(rayUV_0)) - { - -#line 53 - occlusion_0 = 0.0; - break; - } - - float depthDelta_0 = rayDepth_0 - sceneDepth_0 - 0.00100000004749745; - -#line 57 - bool _S8; - - if(depthDelta_0 >= 0.0) - { - -#line 59 - _S8 = depthDelta_0 < 0.01999999955296516; - -#line 59 - } - else - { - -#line 59 - _S8 = false; - -#line 59 - } - -#line 59 - if(_S8) - { - -#line 59 - occlusion_0 = 1.0; - - break; - } - -#line 43 - i_0 = i_0 + int(1); - -#line 43 - rayPos_0 = rayPos_1; - -#line 43 - } - -#line 43 - pixelOutput_0 _S9 = { 1.0 - occlusion_0 }; - -#line 65 - return _S9; -} diff --git a/shaders/compiled/ScreenSpaceShadows.frag.spv b/shaders/compiled/ScreenSpaceShadows.frag.spv deleted file mode 100644 index 9ed5cbb16b8f4aad6114e311f4c245b8c31e030a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3932 zcmZXW*>BWU6vuziPRqWpqS#WDO&TCz5J50h%L56Og1EzE`hyO(Gi7F=pbuhr@j(m; ze}WI12u5Cv59o^~sL{Af;)?r@Z>}-%^ZCua?F26Q_MG!Q=bm%!x%b!7G`6EP$&E>p zWNGp{KV8$4v5CyYq$Syl?B3qHy|Y^D>s-5TmHsJ7lOl_mnv74H(Z_mwSG-DZ&SEP0V?E`naaY>8WHNiog~Gt$YO!q59RIH7nzQ=* zEBOPv?>43->#Z*xs`c+mkJb)XQnqIKJCW7=;Lt$Ym)RaPi_84uva_V6T7`~^rCLwE zk{{d~&uf31h%5CKLcguaR_xyXd|!Dui>>Zueyi86qJx&qhdUXnlng6~afSoM1O2tGVg+@C_cjLeN4tvETE0|BM|kh0ba=40mJTt+`Z>LqYSveM zW_z>==q)}nG7IlxboROAkTHcynwGNTW%D^wk8!Nnxn#I*cR5`;zB5e2R_uY-gH)V6xw~czv*ws-N zaLpr}^JR z&g8V#YR|r?`n#FUo*Y~o(AS3Dg0vs`ImC|3_#~N&Z#=rT`HY=_G*(`FQm~DgMZGD3 zpBi{=^DIUh<2l`TBXSIopHH@>Nd0og#HH<8KnKf^#<_omBumcxE0OMZJ}daCz6K=8 z@y*7sMe_{u(Z2zmwPhauE);XPe_{B}`&*B0e@}%O--0gZ8$S`ajp*{uzX#6u8meaG(tdG~qV_kert=~Up}54^EEIKBBl0P?~W?={ZnLpXijaSyX} z&qqK$;)&4f$8hG;Z?AqwyMVp!1orATwHwHnvAqNT{>Yg}+rMXiZ}R5x`??>P$M4QO z_VECae=OJ!25wU5^C4{i@8dV1&)K_gAJAtV@2(Y@54!Ktb9j$4k=~>74{CHE+ks2} zETn#=_UvFQwdVv|8PDE_?%AWAqFetQz4`X`13BY-dvlR4-=040MZmgB`}f;939M<4 z`izTn>PPonkB9RY(dG7m_@)k`J74GEKHt>CKt8^y0d)7S0r5=@qRSf_-&6@*UbwD& zQ)M`PO(4FhA$0kO_@)lQnNR-?Cbbw@0rJ9S{`g&0(e>AW=QaKaxD52gcRh^met(B~ z-et(6pz(LcvB0_C75DmoAbqaLeS#k2;_s19;p9&O@A4ATR5qTPT zmzR+GjEi-?K(~%(j&;67m$y#LA=jAW61L~`jeP~IV^7~9UG^mZ4fq;ZR~hrgo{ZOL z-1+ckzeV?)zKa+yXZ;wjjP<`qkM(~+cUfQlNALr%hBD@h^^MnOT%5^I=y4{or=Q{E z8+($or`{Imkh2eUdz_4P{^supK4bjdJ`VXD7zVzb z$ejuNS!BG+=h5ZOW$kN`E^F(%1}p&9R$6-+GS0_%ea5{M?&k$`bDje+Ud~=)yfV(> zMRapoe<9LkefjHvoHf+r*`0Ia*^SY@KEx`u+k&mMUJiL4w1VSU+AjyL8)<%ha_SS2 u{thx%JJLRs+B1Xg{LSs$Uj^PxocU|$_9}0_bx1k)UqG5q`5#}{dhkC;8 shadow; - -static const float SSS_THICKNESS = 0.02; -static const float SSS_MAX_RAY_DISTANCE = 0.05; - -float3 computeViewPos(float3 ndcPos) { - float4 viewPos = mul(shadow.invProjection, float4(ndcPos, 1.0)); - return viewPos.xyz / viewPos.w; -} - -[shader("fragment")] -float main([vk::location(0)] float2 fragUV) : SV_Target0 { - float depth = depthTexture.Sample(fragUV).r; - - if (depth >= 1.0) { - return 1.0; - } - - const float3 ndcPos = float3(fragUV * 2.0 - 1.0, depth); - const float3 viewPos = computeViewPos(ndcPos); - - float3 rayPos = viewPos; - - const float stepSize = SSS_MAX_RAY_DISTANCE / float(shadow.numSteps); - float3 toLight = normalize(-shadow.lightDir); - float3 rayStep = toLight * stepSize; - - float depthDelta; - float occlusion = 0.0; - - for (int i = 0; i < shadow.numSteps; i++) { - rayPos += rayStep; - - float4 projectedPos = mul(shadow.projection, float4(rayPos, 1.0)); - float3 screenPos = projectedPos.xyz / projectedPos.w; - - float2 rayUV = 0.5 + screenPos.xy * 0.5; - float rayDepth = screenPos.z; - float sceneDepth = depthTexture.Sample(rayUV).r; - - if (!isCoordsInRange(rayUV)) { - break; - } - - depthDelta = rayDepth - sceneDepth - 0.001; - - if ((depthDelta >= 0.0) && (depthDelta < SSS_THICKNESS)) { - occlusion = 1.0; - break; - } - } - - return 1.0 - occlusion; -} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ce179901..c9029f8f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,7 +20,6 @@ add_library( candlewick/core/Texture.cpp candlewick/core/debug/DepthViz.cpp candlewick/core/debug/Frustum.cpp - candlewick/posteffects/ScreenSpaceShadows.cpp candlewick/posteffects/SSAO.cpp candlewick/utils/LoadMesh.cpp candlewick/utils/LoadMaterial.cpp diff --git a/src/candlewick/posteffects/ScreenSpaceShadows.cpp b/src/candlewick/posteffects/ScreenSpaceShadows.cpp deleted file mode 100644 index 5ff7ae5e..00000000 --- a/src/candlewick/posteffects/ScreenSpaceShadows.cpp +++ /dev/null @@ -1,133 +0,0 @@ -#include "ScreenSpaceShadows.h" - -#include "../core/math_types.h" -#include "../core/DepthAndShadowPass.h" -#include "../core/RenderContext.h" -#include "../core/Shader.h" -#include "../core/Camera.h" - -namespace candlewick { -namespace effects { - ScreenSpaceShadowPass::ScreenSpaceShadowPass(const RenderContext &renderer, - const Config &config) - : config(config), depthTexture(renderer.depthTarget()) { - const Device &device = renderer.device; - - auto vertexShader = Shader::fromMetadata(device, "ShadowCast.vert"); - auto fragmentShader = - Shader::fromMetadata(device, "ScreenSpaceShadows.frag"); - - auto outputAttachmentFormat = SDL_GPU_TEXTUREFORMAT_R32_FLOAT; - SDL_GPUColorTargetDescription color_target_desc; - SDL_zero(color_target_desc); - color_target_desc.format = outputAttachmentFormat; - SDL_GPUGraphicsPipelineCreateInfo pipeline_desc{ - .vertex_shader = vertexShader, - .fragment_shader = fragmentShader, - .vertex_input_state{}, - .primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, - .rasterizer_state{.fill_mode = SDL_GPU_FILLMODE_FILL, - .cull_mode = SDL_GPU_CULLMODE_BACK}, - .target_info{.color_target_descriptions = &color_target_desc, - .num_color_targets = 1, - .has_depth_stencil_target = false}, - .props = 0, - }; - - pipeline = SDL_CreateGPUGraphicsPipeline(device, &pipeline_desc); - assert(pipeline); - - auto [width, height] = renderer.window.sizeInPixels(); - SDL_GPUTextureCreateInfo texture_desc{ - .type = SDL_GPU_TEXTURETYPE_2D, - .format = outputAttachmentFormat, - .usage = - SDL_GPU_TEXTUREUSAGE_COLOR_TARGET | SDL_GPU_TEXTUREUSAGE_SAMPLER, - .width = Uint32(width), - .height = Uint32(height), - .layer_count_or_depth = 1, - .num_levels = 1, - .sample_count = SDL_GPU_SAMPLECOUNT_1, - .props = 0, - }; - targetTexture = SDL_CreateGPUTexture(device, &texture_desc); - assert(targetTexture); - - SDL_GPUSamplerCreateInfo sampler_desc{}; - sampler_desc.min_filter = SDL_GPU_FILTER_NEAREST; - sampler_desc.mag_filter = SDL_GPU_FILTER_NEAREST; - sampler_desc.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE; - sampler_desc.address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE; - sampler_desc.enable_compare = false; - sampler_desc.enable_anisotropy = false; - sampler_desc.props = 0; - depthSampler = SDL_CreateGPUSampler(device, &sampler_desc); - assert(depthSampler); - } - - struct alignas(16) ScreenSpaceShadowsUniform { - GpuMat4 projection; - GpuMat4 invProj; - GpuVec3 viewSpaceLightDir; - float maxDist; - int numSteps; - }; - - void ScreenSpaceShadowPass::release(SDL_GPUDevice *device) noexcept { - if (targetTexture) - SDL_ReleaseGPUTexture(device, targetTexture); - - if (pipeline) - SDL_ReleaseGPUGraphicsPipeline(device, pipeline); - - if (depthSampler) - SDL_ReleaseGPUSampler(device, depthSampler); - } - - void - ScreenSpaceShadowPass::render(CommandBuffer &cmdBuf, const Camera &camera, - const DirectionalLight &light, - std::span castables) { - SDL_GPUColorTargetInfo color_target_info; - SDL_zero(color_target_info); - color_target_info.texture = targetTexture; - color_target_info.clear_color = {0., 0., 0., 0.}; - color_target_info.load_op = SDL_GPU_LOADOP_CLEAR; - color_target_info.store_op = SDL_GPU_STOREOP_STORE; - color_target_info.cycle = false; - - SDL_GPURenderPass *render_pass = - SDL_BeginGPURenderPass(cmdBuf, &color_target_info, 1, nullptr); - SDL_BindGPUGraphicsPipeline(render_pass, pipeline); - - Mat4f invProj = camera.projection.inverse(); - Mat4f vp = camera.viewProj(); - ScreenSpaceShadowsUniform ubo{ - camera.projection, - invProj, - camera.transformVector(light.direction), - config.maxDist, - config.numSteps, - }; - cmdBuf.pushFragmentUniform(0, ubo); - rend::bindFragmentSamplers(render_pass, 0, - {{ - .texture = depthTexture, - .sampler = depthSampler, - }}); - - for (auto &cs : castables) { - auto &&[mesh, tr] = cs; - GpuMat4 mvp = vp * tr; - cmdBuf.pushVertexUniform(0, mvp); - rend::bindMesh(render_pass, mesh); - rend::draw(render_pass, mesh); - } - - SDL_DrawGPUPrimitives(render_pass, 6, 1, 0, 0); - - SDL_EndGPURenderPass(render_pass); - } - -} // namespace effects -} // namespace candlewick diff --git a/src/candlewick/posteffects/ScreenSpaceShadows.h b/src/candlewick/posteffects/ScreenSpaceShadows.h deleted file mode 100644 index 1965a246..00000000 --- a/src/candlewick/posteffects/ScreenSpaceShadows.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include "../core/Core.h" -#include "../core/Tags.h" -#include "../core/LightUniforms.h" -#include "../core/DepthAndShadowPass.h" - -#include - -namespace candlewick { -namespace effects { - - /// \brief WIP screen space shadows - struct ScreenSpaceShadowPass { - struct Config { - float maxDist = 1.0f; - int numSteps = 16; - } config; - SDL_GPUTexture *depthTexture = nullptr; - /// Sampler for the depth texture (e.g. from the prepass) - SDL_GPUSampler *depthSampler = nullptr; - /// Target texture to render the shadow to. - SDL_GPUTexture *targetTexture = nullptr; - /// Render pipeline - SDL_GPUGraphicsPipeline *pipeline = nullptr; - - bool valid() const { - return depthTexture && depthSampler && targetTexture && pipeline; - } - - ScreenSpaceShadowPass(NoInitT) {} - ScreenSpaceShadowPass(const RenderContext &renderer, const Config &config); - - void release(SDL_GPUDevice *device) noexcept; - - void render(CommandBuffer &cmdBuf, const Camera &camera, - const DirectionalLight &light, - std::span castables); - }; - -} // namespace effects -} // namespace candlewick From 6526733cebc717fa1deca8925ca2517aab4f20b0 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Thu, 26 Feb 2026 14:33:20 +0100 Subject: [PATCH 4/6] Remove old GLSL shaders --- shaders/src/old/BasicTriangle.vert | 20 ---- shaders/src/old/DrawQuad.vert | 23 ---- shaders/src/old/FrustumDebug.vert | 69 ------------ shaders/src/old/Hud3dElement.frag | 11 -- shaders/src/old/Hud3dElement.vert | 11 -- shaders/src/old/PbrBasic.frag | 144 ------------------------ shaders/src/old/PbrBasic.vert | 42 ------- shaders/src/old/PbrTransparent.frag | 76 ------------- shaders/src/old/PointSprite.frag | 13 --- shaders/src/old/PointSprite.vert | 21 ---- shaders/src/old/RenderDepth.frag | 79 ------------- shaders/src/old/SSAO.frag | 83 -------------- shaders/src/old/SSAOblur.frag | 27 ----- shaders/src/old/ScreenSpaceShadows.frag | 90 --------------- shaders/src/old/ShadowCast.frag | 5 - shaders/src/old/ShadowCast.vert | 15 --- shaders/src/old/SolidColor.frag | 8 -- shaders/src/old/VertexColor.frag | 11 -- shaders/src/old/VertexColor.vert | 20 ---- shaders/src/old/VertexNormal.frag | 11 -- shaders/src/old/VertexNormal.vert | 21 ---- shaders/src/old/WBOITComposite.frag | 20 ---- shaders/src/old/config.glsl | 1 - shaders/src/old/pbr_lighting.glsl | 92 --------------- shaders/src/old/tone_mapping.glsl | 53 --------- shaders/src/old/utils.glsl | 30 ----- 26 files changed, 996 deletions(-) delete mode 100644 shaders/src/old/BasicTriangle.vert delete mode 100644 shaders/src/old/DrawQuad.vert delete mode 100644 shaders/src/old/FrustumDebug.vert delete mode 100644 shaders/src/old/Hud3dElement.frag delete mode 100644 shaders/src/old/Hud3dElement.vert delete mode 100644 shaders/src/old/PbrBasic.frag delete mode 100644 shaders/src/old/PbrBasic.vert delete mode 100644 shaders/src/old/PbrTransparent.frag delete mode 100644 shaders/src/old/PointSprite.frag delete mode 100644 shaders/src/old/PointSprite.vert delete mode 100644 shaders/src/old/RenderDepth.frag delete mode 100644 shaders/src/old/SSAO.frag delete mode 100644 shaders/src/old/SSAOblur.frag delete mode 100644 shaders/src/old/ScreenSpaceShadows.frag delete mode 100644 shaders/src/old/ShadowCast.frag delete mode 100644 shaders/src/old/ShadowCast.vert delete mode 100644 shaders/src/old/SolidColor.frag delete mode 100644 shaders/src/old/VertexColor.frag delete mode 100644 shaders/src/old/VertexColor.vert delete mode 100644 shaders/src/old/VertexNormal.frag delete mode 100644 shaders/src/old/VertexNormal.vert delete mode 100644 shaders/src/old/WBOITComposite.frag delete mode 100644 shaders/src/old/config.glsl delete mode 100644 shaders/src/old/pbr_lighting.glsl delete mode 100644 shaders/src/old/tone_mapping.glsl delete mode 100644 shaders/src/old/utils.glsl diff --git a/shaders/src/old/BasicTriangle.vert b/shaders/src/old/BasicTriangle.vert deleted file mode 100644 index ece76cea..00000000 --- a/shaders/src/old/BasicTriangle.vert +++ /dev/null @@ -1,20 +0,0 @@ -#version 450 - -layout (location = 0) out vec4 outColor; - -void main() { - vec2 pos; - - if (gl_VertexIndex == 0) { - pos = vec2(-1, -1); - outColor = vec4(1, 0, 0, 1); - } else if (gl_VertexIndex == 1) { - pos = vec2(1, -1); - outColor = vec4(0, 1, 0, 1); - } else if (gl_VertexIndex == 2) { - pos = vec2(0, 1); - outColor = vec4(0, 0, 1, 1); - } - - gl_Position = vec4(pos, 0, 1); -} diff --git a/shaders/src/old/DrawQuad.vert b/shaders/src/old/DrawQuad.vert deleted file mode 100644 index 26e5fb26..00000000 --- a/shaders/src/old/DrawQuad.vert +++ /dev/null @@ -1,23 +0,0 @@ -// Vertex shader to render a quad on screen. -// Outputs the corresponding UV coordinates, -// which get interpolated in the fragment shader. -#version 450 - -const vec2 positions[6] = vec2[]( - vec2(-1.0, -1.0), - vec2( 1.0, -1.0), - vec2( 1.0, 1.0), - vec2(-1.0, -1.0), - vec2( 1.0, 1.0), - vec2(-1.0, 1.0) -); - -layout(location = 0) out vec2 outUV; - -void main() { - vec2 pos = positions[gl_VertexIndex]; - gl_Position = vec4(pos, 0.0, 1.0); - // Convert to UV coordinates - outUV.x = pos.x * 0.5 + 0.5; - outUV.y = 0.5 - pos.y * 0.5; -} diff --git a/shaders/src/old/FrustumDebug.vert b/shaders/src/old/FrustumDebug.vert deleted file mode 100644 index 536e8448..00000000 --- a/shaders/src/old/FrustumDebug.vert +++ /dev/null @@ -1,69 +0,0 @@ -#version 450 - -layout(set=1, binding=0) uniform DebugTransform { - mat4 invProj; - mat4 mvp; - vec4 color; - vec3 eyePos; -}; - -layout(location=0) out vec4 outColor; - -// Line indices for frustum edges -const uint[24] LINE_INDICES = uint[]( - // bottom face - 0, 1, // x-edge - 0, 2, // y-edge - 2, 3, // x-edge - 1, 3, // y-edge - // top face - 4, 5, // x-edge - 4, 6, // y-edge - 6, 7, // x-edge - 5, 7, // y-edge - // vertical edges - 0, 4, // z-edge - 1, 5, // z-edge - 2, 6, // z-edge - 3, 7 // z-edge -); - -vec4 getNDCCorner(uint idx) { - return vec4( - 2.0 * float(idx & 1) - 1.0, - 2.0 * float((idx >> 1) & 1) - 1.0, - 2.0 * float((idx >> 2) & 1) - 1.0, - 1.0 - ); -} - -void main() { - if (gl_VertexIndex < 24) { - uint cornerIdx = LINE_INDICES[gl_VertexIndex]; - vec4 ndc = getNDCCorner(cornerIdx); - vec4 viewPos = invProj * ndc; - viewPos /= viewPos.w; - gl_Position = mvp * viewPos; - } else if (gl_VertexIndex < 30) { - uint axisIdx = (gl_VertexIndex - 24) / 2; - uint pointIdx = gl_VertexIndex & 1; - float size = 0.1; - vec3 offset = vec3(0.0); - offset[axisIdx] = pointIdx == 0 ? -size : size; - gl_Position = mvp * vec4(eyePos + offset, 1.0); - } else { - // Z=0 intersection quad - uint lineIdx = (gl_VertexIndex - 30) / 2; - uint pointIdx = gl_VertexIndex & 1; - - uint edgeNum = (lineIdx + pointIdx) % 4; - uint near = edgeNum; - uint far = near + 4; - vec4 center = mix(getNDCCorner(near), getNDCCorner(far), 0.5); - - vec4 viewPos = invProj * center; - viewPos /= viewPos.w; - gl_Position = mvp * viewPos; - } - outColor = color; -} diff --git a/shaders/src/old/Hud3dElement.frag b/shaders/src/old/Hud3dElement.frag deleted file mode 100644 index e87f45b0..00000000 --- a/shaders/src/old/Hud3dElement.frag +++ /dev/null @@ -1,11 +0,0 @@ -#version 450 - -layout(location=0) out vec4 fragColor; - -layout(set=3, binding=0) uniform Color { - vec4 color; -}; - -void main() { - fragColor = color; -} diff --git a/shaders/src/old/Hud3dElement.vert b/shaders/src/old/Hud3dElement.vert deleted file mode 100644 index e44ef458..00000000 --- a/shaders/src/old/Hud3dElement.vert +++ /dev/null @@ -1,11 +0,0 @@ -#version 450 - -layout(location=0) in vec3 inPosition; - -layout(set=1, binding=0) uniform TranformBlock { - mat4 mvp; -}; - -void main() { - gl_Position = mvp * vec4(inPosition, 1.0); -} diff --git a/shaders/src/old/PbrBasic.frag b/shaders/src/old/PbrBasic.frag deleted file mode 100644 index 4b918a86..00000000 --- a/shaders/src/old/PbrBasic.frag +++ /dev/null @@ -1,144 +0,0 @@ -#version 450 -#define HAS_SHADOW_MAPS -#define HAS_G_BUFFER -#define HAS_SSAO - -#include "utils.glsl" -#include "tone_mapping.glsl" -#include "pbr_lighting.glsl" -#include "config.glsl" - -layout(location=0) in vec3 fragViewPos; -layout(location=1) in vec3 fragViewNormal; -layout(location=2) in vec3 fragLightPos[MAX_NUM_LIGHTS]; - -// set=3 is required, see SDL3's documentation for SDL_CreateGPUShader -// https://wiki.libsdl.org/SDL3/SDL_CreateGPUShader -layout (set=3, binding=0) uniform Material { - // material diffuse color - PbrMaterial material; -}; - -layout(set=3, binding=1) uniform LightBlock { - vec3 direction[MAX_NUM_LIGHTS]; - vec3 color[MAX_NUM_LIGHTS]; - float intensity[MAX_NUM_LIGHTS]; - int numLights; -} light; - -layout(set=3, binding=2) uniform EffectParams { - uint useSsao; -} params; - -layout(set = 3, binding = 3) uniform ShadowAtlasInfo { - ivec4 lightRegions[MAX_NUM_LIGHTS]; -}; - -#ifdef HAS_SHADOW_MAPS - layout (set=2, binding=0) uniform sampler2DShadow shadowMap; -#endif -#ifdef HAS_SSAO - layout (set=2, binding=1) uniform sampler2D ssaoTex; -#endif - -layout(location=0) out vec4 fragColor; -#ifdef HAS_G_BUFFER - // output normals for post-effects - layout(location=1) out vec2 outNormal; - // output NDC depth for post-effects (avoids sampling MSAA depth texture) - layout(location=2) out float outDepth; -#endif - -#ifdef HAS_SHADOW_MAPS -float calcShadowmap(int lightIndex, float NdotL, ivec2 atlasSize) { - // float bias = max(0.05 * (1.0 - NdotL), 0.005); - float bias = 0.005; - vec3 lightSpacePos = fragLightPos[lightIndex]; - vec2 uv; - uv.x = 0.5 + lightSpacePos.x * 0.5; - uv.y = 0.5 - lightSpacePos.y * 0.5; - float depthRef = lightSpacePos.z - bias; - if (!isCoordsInRange(vec3(uv, depthRef))) { - return 1.0; - } - - ivec4 region = lightRegions[lightIndex]; - uv = region.xy + uv * region.zw; - uv = uv / atlasSize; - vec2 regionMin = vec2(region.xy) / atlasSize; - vec2 regionMax = vec2(region.xy + region.zw) / atlasSize; - - float value = 0.0; - const vec2 offsets = 1.0 / atlasSize; - // pcf loop - const int halfKernel = 1; - const float weight = 1.0 / pow(2 * halfKernel + 1, 2); - for (int i = -halfKernel; i <= halfKernel; i++) { - for (int j = -halfKernel; j <= halfKernel; j++) { - vec2 offUV = uv + vec2(i, j) * offsets; - offUV = clamp(offUV, regionMin, regionMax); - vec3 texCoords = vec3(offUV, depthRef); - value += weight * texture(shadowMap, texCoords); - } - } - - return value; -} -#endif - -void main() { - vec3 normal = normalize(fragViewNormal); - const vec3 V = normalize(-fragViewPos); -#ifdef HAS_SHADOW_MAPS - const ivec2 atlasSize = textureSize(shadowMap, 0).xy; -#endif - - if (!gl_FrontFacing) { - // Flip normal for back faces - normal = -normal; - } - - vec3 Lo = vec3(0); - for(int i = 0; i < light.numLights; i++) { - vec3 lightDir = normalize(-light.direction[i]); - vec3 _lo = calculatePbrLighting( - normal, - V, - lightDir, - material, - light.color[i], - light.intensity[i] - ); -#ifdef HAS_SHADOW_MAPS - const float NdotL = max(dot(normal, lightDir), 0.0); - const float shadowValue = calcShadowmap(i, NdotL, atlasSize); - _lo *= shadowValue; -#endif - Lo += _lo; - } - - // Ambient term (very simple) - vec3 ambient = vec3(0.1) * material.baseColor.rgb * material.ao; - -#ifdef HAS_SSAO - if(params.useSsao == 1) { - vec2 ssaoTexSize = textureSize(ssaoTex, 0).xy; - vec2 ssaoUV = gl_FragCoord.xy / ssaoTexSize; - ambient *= texture(ssaoTex, ssaoUV).r; - } -#endif - - // Final color - vec3 color = ambient + Lo; - - // Tone mapping and gamma correction - color = uncharted2ToneMapping(color); - color = pow(color, vec3(1.0/2.2)); - - // Output - fragColor = vec4(color, material.baseColor.a); -#ifdef HAS_G_BUFFER - outNormal = fragViewNormal.rg; - outDepth = gl_FragCoord.z; -#endif -} diff --git a/shaders/src/old/PbrBasic.vert b/shaders/src/old/PbrBasic.vert deleted file mode 100644 index c03137a1..00000000 --- a/shaders/src/old/PbrBasic.vert +++ /dev/null @@ -1,42 +0,0 @@ -#version 450 - -#include "config.glsl" - -layout(location=0) in vec3 inPosition; -layout(location=1) in vec3 inNormal; - -// world-space position-normal -layout(location=0) out vec3 fragViewPos; -layout(location=1) out vec3 fragViewNormal; -layout(location=2) out vec3 fragLightPos[MAX_NUM_LIGHTS]; - - -// set=1 is required, for some reason -layout(set=1, binding=0) uniform TranformBlock -{ - mat4 modelView; - mat4 mvp; - mat3 normalMatrix; -}; - -layout(set=1, binding=1) uniform LightBlockV -{ - mat4 mvp[MAX_NUM_LIGHTS]; - int numLights; -} lights; - -out gl_PerVertex { - invariant vec4 gl_Position; -}; - -void main() { - vec4 hp = vec4(inPosition, 1.0); - fragViewPos = vec3(modelView * hp); - fragViewNormal = normalize(normalMatrix * inNormal); - gl_Position = mvp * hp; - - for (uint i = 0; i < lights.numLights; i++) { - vec4 flps = lights.mvp[i] * hp; - fragLightPos[i] = flps.xyz / flps.w; - } -} diff --git a/shaders/src/old/PbrTransparent.frag b/shaders/src/old/PbrTransparent.frag deleted file mode 100644 index 7da0c262..00000000 --- a/shaders/src/old/PbrTransparent.frag +++ /dev/null @@ -1,76 +0,0 @@ -#version 450 -#define HAS_WBOIT -#define HAS_SHADOW_MAPS -#define HAS_SSAO - -#include "tone_mapping.glsl" -#include "pbr_lighting.glsl" -#include "config.glsl" - -layout(location=0) in vec3 fragViewPos; -layout(location=1) in vec3 fragViewNormal; -layout(location=2) in vec3 fragLightPos; - -// layout declarations with two outputs -layout(location = 0) out vec4 accum; // R16G16B16A16 accumulation -layout(location = 1) out float reveal; // R8 revealage - -layout (set=3, binding=0) uniform Material { - // material diffuse color - PbrMaterial material; -}; - -layout(set=3, binding=1) uniform LightBlock { - vec3 direction[MAX_NUM_LIGHTS]; - vec3 color[MAX_NUM_LIGHTS]; - float intensity[MAX_NUM_LIGHTS]; - int numLights; -} light; - -layout(set=3, binding=2) uniform EffectParams { - uint useSsao; -} params; - -#ifdef HAS_SHADOW_MAPS - layout (set=2, binding=0) uniform sampler2DShadow shadowMap; -#endif -#ifdef HAS_SSAO - layout (set=2, binding=1) uniform sampler2D ssaoTex; -#endif - - -void main() { - vec3 normal = normalize(fragViewNormal); - vec3 V = normalize(-fragViewPos); - - vec3 Lo = vec3(0.); - for (uint i = 0; i < light.numLights; i++) { - vec3 lightDir = normalize(-light.direction[i]); - Lo += calculatePbrLighting( - normal, - V, - lightDir, - material, - light.color[i], - light.intensity[i] - ); - } - - vec3 ambient = vec3(0.03) * material.baseColor.rgb * material.ao; - vec3 color = ambient + Lo; - - // Tone mapping and gamma correction - color = uncharted2ToneMapping(color); - color = pow(color, vec3(1.0/2.2)); - - // WBOIT specific calculations - float alpha = material.baseColor.a; - - const float z = gl_FragCoord.z; - float w1 = alpha * 10. + 0.01; - float weight = clamp(w1 * (1.0 - z * 0.3), 1e-2, 1e3); - - // Outputs for WBOIT - accum = vec4(color * alpha * weight, alpha); - reveal = 1. - alpha * weight; -} diff --git a/shaders/src/old/PointSprite.frag b/shaders/src/old/PointSprite.frag deleted file mode 100644 index 591ee131..00000000 --- a/shaders/src/old/PointSprite.frag +++ /dev/null @@ -1,13 +0,0 @@ -#version 450 - -layout(location=0) in vec4 pointColor; -layout(location=0) out vec4 fragColor; - -void main() { - // Can use gl_PointCoord for texture/circular shape - // Can discard fragments to make round points - if (length(gl_PointCoord - 0.5) > 0.5) { - discard; - } - fragColor = pointColor; -} diff --git a/shaders/src/old/PointSprite.vert b/shaders/src/old/PointSprite.vert deleted file mode 100644 index 92d49772..00000000 --- a/shaders/src/old/PointSprite.vert +++ /dev/null @@ -1,21 +0,0 @@ -#version 450 - -#include "tone_mapping.glsl" - -layout(location=0) in vec3 position; -layout(location=4) in vec4 color; - -layout(set=1, binding=0) uniform TranformBlock -{ - mat4 model; - mat4 viewProj; -} transform; - -layout(location=0) out vec4 pointColor; - -void main() { - gl_Position = transform.viewProj * transform.model * vec4(position, 1.0); - gl_PointSize = 5.0; // Fixed size or distance-based - pointColor.rgb = uncharted2ToneMapping(color.rgb); - pointColor.w = 1.0; -} diff --git a/shaders/src/old/RenderDepth.frag b/shaders/src/old/RenderDepth.frag deleted file mode 100644 index 0d4f7b98..00000000 --- a/shaders/src/old/RenderDepth.frag +++ /dev/null @@ -1,79 +0,0 @@ -// To be used with DrawQuad.vert -#version 450 - -#include "utils.glsl" - -#define VIZ_GRAYSCALE 0 -#define VIZ_HEATMAP 1 - -layout(location = 0) in vec2 inUV; -layout(location = 0) out vec4 outColor; - -layout (set=2, binding=0) uniform sampler2D depthTex; - -layout (set=3, binding=0) uniform CameraParams { - int mode; - float near; - float far; - uint isOrtho; // 0 for perspective, 1 for ortho -}; - -vec3 visualizeDepthGrayscale(float depth) { - float lin; - if (isOrtho == 1) { - lin = linearizeDepthOrtho(depth, near, far); - } else { - lin = linearizeDepth(depth, near, far); - } - float norm = (lin - near) / (far - near); - return vec3(norm); -} - -vec3 visualizeDepthHeatmap(float depth) { - float lin; - if (isOrtho == 1) { - lin = linearizeDepthOrtho(depth, near, far); - } else { - lin = linearizeDepth(depth, near, far); - } - // Normalize to 0-1 range based on near/far planes - float normalized = (lin - near) / (far - near); - - // Convert to heatmap colors: - // Blue (cold) -> Cyan -> Green -> Yellow -> Red (hot) - vec3 color; - if(normalized < 0.25) { - // Blue to Cyan - float t = normalized / 0.25; - color = mix(vec3(0,0,1), vec3(0,1,1), t); - } else if(normalized < 0.5) { - // Cyan to Green - float t = (normalized - 0.25) / 0.25; - color = mix(vec3(0,1,1), vec3(0,1,0), t); - } else if(normalized < 0.75) { - // Green to Yellow - float t = (normalized - 0.5) / 0.25; - color = mix(vec3(0,1,0), vec3(1,1,0), t); - } else { - // Yellow to Red - float t = (normalized - 0.75) / 0.25; - color = mix(vec3(1,1,0), vec3(1,0,0), t); - } - return color; -} - -void main() { - float depth = texture(depthTex, inUV).r; - - vec3 color; - switch (mode) { - case VIZ_GRAYSCALE: - color = visualizeDepthGrayscale(depth); - break; - case VIZ_HEATMAP: - color = visualizeDepthHeatmap(depth); - break; - } - outColor.rgb = color; - outColor.w = 1.0; -} diff --git a/shaders/src/old/SSAO.frag b/shaders/src/old/SSAO.frag deleted file mode 100644 index 2c80c8c4..00000000 --- a/shaders/src/old/SSAO.frag +++ /dev/null @@ -1,83 +0,0 @@ -#version 450 - - -layout(location=0) in vec2 inUV; -layout(location=0) out float aoValue; - -layout(set=2, binding=0) uniform sampler2D depthTex; -layout(set=2, binding=1) uniform sampler2D normalMap; -layout(set=2, binding=2) uniform sampler2D ssaoNoise; - -// Maximum number of kernel samples; actual count is camera.kernelSize. -const int SSAO_MAX_KERNEL_SIZE = 64; -const float SSAO_RADIUS = 1.0; -const float SSAO_BIAS = 0.01; -const float SSAO_INTENSITY = 1.5; - -layout(set=3, binding=0) uniform SSAOParams { - vec4 samples[SSAO_MAX_KERNEL_SIZE]; -} kernel; - -layout(set=3, binding=1) uniform Camera { - mat4 projection; - mat4 projectionInverse; - uint kernelSize; -} camera; - -vec3 getViewPos(float depth, vec2 uv) { - vec4 clipPos = vec4(uv * 2.0 - 1.0, depth, 1.0); - vec4 viewPos = camera.projectionInverse * clipPos; - return viewPos.xyz / viewPos.w; -} - -vec3 sampleNoiseTexture(vec2 uv) { - vec2 viewport = textureSize(depthTex, 0).xy; - vec2 noiseScale = viewport / 4.0; - uv = uv * noiseScale; - return vec3(texture(ssaoNoise, uv).rg, 0); -} - -float calculatePixelAO(vec2 uv) { - float depth = texture(depthTex, uv).r; - vec3 viewPos = getViewPos(depth, uv); - vec3 viewNormal; - viewNormal.xy = texture(normalMap, uv).xy; - viewNormal.z = sqrt(1 - dot(viewNormal.xy, viewNormal.xy)); - - vec3 randVec = sampleNoiseTexture(uv); - - // tbn matrix for rotating samples - vec3 tangent = normalize(randVec - viewNormal * dot(randVec, viewNormal)); - vec3 bitangent = cross(tangent, viewNormal); - mat3 TBN = mat3(tangent, bitangent, viewNormal); - - // accumulate occlusion - float occlusion = 0.0; - for(int i = 0; i < int(camera.kernelSize); i++) { - // get sample position - vec3 samplePos = TBN * kernel.samples[i].xyz; // Rotate sample vector - samplePos = viewPos + samplePos * SSAO_RADIUS; // Move it to view-space position - - // project sample to get its screen-space coordinates - vec4 offset = camera.projection * vec4(samplePos, 1.0); - offset.xy /= offset.w; // Perspective divide - offset.xy = offset.xy * 0.5 + 0.5; // Transform to [0,1] range - - // get sample depth - float sampleDepth = texture(depthTex, offset.xy).r; - - // convert sample's depth to view space for comparison - vec3 sampleViewPos = getViewPos(sampleDepth, offset.xy); - - // Rarnge check & accumulate - float rangeCheck = smoothstep(0.0, 1.0, SSAO_RADIUS / abs(viewPos.z - sampleViewPos.z - SSAO_BIAS)); - occlusion += (sampleViewPos.z >= samplePos.z + SSAO_BIAS ? 1.0 : 0.0) * rangeCheck; - } - - occlusion = 1.0 - (occlusion / float(camera.kernelSize)) * SSAO_INTENSITY; - return occlusion; -} - -void main() { - aoValue = calculatePixelAO(inUV); -} diff --git a/shaders/src/old/SSAOblur.frag b/shaders/src/old/SSAOblur.frag deleted file mode 100644 index 66313e71..00000000 --- a/shaders/src/old/SSAOblur.frag +++ /dev/null @@ -1,27 +0,0 @@ -#version 450 - -layout(location=0) in vec2 inUV; -layout(location=0) out float aoValue; - -layout(set=2, binding=0) uniform sampler2D aoTex; - - -const float weights[5] = float[](0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216); -const int KERNEL_RADIUS = 4; - -layout(set=3, binding=0) uniform BlurParams -{ - vec2 direction; -}; - -void main() { - vec2 texelSize = 1.0 / vec2(textureSize(aoTex, 0)); - float result = texture(aoTex, inUV).r * weights[0]; - - for(int i = 1; i <= KERNEL_RADIUS; i++) { - vec2 off = direction * texelSize * i; - result += texture(aoTex, inUV + off).r * weights[i]; - result += texture(aoTex, inUV - off).r * weights[i]; - } - aoValue = result; -} diff --git a/shaders/src/old/ScreenSpaceShadows.frag b/shaders/src/old/ScreenSpaceShadows.frag deleted file mode 100644 index d698bc8d..00000000 --- a/shaders/src/old/ScreenSpaceShadows.frag +++ /dev/null @@ -1,90 +0,0 @@ -#version 450 - -#include "utils.glsl" - -layout(location = 0) in vec2 fragUV; -layout(location = 0) out float fragShadow; - -// Depth texture from pre-pass -layout(set=2, binding=0) uniform sampler2D depthTexture; - -// Parameters for the effect -layout(set=3, binding=0) uniform ShadowParams { - // Camera projection matrix - mat4 projection; - // Inverse projection matrix - mat4 invProjection; - // View-space light direction - vec3 lightDir; - // Maximum ray march distance - float maxDistance; - // Maximum number of steps - int numSteps; -}; - -// reconstruct view-space position from depth -vec3 computeViewPos(vec3 ndcPos) { - vec4 viewPos = invProjection * vec4(ndcPos, 1.0); - return viewPos.xyz / viewPos.w; -} - -const float SSS_THICKNESS = 0.02; -const float SSS_MAX_RAY_DISTANCE = 0.05; - -void main() { - // Sample depth - float depth = texture(depthTexture, fragUV).r; - - if (depth >= 1.0) { - fragShadow = 1.0; - return; - } - - // reconstruct view-space position - const vec3 ndcPos = vec3(fragUV * 2. - 1., depth); - const vec3 viewPos = computeViewPos(ndcPos); - - // initial ray position - vec3 rayPos = viewPos; - - const float stepSize = SSS_MAX_RAY_DISTANCE / float(numSteps); - vec3 toLight = normalize(-lightDir); - vec3 rayStep = toLight * stepSize; - - float depthDelta; - float occlusion = 0.0; - - // march a ray from the fragment towards the light - for (int i = 0; i < numSteps; i++) { - // advance ray - rayPos += rayStep; - - // project current ray position to screen space - vec4 projectedPos = projection * vec4(rayPos, 1.0); - vec3 screenPos = projectedPos.xyz / projectedPos.w; - - // convert to UV coordinates - vec2 rayUV = 0.5 + screenPos.xy * 0.5; - - // depth at the ray depth - float rayDepth = screenPos.z; - float sceneDepth = texture(depthTexture, rayUV).r; - - - if(!isCoordsInRange(rayUV)) { - break; - } - - depthDelta = rayDepth - sceneDepth - 0.001; - - // compare depths: if the current depth is closer than the ray, - // then fragment is occluded. - if ((depthDelta >= 0.0) && (depthDelta < SSS_THICKNESS)) { - occlusion = 1.0; - break; - } - } - - // No shadow found - fragShadow = 1.0 - occlusion; -} diff --git a/shaders/src/old/ShadowCast.frag b/shaders/src/old/ShadowCast.frag deleted file mode 100644 index debf1cfd..00000000 --- a/shaders/src/old/ShadowCast.frag +++ /dev/null @@ -1,5 +0,0 @@ -#version 450 - -void main() { - gl_FragDepth = gl_FragCoord.z; -} diff --git a/shaders/src/old/ShadowCast.vert b/shaders/src/old/ShadowCast.vert deleted file mode 100644 index 0d47165d..00000000 --- a/shaders/src/old/ShadowCast.vert +++ /dev/null @@ -1,15 +0,0 @@ -#version 450 - -layout(location=0) in vec3 inPosition; - -layout(set=1, binding=0) uniform CameraBlock { - mat4 mvp; -}; - -out gl_PerVertex { - invariant vec4 gl_Position; -}; - -void main() { - gl_Position = mvp * vec4(inPosition, 1.0); -} diff --git a/shaders/src/old/SolidColor.frag b/shaders/src/old/SolidColor.frag deleted file mode 100644 index fbc8960e..00000000 --- a/shaders/src/old/SolidColor.frag +++ /dev/null @@ -1,8 +0,0 @@ -#version 450 - -layout (location = 0) in vec4 Color; -layout (location = 0) out vec4 FragColor; - -void main() { - FragColor = Color; -} diff --git a/shaders/src/old/VertexColor.frag b/shaders/src/old/VertexColor.frag deleted file mode 100644 index 4b980dff..00000000 --- a/shaders/src/old/VertexColor.frag +++ /dev/null @@ -1,11 +0,0 @@ -#version 450 - -layout(location=0) in vec4 interpColor; - -layout(location=0) out vec4 FragColor; - -void main() { - - FragColor = interpColor; - -} diff --git a/shaders/src/old/VertexColor.vert b/shaders/src/old/VertexColor.vert deleted file mode 100644 index d4485e6d..00000000 --- a/shaders/src/old/VertexColor.vert +++ /dev/null @@ -1,20 +0,0 @@ -#version 450 - -layout(location=0) in vec3 position; -layout(location=4) in vec4 color; - -layout(location=0) out vec4 interpColor; - -// set=1 is required, for some god forsaken reason -// i am not that smart -layout(set=1, binding=0) uniform UniformBlock -{ - mat4 viewProj; -}; - -void main() { - - gl_Position = viewProj * vec4(position, 1.0); - - interpColor = color; -} diff --git a/shaders/src/old/VertexNormal.frag b/shaders/src/old/VertexNormal.frag deleted file mode 100644 index 389bfc33..00000000 --- a/shaders/src/old/VertexNormal.frag +++ /dev/null @@ -1,11 +0,0 @@ -#version 450 - -layout(location=0) in vec3 f_normal; - -layout(location=0) out vec4 FragColor; - -void main() { - - FragColor.xyz = f_normal; - -} diff --git a/shaders/src/old/VertexNormal.vert b/shaders/src/old/VertexNormal.vert deleted file mode 100644 index b87b7cc2..00000000 --- a/shaders/src/old/VertexNormal.vert +++ /dev/null @@ -1,21 +0,0 @@ -#version 450 - -layout(location=0) in vec3 position; -layout(location=1) in vec3 normal; - -layout(location=0) out vec3 f_normal; - -// set=1 is required, see the documentation on SDL3's shader layout -// https://wiki.libsdl.org/SDL3/SDL_CreateGPUShader -layout(set=1, binding=0) uniform TranformBlock -{ - mat4 mvp; - mat3 normalMatrix; -}; - -void main() { - - f_normal = normalize(normalMatrix * normal); - gl_Position = mvp * vec4(position, 1.0); - -} diff --git a/shaders/src/old/WBOITComposite.frag b/shaders/src/old/WBOITComposite.frag deleted file mode 100644 index c841e5e1..00000000 --- a/shaders/src/old/WBOITComposite.frag +++ /dev/null @@ -1,20 +0,0 @@ -#version 450 -layout(set=2, binding=0) uniform sampler2DMS accumTexture; -layout(set=2, binding=1) uniform sampler2DMS revealTexture; - -layout(location = 0) out vec4 outColor; - -void main() { - ivec2 uv = ivec2(gl_FragCoord.xy); - - vec4 accum = texelFetch(accumTexture, uv, gl_SampleID); - float reveal = texelFetch(revealTexture, uv, gl_SampleID).r; - - vec3 color = accum.rgb; - if (accum.a > 0.001) { - color = accum.rgb / accum.a; - } - - // Output final color - outColor = vec4(color, reveal); -} diff --git a/shaders/src/old/config.glsl b/shaders/src/old/config.glsl deleted file mode 100644 index b316f04c..00000000 --- a/shaders/src/old/config.glsl +++ /dev/null @@ -1 +0,0 @@ -#define MAX_NUM_LIGHTS 4 diff --git a/shaders/src/old/pbr_lighting.glsl b/shaders/src/old/pbr_lighting.glsl deleted file mode 100644 index 97cb91fc..00000000 --- a/shaders/src/old/pbr_lighting.glsl +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef _PBR_LIGHTING_GLSL_ -#define _PBR_LIGHTING_GLSL_ - -struct PbrMaterial { - vec4 baseColor; - float metalness; - float roughness; - float ao; -}; - -// Constants -const float PI = 3.14159265359; -const float F0 = 0.04; // Standard base reflectivity - -// Schlick's Fresnel approximation -vec3 fresnelSchlick(float cosTheta, vec3 F0) { - return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0); -} - -// Normal Distribution Function (GGX/Trowbridge-Reitz) -float distributionGGX(vec3 normal, vec3 H, float roughness) { - float a = roughness * roughness; - float a2 = a * a; - float NdotH = max(dot(normal, H), 0.0); - float NdotH2 = NdotH * NdotH; - - float denom = (NdotH2 * (a2 - 1.0) + 1.0); - denom = PI * denom * denom; - - return a2 / denom; -} - -// Geometry function (Smith's method with Schlick-GGX) -float geometrySchlickGGX(float NdotV, float roughness) { - float r = (roughness + 1.0); - float k = (r * r) / 8.0; - - float num = NdotV; - float denom = NdotV * (1.0 - k) + k; - - return num / denom; -} - -float geometrySmith(vec3 normal, vec3 V, vec3 L, float roughness) { - float NdotV = max(dot(normal, V), 0.0); - float NdotL = max(dot(normal, L), 0.0); - float ggx2 = geometrySchlickGGX(NdotV, roughness); - float ggx1 = geometrySchlickGGX(NdotL, roughness); - - return ggx1 * ggx2; -} - -// Core PBR calculation - returns direct lighting only -// (no ambient, no shadows, no SSAO - those are applied outside) -vec3 calculatePbrLighting( - vec3 normal, - vec3 V, - vec3 lightDir, - PbrMaterial material, - vec3 lightColor, - float lightIntensity -) { - vec3 H = normalize(lightDir + V); - - // Base reflectivity - vec3 specColor = mix(F0.rrr, material.baseColor.rgb, material.metalness); - - // Cook-Torrance BRDF - float NDF = distributionGGX(normal, H, material.roughness); - float G = geometrySmith(normal, V, lightDir, material.roughness); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), specColor); - - // Specular and diffuse components - float denominator = 4.0 * max(dot(normal, V), dot(normal, lightDir)) + 0.0001; - vec3 specular = NDF * G * F / denominator; - - // Energy conservation: diffuse and specular - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - - // Only non-metallic surfaces have diffuse lighting - kD *= 1.0 - material.metalness; - - // Combine lighting (no attenuation for directional light) - float NdotL = max(dot(normal, lightDir), 0.0); - const vec3 lightCol = lightIntensity * lightColor; - - // Return direct lighting contribution - return (kD * material.baseColor.rgb / PI + specular) * lightCol * NdotL; -} - -#endif // _PBR_LIGHTING_GLSL_ diff --git a/shaders/src/old/tone_mapping.glsl b/shaders/src/old/tone_mapping.glsl deleted file mode 100644 index d3a3e913..00000000 --- a/shaders/src/old/tone_mapping.glsl +++ /dev/null @@ -1,53 +0,0 @@ -// See https://64.github.io/tonemapping/ - -// Reinhard Tone Mapping -vec3 reinhardToneMapping(vec3 color) { - return color / (color + vec3(1.0)); -} - -vec3 exposureToneMapping(vec3 color, float exposure) { - // Exposure adjustment - return 1.0 - exp(-color * exposure); -} - -// ACES Filmic Tone Mapping (Academy Color Encoding System) -vec3 acesFastToneMapping(vec3 color) { - float a = 2.51f; - float b = 0.03f; - float c = 2.43f; - float d = 0.59f; - float e = 0.14f; - - return clamp( - (color * (a * color + vec3(b))) / - (color * (c * color + vec3(d)) + vec3(e)), - vec3(0.0), - vec3(1.0) - ); -} - -// Uncharted 2 Tone Mapping (John Hable) -vec3 uncharted2ToneMapping_Partial(vec3 color) { - float A = 0.15f; // Shoulder strength - float B = 0.50f; // Linear strength - float C = 0.10f; // Linear angle - float D = 0.20f; // Toe strength - float E = 0.02f; // Toe numerator - float F = 0.30f; // Toe denominator - - return (color * (A * color + C * B) + D * E) / - (color * (A * color + B) + D * F) - vec3(E / F); -} - -vec3 uncharted2ToneMapping(vec3 color) { - float exposure_bias = 2.0; - vec3 curr = uncharted2ToneMapping_Partial(exposure_bias * color); - - vec3 W = vec3(11.2f); // White point - vec3 white_scale = vec3(1.0) / uncharted2ToneMapping_Partial(W); - return curr * white_scale; -} - -vec3 saturate(vec3 color) { - return clamp(color, vec3(0.0), vec3(1.0)); -} diff --git a/shaders/src/old/utils.glsl b/shaders/src/old/utils.glsl deleted file mode 100644 index e4e9aaf4..00000000 --- a/shaders/src/old/utils.glsl +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _UTILS_GLSL_ -#define _UTILS_GLSL_ - - -bool isCoordsInRange(vec3 uv) { - return uv.x >= 0.0 && - uv.y >= 0.0 && - uv.x <= 1.0 && - uv.y <= 1.0 && - uv.z >= 0.0 && - uv.z <= 1.0; -} - -bool isCoordsInRange(vec2 uv) { - return uv.x >= 0.0 && - uv.y >= 0.0 && - uv.x <= 1.0 && - uv.y <= 1.0; -} - -float linearizeDepth(float depth, float zNear, float zFar) { - float z_ndc = 2.0 * depth - 1.0; - return (2.0 * zNear * zFar) / (zFar + zNear - z_ndc * (zFar - zNear)); -} - -float linearizeDepthOrtho(float depth, float zNear, float zFar) { - return zNear + depth * (zFar - zNear); -} - -#endif // _UTILS_GLSL_ From 9e1762180237474b6162e9e78dc1b44d394b225c Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Thu, 26 Feb 2026 16:13:05 +0100 Subject: [PATCH 5/6] utils/WriteTextureToImage : throw error instead of assert if texture download fails --- src/candlewick/utils/WriteTextureToImage.cpp | 9 +++++++-- src/candlewick/utils/WriteTextureToImage.h | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/candlewick/utils/WriteTextureToImage.cpp b/src/candlewick/utils/WriteTextureToImage.cpp index ff7efa5b..6646ba8c 100644 --- a/src/candlewick/utils/WriteTextureToImage.cpp +++ b/src/candlewick/utils/WriteTextureToImage.cpp @@ -62,8 +62,13 @@ namespace media { // pixel size, in bytes const Uint32 pixelSize = SDL_GPUTextureFormatTexelBlockSize(format); const Uint32 requiredSize = width * height * pixelSize; - assert(requiredSize == - SDL_CalculateGPUTextureFormatSize(format, width, height, 1)); + if (Uint32 texSize = + SDL_CalculateGPUTextureFormatSize(format, width, height, 1); + requiredSize != texSize) + terminate_with_message( + "The required size for the payload ({:d} bytes) is different from " + "the target texture's size ({:d} bytes)", + requiredSize, texSize); SDL_GPUTransferBuffer *buffer = pool.acquireBuffer(requiredSize); diff --git a/src/candlewick/utils/WriteTextureToImage.h b/src/candlewick/utils/WriteTextureToImage.h index 28330fc2..9eca1982 100644 --- a/src/candlewick/utils/WriteTextureToImage.h +++ b/src/candlewick/utils/WriteTextureToImage.h @@ -22,7 +22,7 @@ namespace media { Uint32 _currentBufSize = 0; public: - TransferBufferPool(const Device &device); + explicit TransferBufferPool(const Device &device); void release() noexcept; ~TransferBufferPool() noexcept { this->release(); } From b32d96cd3cbd8c08fa89ff9159e957cd143f8ac6 Mon Sep 17 00:00:00 2001 From: ManifoldFR Date: Thu, 26 Feb 2026 16:37:34 +0100 Subject: [PATCH 6/6] wb oit : fix final target alpha --- shaders/compiled/WBOITComposite.frag.msl | 2 +- shaders/compiled/WBOITComposite.frag.spv | Bin 1312 -> 1348 bytes shaders/src/WBOITComposite.frag.slang | 2 +- src/candlewick/multibody/RobotScene.cpp | 6 +++--- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/shaders/compiled/WBOITComposite.frag.msl b/shaders/compiled/WBOITComposite.frag.msl index 11ac1712..6ac79fab 100644 --- a/shaders/compiled/WBOITComposite.frag.msl +++ b/shaders/compiled/WBOITComposite.frag.msl @@ -74,7 +74,7 @@ struct KernelContext_0 } #line 13 - pixelOutput_0 _S7 = { float4(color_0, _S4) }; + pixelOutput_0 _S7 = { float4(color_0, 1.0 - _S4) }; diff --git a/shaders/compiled/WBOITComposite.frag.spv b/shaders/compiled/WBOITComposite.frag.spv index 225d12d1daddea467a4827f03ccb8c25125f6550..84ac8eecb530cec3453bf4266c8375101e1c6f71 100644 GIT binary patch delta 153 zcmZ3$b%cwTnMs+Qft8VgfkA`8ej=|uquoT`?TmJlSs7sH12IJGF9Rck1rP%O__7l* delta 117 zcmX@YwSbG4nMs+Qft8VgfkA`8b|SAmqs>I$?Tj{)Ss7