From e60dcb6378c07f927b4eeb65ef8e24e80afc1312 Mon Sep 17 00:00:00 2001 From: Williscool13 Date: Thu, 10 Apr 2025 22:31:05 +0700 Subject: [PATCH 01/15] Changed render targe space from view to world. --- assets/settings.willengine | 29 +++++++-------- .../ground_truth/gtao_main_pass.comp | 13 ++----- shaders/deferredMrt.frag | 10 +++--- shaders/deferredMrt.vert | 16 ++++----- shaders/deferredResolve.comp | 36 +++++++++---------- shaders/environment/environment.frag | 8 ++++- shaders/include/environment.glsl | 19 ++++++---- shaders/include/pbr.glsl | 7 +++- shaders/include/shadows.glsl | 5 +-- shaders/postProcess.comp | 5 +-- shaders/terrain/terrain.frag | 2 +- shaders/transparent.frag | 23 ++++++------ shaders/transparent.vert | 13 +++---- src/core/engine.h | 5 ++- src/core/scene/serializer.cpp | 6 ++++ src/renderer/renderer_constants.h | 4 +-- 16 files changed, 108 insertions(+), 93 deletions(-) diff --git a/assets/settings.willengine b/assets/settings.willengine index c46a3a0b..5449109c 100644 --- a/assets/settings.willengine +++ b/assets/settings.willengine @@ -6,32 +6,33 @@ }, "mainLight": { "direction": [ - 0.007031798828393221, - -0.9709741473197937, - -0.23908114433288574 + -0.28118541836738586, + -0.9318217039108276, + -0.22944071888923645 ], "color": [ - 1.0, - 1.0, + 0.30000001192092896, + 0.4000000059604645, 1.0 ], - "intensity": 1.0 + "intensity": 2.0 }, "cameraProperties": { "position": [ - -5.494653224945068, - 111.15990447998047, - 115.60420227050781 + 103.57131958007813, + 123.65534210205078, + -47.807979583740234 ], "rotation": [ - 0.15897978842258453, - 0.01722628064453602, - 0.002778323134407401, - -0.9871276021003723 + -0.15256869792938232, + -0.8378262519836426, + -0.4332984387874603, + 0.2949957251548767 ], "fov": 1.3089969158172607, "aspectRatio": 1.7777777910232544, "nearPlane": 1000.0, "farPlane": 0.10000000149011612 - } + }, + "environmentMapIndex": 5 } \ No newline at end of file diff --git a/shaders/ambient_occlusion/ground_truth/gtao_main_pass.comp b/shaders/ambient_occlusion/ground_truth/gtao_main_pass.comp index 6aff7c77..86f2ad12 100644 --- a/shaders/ambient_occlusion/ground_truth/gtao_main_pass.comp +++ b/shaders/ambient_occlusion/ground_truth/gtao_main_pass.comp @@ -1,5 +1,6 @@ #version 460 +#include "common.glsl" #include "scene.glsl" #include "gtao.glsl" @@ -102,15 +103,6 @@ vec4 reconstructViewSpacePosition(vec2 uv, float viewDepth) { return positionVS; } -mat3 adjugate(mat4 m) { - return mat3( - cross(m[1].xyz, m[2].xyz), - cross(m[2].xyz, m[0].xyz), - cross(m[0].xyz, m[1].xyz) - ); - -} - void main() { if (pushConstants.debug == -1){ return; @@ -139,8 +131,7 @@ void main() { // Get view space normal by sampling normal buffer and converting from world to view (code not relevant) - vec3 worldNormal = texture(normalBuffer, uv).rgb; - vec3 viewNormal = adjugate(sceneData.view) * worldNormal; + vec3 viewNormal = texture(normalBuffer, uv).rgb; if (pushConstants.debug == 2){ imageStore(debugImage, screenPos, vec4(viewNormal, 1.0f)); diff --git a/shaders/deferredMrt.frag b/shaders/deferredMrt.frag index 0abd3e45..bb48b679 100644 --- a/shaders/deferredMrt.frag +++ b/shaders/deferredMrt.frag @@ -9,12 +9,12 @@ // world space -layout (location = 0) in vec3 inPosition; -layout (location = 1) in vec3 inNormal; +layout (location = 0) in vec3 inViewPosition; +layout (location = 1) in vec3 inViewNormal; layout (location = 2) in vec4 inColor; layout (location = 3) in vec2 inUV; layout (location = 4) in flat uint inMaterialIndex; -layout (location = 5) in flat uint inBHasTransparent; +layout (location = 5) in flat uint inHasTransparent; layout (location = 6) in vec4 inCurrMvpPosition; layout (location = 7) in vec4 inPrevMvpPosition; @@ -71,9 +71,9 @@ void main() { } - normalTarget = vec4(normalize(inNormal), 0.0f); + normalTarget = vec4(normalize(inViewNormal), 0.0f); albedoTarget = vec4(albedo.xyz, 1.0f); - pbrTarget = vec4(metallic, roughness, 0.0f, inBHasTransparent); + pbrTarget = vec4(metallic, roughness, 0.0f, inHasTransparent); vec2 currNdc = inCurrMvpPosition.xy / inCurrMvpPosition.w; vec2 prevNdc = inPrevMvpPosition.xy / inPrevMvpPosition.w; diff --git a/shaders/deferredMrt.vert b/shaders/deferredMrt.vert index 64aa3143..0a26b919 100644 --- a/shaders/deferredMrt.vert +++ b/shaders/deferredMrt.vert @@ -20,12 +20,12 @@ layout (location = 1) in vec3 normal; layout (location = 2) in vec4 color; layout (location = 3) in vec2 uv; -layout (location = 0) out vec3 outPosition; -layout (location = 1) out vec3 outNormal; +layout (location = 0) out vec3 outViewPosition; +layout (location = 1) out vec3 outViewNormal; layout (location = 2) out vec4 outColor; layout (location = 3) out vec2 outUV; layout (location = 4) out flat uint outMaterialIndex; -layout (location = 5) out flat uint inBHasTransparent; +layout (location = 5) out flat uint outHasTransparent; layout (location = 6) out vec4 outCurrMvpPosition; layout (location = 7) out vec4 outPrevMvpPosition; @@ -35,16 +35,16 @@ void main() { uint materialIndex = primitive.materialIndex; Model models = bufferAddresses.modelBufferDeviceAddress.models[modelIndex]; - vec4 worldPos = models.currentModelMatrix * vec4(position, 1.0); + vec4 viewPos = sceneData.view * models.currentModelMatrix * vec4(position, 1.0); - outPosition = worldPos.xyz; - outNormal = adjugate(models.currentModelMatrix) * normal; + outViewPosition = viewPos.xyz; + outViewNormal = mat3(sceneData.view) * adjugate(models.currentModelMatrix) * normal; outColor = color; outUV = uv; outMaterialIndex = materialIndex; - inBHasTransparent = primitive.bHasTransparent; + outHasTransparent = primitive.bHasTransparent; - vec4 currClipPos = sceneData.viewProj * worldPos; + vec4 currClipPos = sceneData.proj * viewPos; vec4 prevClipPos = sceneData.prevViewProj * models.previousModelMatrix * vec4(position, 1.0); currClipPos.xy += currClipPos.w * sceneData.jitter.xy; prevClipPos.xy += prevClipPos.w * sceneData.jitter.zw; diff --git a/shaders/deferredResolve.comp b/shaders/deferredResolve.comp index 2e07ec29..96d90234 100644 --- a/shaders/deferredResolve.comp +++ b/shaders/deferredResolve.comp @@ -59,14 +59,11 @@ vec3 reconstructPosition(vec2 uv, float ndcDepth) { vec4 positionVS = sceneData.invProjection * vec4(ndc, ndcDepth, 1.0); positionVS /= positionVS.w; - // Transform to world-space - vec4 positionWS = sceneData.invView * positionVS; - - return positionWS.xyz; + return positionVS.xyz; } void main() { - // All calculations are done in World Space unless explicitly declared otherwise + // All calculations are done in View Space unless explicitly declared otherwise ivec2 screenPos = ivec2(gl_GlobalInvocationID.xy); if (screenPos.x > pushConstants.width || screenPos.y > pushConstants.height) { return; @@ -86,9 +83,9 @@ void main() { return; } float depth = texture(depthBuffer, uv).r; - vec3 normal = texture(normalRenderTarget, uv).rgb; + vec3 viewNormal = texture(normalRenderTarget, uv).rgb; vec4 pbrData = texture(pbrRenderTarget, uv); - vec3 position = reconstructPosition(uv, depth); + vec3 viewPosition = reconstructPosition(uv, depth); float roughness = pbrData.g; float metallic = pbrData.r; @@ -96,10 +93,11 @@ void main() { bool hasTransparent = pbrData.a == 1; - vec3 N = normalize(normal); - vec3 V = normalize(sceneData.cameraPos.xyz - position); + vec3 N = normalize(viewNormal); + vec3 V = normalize(-viewPosition); - vec3 L = normalize(-shadowCascadeData.directionalLightData.direction);// for point lights, light.pos - inPosition + // for point lights, light.pos - inPosition + vec3 L = normalize(mat3(sceneData.view) * normalize(-shadowCascadeData.directionalLightData.direction)); vec3 H = normalize(V + L); // SPECULAR @@ -122,9 +120,10 @@ void main() { // SHADOWS float offset = 0.05f; - float normalOffsetScale = max(offset, dot(normal, L) * offset); - vec3 offsetPosition = position + normal * normalOffsetScale; - float _tempShadowFactor = getShadowFactorBlend(pushConstants.pcfLevel, position, sceneData.view, shadowCascadeData.cascadeSplits, shadowCascadeData.lightViewProj, shadowMapSampler, shadowCascadeData.nearShadowPlane, shadowCascadeData.farShadowPlane); + float normalOffsetScale = max(offset, dot(N, L) * offset); + vec3 offsetPosition = viewPosition + N * normalOffsetScale; + vec4 worldPosition = sceneData.invView * vec4(offsetPosition, 1.0f); + float _tempShadowFactor = getShadowFactorBlend(pushConstants.pcfLevel, worldPosition.xyz, abs(viewPosition.z), shadowCascadeData.cascadeSplits, shadowCascadeData.lightViewProj, shadowMapSampler, shadowCascadeData.nearShadowPlane, shadowCascadeData.farShadowPlane); float shadowFactor = clamp(smoothstep(-0.15f, 0.5f, dot(N, L)) * _tempShadowFactor, 0, 1); if (pushConstants.disableShadows == 1) { @@ -135,9 +134,10 @@ void main() { vec3 directLight = (diffuse + specular) * nDotL * shadowFactor * shadowCascadeData.directionalLightData.intensity * shadowCascadeData.directionalLightData.color; // IBL Reflections - vec3 irradiance = DiffuseIrradiance(environmentDiffuseAndSpecular, N); + vec3 worldN = normalize(mat3(sceneData.invView) * N); + vec3 irradiance = DiffuseIrradiance(environmentDiffuseAndSpecular, worldN); vec3 reflectionDiffuse = irradiance * albedo.xyz; - vec3 reflectionSpecular = SpecularReflection(environmentDiffuseAndSpecular, lut, V, N, roughness, F); + vec3 reflectionSpecular = SpecularReflection(environmentDiffuseAndSpecular, lut, V, N, sceneData.invView, roughness, F0); float ao = 1.0f; if (!hasTransparent) { @@ -166,7 +166,7 @@ void main() { imageStore(outputImage, screenPos, albedo); break; case 4: - imageStore(outputImage, screenPos, vec4(normal, 1.0f)); + imageStore(outputImage, screenPos, vec4(worldN * 0.5f + 0.5f, 1.0f)); break; case 5: imageStore(outputImage, screenPos, pbrData); @@ -175,7 +175,7 @@ void main() { imageStore(outputImage, screenPos, vec4(vec3(shadowFactor), 1.0f)); break; case 7: - float viewDepth = getViewSpaceDepth(position, sceneData.view); + float viewDepth = abs(viewPosition.z); int cascadeLevel = selectCascadeLevel(viewDepth, shadowCascadeData.cascadeSplits); float value = viewDepth - shadowCascadeData.cascadeSplits[cascadeLevel].nearPlane; float diff = value / (shadowCascadeData.cascadeSplits[cascadeLevel].farPlane - shadowCascadeData.cascadeSplits[cascadeLevel].nearPlane); @@ -190,7 +190,7 @@ void main() { break; case 9: float ao = texture(aoBuffer, uv).r; - imageStore(outputImage, screenPos, vec4(vec3(ao), 1.0f)); + imageStore(outputImage, screenPos, vec4(vec3(viewPosition), 1.0f)); break; } } \ No newline at end of file diff --git a/shaders/environment/environment.frag b/shaders/environment/environment.frag index 5d408c4c..dd53a94c 100644 --- a/shaders/environment/environment.frag +++ b/shaders/environment/environment.frag @@ -1,4 +1,7 @@ #version 450 + +#include "scene.glsl" + layout (location = 0) in vec3 uv; layout (location = 1) in vec4 inCurrMvpPosition; layout (location = 2) in vec4 inPrevMvpPosition; @@ -8,6 +11,8 @@ layout (location = 1) out vec4 albedoTarget;// 10,10,10, (2 -> 0 = environment M layout (location = 2) out vec4 pbrTarget;// 8 metallic, 8 roughness, 8 emissive (unused), 8 unused layout (location = 3) out vec2 velocityTarget;// 16 X, 16 Y +// layout (std140, set = 0, binding = 0) uniform SceneData - scene.glsl + layout(set = 1, binding = 0) uniform samplerCube environmentMap; void main() @@ -19,7 +24,8 @@ void main() // 0 = environment map flag albedoTarget = vec4(envColor, 0.0); - normalTarget = vec4(-direction, 0.0f); + vec3 normal = mat3(sceneData.view) * -direction; + normalTarget = vec4(normal, 0.0f); pbrTarget = vec4(0.0f); vec2 currNdc = inCurrMvpPosition.xy / inCurrMvpPosition.w; diff --git a/shaders/include/environment.glsl b/shaders/include/environment.glsl index 198eaf5d..cb09cfc7 100644 --- a/shaders/include/environment.glsl +++ b/shaders/include/environment.glsl @@ -2,21 +2,26 @@ const float MAX_REFLECTION_LOD = 4.0; const uint DIFF_IRRA_MIP_LEVEL = 5; const bool FLIP_ENVIRONMENT_MAP_Y = true; +#include "pbr.glsl" -vec3 DiffuseIrradiance(samplerCube envDiffSpec, vec3 N) +vec3 DiffuseIrradiance(samplerCube envDiffSpec, vec3 worldNormal) { - vec3 ENV_N = N; + vec3 ENV_N = worldNormal; if (FLIP_ENVIRONMENT_MAP_Y) { ENV_N.y = -ENV_N.y; } return textureLod(envDiffSpec, ENV_N, DIFF_IRRA_MIP_LEVEL).rgb; } -vec3 SpecularReflection(samplerCube envDiffSpec, sampler2D lut, vec3 V, vec3 N, float roughness, vec3 F) { - vec3 R = reflect(-V, N); - if (FLIP_ENVIRONMENT_MAP_Y) { R.y = -R.y; } +vec3 SpecularReflection(samplerCube envDiffSpec, sampler2D lut, vec3 viewV, vec3 viewN, mat4 invView, float roughness, vec3 F0) { + vec3 R = reflect(-viewV, viewN); + + vec3 worldR = normalize((invView * vec4(R, 0.0)).xyz); + + if (FLIP_ENVIRONMENT_MAP_Y) { worldR.y = -worldR.y; } // dont need to skip mip 5 because never goes above 4 - vec3 prefilteredColor = textureLod(envDiffSpec, R, roughness * MAX_REFLECTION_LOD).rgb; + vec3 prefilteredColor = textureLod(envDiffSpec, worldR, roughness * MAX_REFLECTION_LOD).rgb; - vec2 envBRDF = texture(lut, vec2(max(dot(N, V), 0.0f), roughness)).rg; + vec2 envBRDF = texture(lut, vec2(max(dot(viewN, viewV), 0.0f), roughness)).rg; + vec3 F = F_SCHLICK(viewV, viewN, F0); return prefilteredColor * (F * envBRDF.x + envBRDF.y); } \ No newline at end of file diff --git a/shaders/include/pbr.glsl b/shaders/include/pbr.glsl index 4454743f..4bc39ca0 100644 --- a/shaders/include/pbr.glsl +++ b/shaders/include/pbr.glsl @@ -1,3 +1,6 @@ +#ifndef PBR_GLSL +#define PBR_GLSL + vec3 Lambert(vec3 kD, vec3 albedo) { return kD * albedo / 3.14159265359; @@ -52,4 +55,6 @@ vec3 F_SCHLICK(vec3 V, vec3 H, vec3 F0){ // unreal optimized return F0 + (1 - F0) * pow(2, FRESNEL_POWER_UNREAL(V, H)); -} \ No newline at end of file +} + +#endif // PBR_GLSL \ No newline at end of file diff --git a/shaders/include/shadows.glsl b/shaders/include/shadows.glsl index 98789c56..6a6dacd0 100644 --- a/shaders/include/shadows.glsl +++ b/shaders/include/shadows.glsl @@ -28,10 +28,7 @@ int getCascadeLevel(vec3 worldPos, mat4 viewMatrix, CascadeSplit cascadeSplits[4 return selectCascadeLevel(viewDepth, cascadeSplits); } -float getShadowFactorBlend(int pcfLevel, vec3 worldPos, mat4 sceneViewMatrix, CascadeSplit[4] splits, mat4[4] lightMatrices, sampler2DShadow[4] shadowMaps, float cascadeNearPlane, float cascadeFarPlane) { - vec4 viewPos = sceneViewMatrix * vec4(worldPos, 1.0); - float viewSpaceDepth = abs(viewPos.z); - +float getShadowFactorBlend(int pcfLevel, vec3 worldPos, float viewSpaceDepth, CascadeSplit[4] splits, mat4[4] lightMatrices, sampler2DShadow[4] shadowMaps, float cascadeNearPlane, float cascadeFarPlane) { if (viewSpaceDepth < cascadeNearPlane) { // Too close = shadowed return 0.0f; diff --git a/shaders/postProcess.comp b/shaders/postProcess.comp index c8de1622..25c39cb9 100644 --- a/shaders/postProcess.comp +++ b/shaders/postProcess.comp @@ -54,8 +54,8 @@ void main() { vec3 color = fullColor.rgb; if ((push.flags & 1) != 0) { - //color = reinhardTonemap(color); color = aces(color); + //color = aces(color); } if ((push.flags & 4) != 0) { @@ -67,8 +67,5 @@ void main() { color = sharpen(color, sceneData.texelSize, uv); } - - - imageStore(outputImage, pixel, vec4(color, fullColor.a)); } \ No newline at end of file diff --git a/shaders/terrain/terrain.frag b/shaders/terrain/terrain.frag index 4aef3906..4f2dfd81 100644 --- a/shaders/terrain/terrain.frag +++ b/shaders/terrain/terrain.frag @@ -41,7 +41,7 @@ float smoothBlend(float value, float threshold, float range) { } void main() { - normalTarget = vec4(normalize(inNormal), 0.0f); + normalTarget = vec4(mat3(sceneData.view) * normalize(inNormal), 0.0f); float slope = 1.0 - abs(dot(normalize(inNormal), vec3(0.0, 1.0, 0.0))); float height = inPosition.y; diff --git a/shaders/transparent.frag b/shaders/transparent.frag index d5bc4dd0..2ef1dfaf 100644 --- a/shaders/transparent.frag +++ b/shaders/transparent.frag @@ -12,8 +12,8 @@ #include "transparent.glsl" // world space -layout (location = 0) in vec3 inPosition; -layout (location = 1) in vec3 inNormal; +layout (location = 0) in vec3 inViewPosition; +layout (location = 1) in vec3 inViewNormal; layout (location = 2) in vec4 inColor; layout (location = 3) in vec2 inUV; layout (location = 4) in flat uint inMaterialIndex; @@ -81,10 +81,11 @@ void main() { roughness *= metalRoughSample.g; } - vec3 N = normalize(inNormal); - vec3 V = normalize(sceneData.cameraPos.xyz - inPosition); + vec3 N = normalize(inViewNormal); + vec3 V = normalize(-inViewPosition); - vec3 L = normalize(-shadowCascadeData.directionalLightData.direction); // for point lights, light.pos - inPosition + // for point lights, light.pos - inPosition + vec3 L = normalize(mat3(sceneData.view) * normalize(-shadowCascadeData.directionalLightData.direction)); vec3 H = normalize(V + L); // SPECULAR @@ -107,9 +108,10 @@ void main() { // SHADOWS float offset = 0.05f; - float normalOffsetScale = max(offset, dot(inNormal, L) * offset); - vec3 offsetPosition = inPosition + inNormal * normalOffsetScale; - float _tempShadowFactor = getShadowFactorBlend(1, inPosition, sceneData.view, shadowCascadeData.cascadeSplits, shadowCascadeData.lightViewProj, shadowMapSampler, shadowCascadeData.nearShadowPlane, shadowCascadeData.farShadowPlane); + float normalOffsetScale = max(offset, dot(N, L) * offset); + vec3 offsetPosition = inViewPosition + N * normalOffsetScale; + vec4 worldPosition = sceneData.invView * vec4(offsetPosition, 1.0f); + float _tempShadowFactor = getShadowFactorBlend(1, worldPosition.xyz, abs(inViewPosition.z), shadowCascadeData.cascadeSplits, shadowCascadeData.lightViewProj, shadowMapSampler, shadowCascadeData.nearShadowPlane, shadowCascadeData.farShadowPlane); float shadowFactor = clamp(smoothstep(-0.15f, 0.5f, dot(N, L)) * _tempShadowFactor, 0, 1); if (pushConstants.receiveShadows == 0) { @@ -119,9 +121,10 @@ void main() { vec3 directLight = (diffuse + specular) * nDotL * shadowFactor * shadowCascadeData.directionalLightData.intensity * shadowCascadeData.directionalLightData.color; // IBL Reflections - vec3 irradiance = DiffuseIrradiance(environmentDiffuseAndSpecular, N); + vec3 worldN = normalize(mat3(sceneData.invView) * N); + vec3 irradiance = DiffuseIrradiance(environmentDiffuseAndSpecular, worldN); vec3 reflectionDiffuse = irradiance * albedo.xyz; - vec3 reflectionSpecular = SpecularReflection(environmentDiffuseAndSpecular, lut, V, N, roughness, F); + vec3 reflectionSpecular = SpecularReflection(environmentDiffuseAndSpecular, lut, V, N, sceneData.invView, roughness, F0); float ao = 1.0f; vec3 ambient = (kD * reflectionDiffuse + reflectionSpecular) * ao; diff --git a/shaders/transparent.vert b/shaders/transparent.vert index d41c7f83..79846653 100644 --- a/shaders/transparent.vert +++ b/shaders/transparent.vert @@ -20,8 +20,8 @@ layout (location = 1) in vec3 normal; layout (location = 2) in vec4 color; layout (location = 3) in vec2 uv; -layout (location = 0) out vec3 outPosition; -layout (location = 1) out vec3 outNormal; +layout (location = 0) out vec3 outViewPosition; +layout (location = 1) out vec3 outViewNormal; layout (location = 2) out vec4 outColor; layout (location = 3) out vec2 outUV; layout (location = 4) out flat uint outMaterialIndex; @@ -32,16 +32,17 @@ void main() { uint materialIndex = primitive.materialIndex; Model models = bufferAddresses.modelBufferDeviceAddress.models[modelIndex]; - vec4 worldPos = models.currentModelMatrix * vec4(position, 1.0); + vec4 viewPos = sceneData.view * models.currentModelMatrix * vec4(position, 1.0); - outPosition = worldPos.xyz; - outNormal = adjugate(models.currentModelMatrix) * normal; + outViewPosition = viewPos.xyz; + outViewNormal = mat3(sceneData.view) * adjugate(models.currentModelMatrix) * normal; outColor = color; outUV = uv; outMaterialIndex = materialIndex; - vec4 currClipPos = sceneData.viewProj * worldPos; + vec4 currClipPos = sceneData.proj * viewPos; currClipPos.xy += currClipPos.w * sceneData.jitter.xy; + // do not calculate previous because transparents shouldn't contribute motion vectors gl_Position = currClipPos; } \ No newline at end of file diff --git a/src/core/engine.h b/src/core/engine.h index f6d93500..49e5399d 100644 --- a/src/core/engine.h +++ b/src/core/engine.h @@ -194,6 +194,9 @@ class Engine DirectionalLight getMainLight() const { return mainLight; } void setMainLight(const DirectionalLight& newLight) { mainLight = newLight; } + int32_t getCurrentEnvironmentMapIndex() const { return environmentMapIndex; } + void setCurrentEnvironmentMapIndex(const int32_t index) { environmentMapIndex = index; } + private: // Scene Data DescriptorBufferUniform sceneDataDescriptorBuffer; AllocatedBuffer sceneDataBuffers[FRAME_OVERLAP]{}; @@ -229,7 +232,7 @@ class Engine AllocatedImage depthImage{}; /** - * 8.8.8 Normals - 8 unused + * 8.8.8 View Normals - 8 unused */ AllocatedImage normalRenderTarget{}; /** diff --git a/src/core/scene/serializer.cpp b/src/core/scene/serializer.cpp index 2e9e2adb..e86ecd37 100644 --- a/src/core/scene/serializer.cpp +++ b/src/core/scene/serializer.cpp @@ -356,6 +356,8 @@ bool Serializer::serializeEngineSettings(Engine* engine) rootJ["cameraProperties"] = cameraProperties; + rootJ["environmentMapIndex"] = engine->getCurrentEnvironmentMapIndex(); + const std::filesystem::path filepath = {"assets/settings.willengine"}; @@ -457,6 +459,10 @@ bool Serializer::deserializeEngineSettings(Engine* engine) engine->setMainLight(light); } + if (rootJ.contains("environmentMapIndex")) { + engine->setCurrentEnvironmentMapIndex(rootJ["environmentMapIndex"]); + } + return true; } catch (const std::exception& e) { diff --git a/src/renderer/renderer_constants.h b/src/renderer/renderer_constants.h index 3dfd19e9..c0d9611d 100644 --- a/src/renderer/renderer_constants.h +++ b/src/renderer/renderer_constants.h @@ -10,8 +10,8 @@ constexpr int32_t FRAME_OVERLAP = 2; constexpr char ENGINE_NAME[] = "Will Engine"; constexpr bool USING_REVERSED_DEPTH_BUFFER = true; constexpr VkDeviceSize ZERO_DEVICE_SIZE = 0; -constexpr VkExtent2D RENDER_EXTENTS{1920, 1080}; -//constexpr VkExtent2D RENDER_EXTENTS{2140, 1440}; +//constexpr VkExtent2D RENDER_EXTENTS{1920, 1080}; +constexpr VkExtent2D RENDER_EXTENTS{2140, 1440}; //constexpr VkExtent2D RENDER_EXTENTS{3840, 2160}; constexpr float RENDER_EXTENT_WIDTH{RENDER_EXTENTS.width}; constexpr float RENDER_EXTENT_HEIGHT{RENDER_EXTENTS.height}; From 2bd8d07e8d866e2ed139718d4ba475cb7488f4fd Mon Sep 17 00:00:00 2001 From: Williscool13 Date: Thu, 10 Apr 2025 23:08:15 +0700 Subject: [PATCH 02/15] Fix excessive blackening when facing direction is almost antiparallel to the light direction. --- assets/settings.willengine | 26 +++++++++++++------------- shaders/deferredResolve.comp | 4 ++-- shaders/include/environment.glsl | 5 +---- shaders/transparent.frag | 2 +- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/assets/settings.willengine b/assets/settings.willengine index 5449109c..57b900aa 100644 --- a/assets/settings.willengine +++ b/assets/settings.willengine @@ -6,33 +6,33 @@ }, "mainLight": { "direction": [ - -0.28118541836738586, - -0.9318217039108276, - -0.22944071888923645 + -0.4358838200569153, + -0.8787980675697327, + -0.1942143738269806 ], "color": [ - 0.30000001192092896, - 0.4000000059604645, + 1.0, + 1.0, 1.0 ], "intensity": 2.0 }, "cameraProperties": { "position": [ - 103.57131958007813, - 123.65534210205078, - -47.807979583740234 + -8.284133911132813, + 75.93592834472656, + -2.76928448677063 ], "rotation": [ - -0.15256869792938232, - -0.8378262519836426, - -0.4332984387874603, - 0.2949957251548767 + 0.15774185955524445, + 0.776819109916687, + 0.21475039422512054, + -0.5705716609954834 ], "fov": 1.3089969158172607, "aspectRatio": 1.7777777910232544, "nearPlane": 1000.0, "farPlane": 0.10000000149011612 }, - "environmentMapIndex": 5 + "environmentMapIndex": 3 } \ No newline at end of file diff --git a/shaders/deferredResolve.comp b/shaders/deferredResolve.comp index 96d90234..517fed8a 100644 --- a/shaders/deferredResolve.comp +++ b/shaders/deferredResolve.comp @@ -137,7 +137,7 @@ void main() { vec3 worldN = normalize(mat3(sceneData.invView) * N); vec3 irradiance = DiffuseIrradiance(environmentDiffuseAndSpecular, worldN); vec3 reflectionDiffuse = irradiance * albedo.xyz; - vec3 reflectionSpecular = SpecularReflection(environmentDiffuseAndSpecular, lut, V, N, sceneData.invView, roughness, F0); + vec3 reflectionSpecular = SpecularReflection(environmentDiffuseAndSpecular, lut, V, N, sceneData.invView, roughness, F); float ao = 1.0f; if (!hasTransparent) { @@ -190,7 +190,7 @@ void main() { break; case 9: float ao = texture(aoBuffer, uv).r; - imageStore(outputImage, screenPos, vec4(vec3(viewPosition), 1.0f)); + imageStore(outputImage, screenPos, vec4(vec3(ao), 1.0f)); break; } } \ No newline at end of file diff --git a/shaders/include/environment.glsl b/shaders/include/environment.glsl index cb09cfc7..fee7cb47 100644 --- a/shaders/include/environment.glsl +++ b/shaders/include/environment.glsl @@ -2,8 +2,6 @@ const float MAX_REFLECTION_LOD = 4.0; const uint DIFF_IRRA_MIP_LEVEL = 5; const bool FLIP_ENVIRONMENT_MAP_Y = true; -#include "pbr.glsl" - vec3 DiffuseIrradiance(samplerCube envDiffSpec, vec3 worldNormal) { vec3 ENV_N = worldNormal; @@ -11,7 +9,7 @@ vec3 DiffuseIrradiance(samplerCube envDiffSpec, vec3 worldNormal) return textureLod(envDiffSpec, ENV_N, DIFF_IRRA_MIP_LEVEL).rgb; } -vec3 SpecularReflection(samplerCube envDiffSpec, sampler2D lut, vec3 viewV, vec3 viewN, mat4 invView, float roughness, vec3 F0) { +vec3 SpecularReflection(samplerCube envDiffSpec, sampler2D lut, vec3 viewV, vec3 viewN, mat4 invView, float roughness, vec3 F) { vec3 R = reflect(-viewV, viewN); vec3 worldR = normalize((invView * vec4(R, 0.0)).xyz); @@ -22,6 +20,5 @@ vec3 SpecularReflection(samplerCube envDiffSpec, sampler2D lut, vec3 viewV, vec3 vec2 envBRDF = texture(lut, vec2(max(dot(viewN, viewV), 0.0f), roughness)).rg; - vec3 F = F_SCHLICK(viewV, viewN, F0); return prefilteredColor * (F * envBRDF.x + envBRDF.y); } \ No newline at end of file diff --git a/shaders/transparent.frag b/shaders/transparent.frag index 2ef1dfaf..5464375f 100644 --- a/shaders/transparent.frag +++ b/shaders/transparent.frag @@ -124,7 +124,7 @@ void main() { vec3 worldN = normalize(mat3(sceneData.invView) * N); vec3 irradiance = DiffuseIrradiance(environmentDiffuseAndSpecular, worldN); vec3 reflectionDiffuse = irradiance * albedo.xyz; - vec3 reflectionSpecular = SpecularReflection(environmentDiffuseAndSpecular, lut, V, N, sceneData.invView, roughness, F0); + vec3 reflectionSpecular = SpecularReflection(environmentDiffuseAndSpecular, lut, V, N, sceneData.invView, roughness, F); float ao = 1.0f; vec3 ambient = (kD * reflectionDiffuse + reflectionSpecular) * ao; From e518650a4a0117004895a8f46919a8f07912feb6 Mon Sep 17 00:00:00 2001 From: Williscool13 Date: Fri, 11 Apr 2025 17:39:18 +0700 Subject: [PATCH 03/15] Fix GTAO incorrect texture gather --- assets/settings.willengine | 26 +++++++++---------- .../ground_truth/gtao_main_pass.comp | 4 +-- shaders/shadows/shadow_pass.frag | 2 +- .../lighting/shadows/shadow_constants.cpp | 4 +-- .../lighting/shadows/shadow_constants.h | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/assets/settings.willengine b/assets/settings.willengine index 57b900aa..40c40ad8 100644 --- a/assets/settings.willengine +++ b/assets/settings.willengine @@ -6,33 +6,33 @@ }, "mainLight": { "direction": [ - -0.4358838200569153, - -0.8787980675697327, - -0.1942143738269806 + -0.4728662669658661, + -0.7881104350090027, + -0.39405521750450134 ], "color": [ - 1.0, - 1.0, + 0.20000000298023224, + 0.4000000059604645, 1.0 ], "intensity": 2.0 }, "cameraProperties": { "position": [ - -8.284133911132813, - 75.93592834472656, - -2.76928448677063 + -79.6306381225586, + 104.47303009033203, + 21.961862564086914 ], "rotation": [ - 0.15774185955524445, - 0.776819109916687, - 0.21475039422512054, - -0.5705716609954834 + 0.11517144739627838, + 0.8840671181678772, + 0.3000337779521942, + -0.3393239676952362 ], "fov": 1.3089969158172607, "aspectRatio": 1.7777777910232544, "nearPlane": 1000.0, "farPlane": 0.10000000149011612 }, - "environmentMapIndex": 3 + "environmentMapIndex": 5 } \ No newline at end of file diff --git a/shaders/ambient_occlusion/ground_truth/gtao_main_pass.comp b/shaders/ambient_occlusion/ground_truth/gtao_main_pass.comp index 86f2ad12..ad21dd10 100644 --- a/shaders/ambient_occlusion/ground_truth/gtao_main_pass.comp +++ b/shaders/ambient_occlusion/ground_truth/gtao_main_pass.comp @@ -121,8 +121,8 @@ void main() { vec4 valuesBR = textureGatherOffset(prefilteredDepth, gatherCenter, ivec2(1, 1), 0); float viewSpaceZM = valuesUL.y; const float viewSpaceZL = valuesUL.x; - const float viewSpaceZR = valuesUL.z; - const float viewSpaceZT = valuesBR.z; + const float viewSpaceZT = valuesUL.z; + const float viewSpaceZR = valuesBR.z; const float viewSpaceZB = valuesBR.x; vec4 edges = XE_GTAO_CalculateDepthEdges(viewSpaceZM, viewSpaceZL, viewSpaceZR, viewSpaceZT, viewSpaceZB); diff --git a/shaders/shadows/shadow_pass.frag b/shaders/shadows/shadow_pass.frag index 2a921715..364e023b 100644 --- a/shaders/shadows/shadow_pass.frag +++ b/shaders/shadows/shadow_pass.frag @@ -1,5 +1,5 @@ #version 460 void main() { - + // todo: discard if the fragment is cutoff } \ No newline at end of file diff --git a/src/renderer/lighting/shadows/shadow_constants.cpp b/src/renderer/lighting/shadows/shadow_constants.cpp index be3b3e17..2571d972 100644 --- a/src/renderer/lighting/shadows/shadow_constants.cpp +++ b/src/renderer/lighting/shadows/shadow_constants.cpp @@ -5,8 +5,8 @@ #include "shadow_constants.h" float will_engine::shadows::CASCADE_BIAS[SHADOW_CASCADE_COUNT][2] = { - {500.0f, 2.0f}, - {500.0f, 1.0f}, + {500.0f, 0.7f}, + {500.0f, 0.6f}, {600.0f, 1.0f}, {300.0f, 1.0f}, }; diff --git a/src/renderer/lighting/shadows/shadow_constants.h b/src/renderer/lighting/shadows/shadow_constants.h index 0d04db8b..34c03185 100644 --- a/src/renderer/lighting/shadows/shadow_constants.h +++ b/src/renderer/lighting/shadows/shadow_constants.h @@ -13,7 +13,7 @@ static constexpr float LAMBDA = 0.8f; static constexpr float OVERLAP = 1.05f; static constexpr uint32_t SHADOW_CASCADE_COUNT = 4; static constexpr float CASCADE_NEAR_PLANE = 0.1f; -static constexpr float CASCADE_FAR_PLANE = 1000.0f; +static constexpr float CASCADE_FAR_PLANE = 400.0f; extern float CASCADE_BIAS[SHADOW_CASCADE_COUNT][2]; static constexpr int32_t CASCADE_WIDTH{2048}; static constexpr int32_t CASCADE_HEIGHT{2048}; From 8359d737e0de06caa55000763f3b5f4ac8660148 Mon Sep 17 00:00:00 2001 From: Williscool13 Date: Sat, 12 Apr 2025 16:20:44 +0700 Subject: [PATCH 04/15] Contact shadows wip. --- assets/settings.willengine | 16 ++++++++-------- shaders/shadows/contact_shadow_pass.comp | 15 +++++++++++++++ .../ground_truth_ambient_occlusion.cpp | 4 +--- 3 files changed, 24 insertions(+), 11 deletions(-) create mode 100644 shaders/shadows/contact_shadow_pass.comp diff --git a/assets/settings.willengine b/assets/settings.willengine index 40c40ad8..31645f95 100644 --- a/assets/settings.willengine +++ b/assets/settings.willengine @@ -19,20 +19,20 @@ }, "cameraProperties": { "position": [ - -79.6306381225586, - 104.47303009033203, - 21.961862564086914 + -0.008705933578312397, + 71.13257598876953, + 0.5683935880661011 ], "rotation": [ - 0.11517144739627838, - 0.8840671181678772, - 0.3000337779521942, - -0.3393239676952362 + 0.1442754864692688, + -0.015505615621805191, + -0.0022719609551131725, + -0.9894134402275085 ], "fov": 1.3089969158172607, "aspectRatio": 1.7777777910232544, "nearPlane": 1000.0, "farPlane": 0.10000000149011612 }, - "environmentMapIndex": 5 + "environmentMapIndex": 3 } \ No newline at end of file diff --git a/shaders/shadows/contact_shadow_pass.comp b/shaders/shadows/contact_shadow_pass.comp new file mode 100644 index 00000000..75ddb541 --- /dev/null +++ b/shaders/shadows/contact_shadow_pass.comp @@ -0,0 +1,15 @@ +#version 460 + +#include "scene.glsl" + +layout(local_size_x = 64) in; + + +void main() { + const ivec2 screenPos = ivec2(gl_GlobalInvocationID.xy) * ivec2(2, 1); + if (screenPos.x > sceneData.renderTargetSize.x || screenPos.y > sceneData.renderTargetSize.y) { + return; + } + + +} diff --git a/src/renderer/lighting/ambient_occlusion/ground_truth/ground_truth_ambient_occlusion.cpp b/src/renderer/lighting/ambient_occlusion/ground_truth/ground_truth_ambient_occlusion.cpp index 513a116d..55ee1b95 100644 --- a/src/renderer/lighting/ambient_occlusion/ground_truth/ground_truth_ambient_occlusion.cpp +++ b/src/renderer/lighting/ambient_occlusion/ground_truth/ground_truth_ambient_occlusion.cpp @@ -406,11 +406,9 @@ void will_engine::ambient_occlusion::GroundTruthAmbientOcclusionPipeline::draw(V vkCmdSetDescriptorBufferOffsetsEXT(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, depthPrefilterPipelineLayout, 0, 2, indices.data(), offsets.data()); + // shader only operates on 8,8 work groups, mip 0 will operate on 2x2 texels auto x = static_cast(std::ceil(RENDER_EXTENT_WIDTH / 16.0f)); auto y = static_cast(std::ceil(RENDER_EXTENT_HEIGHT / 16.0f)); - // shader only operates on 8,8 work groups, mip 0 will operate on 2x2 texels - // x = x / 2 + 1; - // y = y / 2 + 1; vkCmdDispatch(cmd, x, y, 1); } From 88ce2cd50f346375ef89693e112723309aa6911e Mon Sep 17 00:00:00 2001 From: Williscool13 Date: Mon, 14 Apr 2025 20:53:09 +0700 Subject: [PATCH 05/15] Major pipeline header cleanup. --- CMakeLists.txt | 27 +++++-- assets/settings.willengine | 16 ++-- shaders/deferredMrt.frag | 3 + shaders/shadows/contact_shadow_pass.comp | 48 ++++++++++++ src/core/engine.cpp | 19 +++-- src/core/engine.h | 8 +- src/renderer/imgui_wrapper.cpp | 78 +++---------------- src/renderer/imgui_wrapper.h | 2 - .../basic_compute/basic_compute_pipeline.cpp | 11 +-- .../basic_compute/basic_compute_pipeline.h | 19 ++--- .../basic_compute_pipeline_types.h | 23 ++++++ .../basic_render/basic_render_pipeline.cpp | 14 ++-- .../basic_render/basic_render_pipeline.h | 30 ++----- .../basic_render_pipeline_types.h | 34 ++++++++ .../contact_shadows_pipeline.cpp | 13 ++++ .../contact_shadow/contact_shadows_pipeline.h | 23 ++++++ .../contact_shadows_pipeline_types.h | 24 ++++++ .../pipelines/deferred_mrt/deferred_mrt.h | 53 ------------- ...rred_mrt.cpp => deferred_mrt_pipeline.cpp} | 11 ++- .../deferred_mrt/deferred_mrt_pipeline.h | 43 ++++++++++ .../deferred_mrt_pipeline_types.h | 30 +++++++ ...olve.cpp => deferred_resolve_pipeline.cpp} | 13 +--- .../deferred_resolve_pipeline.h | 53 +++++++++++++ ...ve.h => deferred_resolve_pipeline_types.h} | 40 ++-------- .../environment/environment_pipeline.cpp | 4 +- .../environment/environment_pipeline.h | 22 ++---- .../environment/environment_pipeline_types.h | 27 +++++++ .../post_process/post_process_pipeline.cpp | 8 +- .../post_process/post_process_pipeline.h | 29 ++----- .../post_process_pipeline_types.h | 70 +++++++++++++++++ .../temporal_antialiasing_pipeline.cpp | 5 +- .../temporal_antialiasing_pipeline.h | 30 ++----- .../temporal_antialiasing_pipeline_types.h | 37 +++++++++ .../pipelines/terrain/terrain_pipeline.cpp | 8 +- .../pipelines/terrain/terrain_pipeline.h | 33 ++------ .../terrain/terrain_pipeline_types.h | 43 ++++++++++ .../transparent_pipeline.cpp | 7 +- .../transparent_pipeline.h | 37 ++------- .../transparent_pipeline_types.h | 46 +++++++++++ ..._pass.cpp => visibility_pass_pipeline.cpp} | 24 +++--- ...lity_pass.h => visibility_pass_pipeline.h} | 21 +---- .../visibility_pass_pipeline_types.h | 36 +++++++++ .../post_process/post_process_types.h | 41 ---------- src/renderer/renderer_constants.h | 6 +- 44 files changed, 734 insertions(+), 435 deletions(-) create mode 100644 src/renderer/pipelines/basic_compute/basic_compute_pipeline_types.h create mode 100644 src/renderer/pipelines/basic_render/basic_render_pipeline_types.h create mode 100644 src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.cpp create mode 100644 src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.h create mode 100644 src/renderer/pipelines/contact_shadow/contact_shadows_pipeline_types.h delete mode 100644 src/renderer/pipelines/deferred_mrt/deferred_mrt.h rename src/renderer/pipelines/deferred_mrt/{deferred_mrt.cpp => deferred_mrt_pipeline.cpp} (96%) create mode 100644 src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline.h create mode 100644 src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline_types.h rename src/renderer/pipelines/deferred_resolve/{deferred_resolve.cpp => deferred_resolve_pipeline.cpp} (97%) create mode 100644 src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline.h rename src/renderer/pipelines/deferred_resolve/{deferred_resolve.h => deferred_resolve_pipeline_types.h} (50%) create mode 100644 src/renderer/pipelines/environment/environment_pipeline_types.h create mode 100644 src/renderer/pipelines/post_process/post_process_pipeline_types.h create mode 100644 src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline_types.h create mode 100644 src/renderer/pipelines/terrain/terrain_pipeline_types.h create mode 100644 src/renderer/pipelines/transparent_pipeline/transparent_pipeline_types.h rename src/renderer/pipelines/visibility_pass/{visibility_pass.cpp => visibility_pass_pipeline.cpp} (80%) rename src/renderer/pipelines/visibility_pass/{visibility_pass.h => visibility_pass_pipeline.h} (58%) create mode 100644 src/renderer/pipelines/visibility_pass/visibility_pass_pipeline_types.h delete mode 100644 src/renderer/post_process/post_process_types.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e688f96..60d0a94b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -156,16 +156,18 @@ set(RENDERER_SOURCES src/renderer/environment/environment.h src/renderer/environment/environment_constants.h src/renderer/environment/environment_types.h - src/renderer/pipelines/deferred_mrt/deferred_mrt.cpp - src/renderer/pipelines/deferred_mrt/deferred_mrt.h - src/renderer/pipelines/deferred_resolve/deferred_resolve.cpp - src/renderer/pipelines/deferred_resolve/deferred_resolve.h + src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline.cpp + src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline.h + src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline_types.h + src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline.cpp + src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline.h + src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline_types.h src/renderer/pipelines/environment/environment_pipeline.cpp src/renderer/pipelines/environment/environment_pipeline.h src/renderer/pipelines/post_process/post_process_pipeline.cpp src/renderer/pipelines/post_process/post_process_pipeline.h - src/renderer/pipelines/visibility_pass/visibility_pass.cpp - src/renderer/pipelines/visibility_pass/visibility_pass.h + src/renderer/pipelines/visibility_pass/visibility_pass_pipeline.cpp + src/renderer/pipelines/visibility_pass/visibility_pass_pipeline.h src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline.cpp src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline.h src/renderer/pipelines/basic_compute/basic_compute_pipeline.cpp @@ -188,7 +190,6 @@ set(RENDERER_SOURCES src/renderer/descriptor_buffer/descriptor_buffer_uniform.cpp src/renderer/descriptor_buffer/descriptor_buffer_uniform.h src/renderer/assets/render_object/render_object_constants.h - src/renderer/post_process/post_process_types.h ) @@ -247,6 +248,18 @@ set(TEMP_SOURCES src/renderer/pipelines/transparent_pipeline/transparent_pipeline.cpp src/renderer/pipelines/transparent_pipeline/transparent_pipeline.h src/engine_constants.h + src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.cpp + src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.h + src/renderer/pipelines/contact_shadow/contact_shadows_pipeline_types.h + + src/renderer/pipelines/environment/environment_pipeline_types.h + src/renderer/pipelines/basic_render/basic_render_pipeline_types.h + src/renderer/pipelines/post_process/post_process_pipeline_types.h + src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline_types.h + src/renderer/pipelines/terrain/terrain_pipeline_types.h + src/renderer/pipelines/transparent_pipeline/transparent_pipeline_types.h + src/renderer/pipelines/basic_compute/basic_compute_pipeline_types.h + src/renderer/pipelines/visibility_pass/visibility_pass_pipeline_types.h ) diff --git a/assets/settings.willengine b/assets/settings.willengine index 31645f95..71153e5a 100644 --- a/assets/settings.willengine +++ b/assets/settings.willengine @@ -19,20 +19,20 @@ }, "cameraProperties": { "position": [ - -0.008705933578312397, - 71.13257598876953, - 0.5683935880661011 + 62.77393341064453, + 81.94156646728516, + -87.18507385253906 ], "rotation": [ - 0.1442754864692688, - -0.015505615621805191, - -0.0022719609551131725, - -0.9894134402275085 + -0.06119464710354805, + -0.3182604908943176, + 0.020581098273396492, + -0.9458022713661194 ], "fov": 1.3089969158172607, "aspectRatio": 1.7777777910232544, "nearPlane": 1000.0, "farPlane": 0.10000000149011612 }, - "environmentMapIndex": 3 + "environmentMapIndex": 1 } \ No newline at end of file diff --git a/shaders/deferredMrt.frag b/shaders/deferredMrt.frag index bb48b679..47eaca35 100644 --- a/shaders/deferredMrt.frag +++ b/shaders/deferredMrt.frag @@ -45,6 +45,8 @@ void main() { } albedo = albedo * inColor * m.colorFactor; + // Look into custom shaders specifically for these? More draw commands vs branching... + // 1 is transparent blend type if (m.alphaCutoff.y == 1) { // Draw only if alpha is close enough to 1 if (albedo.w <= 1.0 - TRANSPARENT_ALPHA_EPSILON) { @@ -52,6 +54,7 @@ void main() { } } + // 2 is "mask" (cutout) blend type if (m.alphaCutoff.y == 2){ // 2 is "mask" blend type if (albedo.w < m.alphaCutoff.x){ diff --git a/shaders/shadows/contact_shadow_pass.comp b/shaders/shadows/contact_shadow_pass.comp index 75ddb541..61382fa9 100644 --- a/shaders/shadows/contact_shadow_pass.comp +++ b/shaders/shadows/contact_shadow_pass.comp @@ -4,6 +4,54 @@ layout(local_size_x = 64) in; +// layout (std140, set = 0, binding = 0) uniform SceneData - scene.glsl + +layout (set = 1, binding = 0) uniform sampler2D depthImage; +layout (r16f, set = 1, binding = 1) uniform image2D outDepth0; +layout (r16f, set = 1, binding = 2) uniform image2D outDepth1; +layout (r16f, set = 1, binding = 3) uniform image2D outDepth2; +layout (r16f, set = 1, binding = 4) uniform image2D outDepth3; +layout (r16f, set = 1, binding = 5) uniform image2D outDepth4; +layout (rgba8, set = 1, binding = 6) uniform image2D debugImage; + +#define SAMPLE_COUNT 60 + +// samples requires for hard shadow +#define HARD_SHADOW_SAMPLES 4 +// shadow fade at shadow edges +#define FADE_OUT_SAMPLES 8 + +layout (push_constant) uniform PushConstants { + float surfaceThickness; + float bilinearThreshold; + vec2 cameraTanHalfFOV; + + vec2 ndcToViewMul; + vec2 ndcToViewAdd; + + vec2 ndcToViewMul_x_PixelSize; + + float depthLinearizeMult; + float depthLinearizeAdd; + + float effectRadius; + float effectFalloffRange; + float denoiseBlurBeta; + + float radiusMultiplier; + float sampleDistributionPower; + float thinOccluderCompensation; + float finalValuePower; + float depthMipSamplingOffset; + int noiseIndex; + int isFinalDenoisePass; + + float sliceCount; + float stepsPerSliceCount; + + int debug; +} pushConstants; + void main() { const ivec2 screenPos = ivec2(gl_GlobalInvocationID.xy) * ivec2(2, 1); diff --git a/src/core/engine.cpp b/src/core/engine.cpp index 13096278..013dad6c 100644 --- a/src/core/engine.cpp +++ b/src/core/engine.cpp @@ -28,13 +28,20 @@ #include "src/renderer/environment/environment.h" #include "src/renderer/lighting/ambient_occlusion/ground_truth/ground_truth_ambient_occlusion.h" #include "src/renderer/lighting/shadows/cascaded_shadow_map.h" -#include "src/renderer/pipelines/deferred_mrt/deferred_mrt.h" -#include "src/renderer/pipelines/deferred_resolve/deferred_resolve.h" +#include "src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline.h" +#include "src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline_types.h" +#include "src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline.h" +#include "src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline_types.h" #include "src/renderer/pipelines/environment/environment_pipeline.h" -#include "src/renderer/pipelines/visibility_pass/visibility_pass.h" +#include "src/renderer/pipelines/environment/environment_pipeline_types.h" +#include "src/renderer/pipelines/visibility_pass/visibility_pass_pipeline.h" #include "src/renderer/pipelines/post_process/post_process_pipeline.h" #include "src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline.h" +#include "src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline_types.h" #include "src/renderer/pipelines/terrain/terrain_pipeline.h" +#include "src/renderer/pipelines/terrain/terrain_pipeline_types.h" +#include "src/renderer/pipelines/transparent_pipeline/transparent_pipeline_types.h" +#include "src/renderer/pipelines/visibility_pass/visibility_pass_pipeline_types.h" #include "src/util/file.h" #include "src/util/halton.h" @@ -199,7 +206,7 @@ void Engine::initRenderer() sceneDataBufferData[0] = DescriptorUniformData{.uniformBuffer = debugSceneDataBuffer, .allocSize = sizeof(SceneData)}; sceneDataDescriptorBuffer.setupData(context->device, sceneDataBufferData, FRAME_OVERLAP); - visibilityPassPipeline = new visibility_pass::VisibilityPassPipeline(*resourceManager); + visibilityPassPipeline = new visibility_pass_pipeline::VisibilityPassPipeline(*resourceManager); environmentPipeline = new environment_pipeline::EnvironmentPipeline(*resourceManager, environmentMap->getCubemapDescriptorSetLayout()); terrainPipeline = new terrain::TerrainPipeline(*resourceManager); deferredMrtPipeline = new deferred_mrt::DeferredMrtPipeline(*resourceManager); @@ -497,7 +504,7 @@ void Engine::draw(float deltaTime) // Updates Cascaded Shadow Map Properties cascadedShadowMap->update(mainLight, camera, currentFrameOverlap); - visibility_pass::VisibilityPassDrawInfo csmFrustumCullDrawInfo{ + visibility_pass_pipeline::VisibilityPassDrawInfo csmFrustumCullDrawInfo{ currentFrameOverlap, allRenderObjects, sceneDataDescriptorBuffer.getDescriptorBufferBindingInfo(), @@ -538,7 +545,7 @@ void Engine::draw(float deltaTime) environmentPipeline->draw(cmd, environmentPipelineDrawInfo); - visibility_pass::VisibilityPassDrawInfo deferredFrustumCullDrawInfo{ + visibility_pass_pipeline::VisibilityPassDrawInfo deferredFrustumCullDrawInfo{ currentFrameOverlap, allRenderObjects, sceneDataDescriptorBuffer.getDescriptorBufferBindingInfo(), diff --git a/src/core/engine.h b/src/core/engine.h index 49e5399d..3fdefa3e 100644 --- a/src/core/engine.h +++ b/src/core/engine.h @@ -20,8 +20,8 @@ #include "src/renderer/assets/asset_manager.h" #include "src/renderer/descriptor_buffer/descriptor_buffer_uniform.h" #include "src/renderer/lighting/directional_light.h" +#include "src/renderer/pipelines/post_process/post_process_pipeline_types.h" #include "src/renderer/pipelines/transparent_pipeline/transparent_pipeline.h" -#include "src/renderer/post_process/post_process_types.h" class ResourceManager; @@ -64,7 +64,7 @@ namespace deferred_mrt class DeferredMrtPipeline; } -namespace visibility_pass +namespace visibility_pass_pipeline { class VisibilityPassPipeline; } @@ -206,7 +206,7 @@ class Engine DirectionalLight mainLight{glm::normalize(glm::vec3(-0.8f, -0.6f, -0.6f)), 1.5f, glm::vec3(1.0f)}; int32_t environmentMapIndex{1}; - post_process::PostProcessType postProcessData{post_process::PostProcessType::Tonemapping | post_process::PostProcessType::Sharpening}; + post_process_pipeline::PostProcessType postProcessData{post_process_pipeline::PostProcessType::Tonemapping | post_process_pipeline::PostProcessType::Sharpening}; std::unordered_set activeMaps; std::unordered_set activeTerrains; @@ -217,7 +217,7 @@ class Engine std::vector hierarchicalDeletionQueue{}; private: // Pipelines - visibility_pass::VisibilityPassPipeline* visibilityPassPipeline{nullptr}; + visibility_pass_pipeline::VisibilityPassPipeline* visibilityPassPipeline{nullptr}; environment_pipeline::EnvironmentPipeline* environmentPipeline{nullptr}; terrain::TerrainPipeline* terrainPipeline{nullptr}; deferred_mrt::DeferredMrtPipeline* deferredMrtPipeline{nullptr}; diff --git a/src/renderer/imgui_wrapper.cpp b/src/renderer/imgui_wrapper.cpp index 0da4d065..1ded8527 100644 --- a/src/renderer/imgui_wrapper.cpp +++ b/src/renderer/imgui_wrapper.cpp @@ -15,6 +15,7 @@ #include "lighting/ambient_occlusion/ground_truth/ground_truth_ambient_occlusion.h" #include "lighting/shadows/cascaded_shadow_map.h" #include "lighting/shadows/shadow_constants.h" +#include "pipelines/post_process/post_process_pipeline_types.h" #include "src/core/engine.h" #include "src/core/time.h" #include "src/core/camera/free_camera.h" @@ -232,38 +233,38 @@ void ImguiWrapper::imguiInterface(Engine* engine) ImGui::Checkbox("Disable Jitter", &engine->bDisableJitter); } - static bool tonemapping = (engine->postProcessData & post_process::PostProcessType::Tonemapping) != - post_process::PostProcessType::None; + static bool tonemapping = (engine->postProcessData & post_process_pipeline::PostProcessType::Tonemapping) != + post_process_pipeline::PostProcessType::None; if (ImGui::CollapsingHeader("Tonemapping", ImGuiTreeNodeFlags_DefaultOpen)) { if (ImGui::Checkbox("Enable Tonemapping", &tonemapping)) { if (tonemapping) { - engine->postProcessData |= post_process::PostProcessType::Tonemapping; + engine->postProcessData |= post_process_pipeline::PostProcessType::Tonemapping; } else { - engine->postProcessData &= ~post_process::PostProcessType::Tonemapping; + engine->postProcessData &= ~post_process_pipeline::PostProcessType::Tonemapping; } } } if (ImGui::CollapsingHeader("Sharpening", ImGuiTreeNodeFlags_DefaultOpen)) { - static bool sharpening = (engine->postProcessData & post_process::PostProcessType::Sharpening) != - post_process::PostProcessType::None; + static bool sharpening = (engine->postProcessData & post_process_pipeline::PostProcessType::Sharpening) != + post_process_pipeline::PostProcessType::None; if (ImGui::Checkbox("Enable Sharpening", &sharpening)) { if (sharpening) { - engine->postProcessData |= post_process::PostProcessType::Sharpening; + engine->postProcessData |= post_process_pipeline::PostProcessType::Sharpening; } else { - engine->postProcessData &= ~post_process::PostProcessType::Sharpening; + engine->postProcessData &= ~post_process_pipeline::PostProcessType::Sharpening; } } } if (ImGui::CollapsingHeader("FXAA", ImGuiTreeNodeFlags_DefaultOpen)) { - static bool fxaa = (engine->postProcessData & post_process::PostProcessType::FXAA) != post_process::PostProcessType::None; + static bool fxaa = (engine->postProcessData & post_process_pipeline::PostProcessType::FXAA) != post_process_pipeline::PostProcessType::None; if (ImGui::Checkbox("Enable FXAA", &fxaa)) { if (fxaa) { - engine->postProcessData |= post_process::PostProcessType::FXAA; + engine->postProcessData |= post_process_pipeline::PostProcessType::FXAA; } else { - engine->postProcessData &= ~post_process::PostProcessType::FXAA; + engine->postProcessData &= ~post_process_pipeline::PostProcessType::FXAA; } } } @@ -1077,61 +1078,6 @@ void ImguiWrapper::imguiInterface(Engine* engine) ImGui::End(); if (ImGui::Begin("Discardable Debug")) { - if (transparentDebugTextureImguiId == VK_NULL_HANDLE) { - if (engine->transparentPipeline->debugImage.image != VK_NULL_HANDLE) { - transparentDebugTextureImguiId = ImGui_ImplVulkan_AddTexture( - engine->resourceManager->getDefaultSamplerNearest(), - engine->transparentPipeline->debugImage.imageView, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - } - } - - ImGui::BeginChild("TransparentDebugPreview", ImVec2(0, 0), false, ImGuiWindowFlags_None); - - if (transparentDebugTextureImguiId == VK_NULL_HANDLE) { - ImGui::TextColored(ImVec4(1.0f, 0.3f, 0.3f, 1.0f), "Debug texture not available."); - } - else { - // Calculate best fit size - float maxSize = ImGui::GetContentRegionAvail().x; - maxSize = glm::min(maxSize, 1024.0f); - - VkExtent3D imageExtent = engine->transparentPipeline->debugImage.imageExtent; - float width = std::min(maxSize, static_cast(imageExtent.width)); - float aspectRatio = static_cast(imageExtent.width) / static_cast(imageExtent.height); - float height = width / aspectRatio; - - ImGui::Image(reinterpret_cast(transparentDebugTextureImguiId), ImVec2(width, height)); - - if (ImGui::Button("Save Transparency Debug Image")) { - if (file::getOrCreateDirectory(file::imagesSavePath)) { - const std::filesystem::path path = file::imagesSavePath / "transparent_debug.png"; - - vk_helpers::saveImageRGBA16SFLOAT( - *engine->resourceManager, - *engine->immediate, - engine->transparentPipeline->debugImage, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_IMAGE_ASPECT_COLOR_BIT, - path.string().c_str(), - false - ); - - ImGui::OpenPopup("SaveConfirmation"); - } - } - - if (ImGui::BeginPopupModal("SaveConfirmation", NULL, ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::Text("Image saved to %s/gtao_debug.png", file::imagesSavePath.string().c_str()); - if (ImGui::Button("OK", ImVec2(120, 0))) { - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); - } - - ImGui::EndChild(); - } - if (postProcessOutputImguiId == VK_NULL_HANDLE) { if (engine->postProcessOutputBuffer.imageView != VK_NULL_HANDLE) { postProcessOutputImguiId = ImGui_ImplVulkan_AddTexture( diff --git a/src/renderer/imgui_wrapper.h b/src/renderer/imgui_wrapper.h index 92a203ee..942a1f19 100644 --- a/src/renderer/imgui_wrapper.h +++ b/src/renderer/imgui_wrapper.h @@ -85,8 +85,6 @@ class ImguiWrapper bool showGtaoDebugPreview = false; VkDescriptorSet aoDebugTextureImguiId{VK_NULL_HANDLE}; - VkDescriptorSet transparentDebugTextureImguiId{VK_NULL_HANDLE}; - VkDescriptorSet postProcessOutputImguiId{VK_NULL_HANDLE}; }; } diff --git a/src/renderer/pipelines/basic_compute/basic_compute_pipeline.cpp b/src/renderer/pipelines/basic_compute/basic_compute_pipeline.cpp index c66a0cc2..48d00cb7 100644 --- a/src/renderer/pipelines/basic_compute/basic_compute_pipeline.cpp +++ b/src/renderer/pipelines/basic_compute/basic_compute_pipeline.cpp @@ -4,15 +4,12 @@ #include "basic_compute_pipeline.h" -#include - +#include "basic_compute_pipeline_types.h" #include "src/renderer/renderer_constants.h" +#include "src/renderer/resource_manager.h" #include "src/renderer/vk_descriptors.h" -#include "src/renderer/vk_helpers.h" -#include "src/renderer/descriptor_buffer/descriptor_buffer_sampler.h" -#include "src/renderer/descriptor_buffer/descriptor_buffer_types.h" -namespace will_engine::basic_compute +namespace will_engine::basic_compute_pipeline { BasicComputePipeline::BasicComputePipeline(ResourceManager& resourceManager) : resourceManager(resourceManager) @@ -57,7 +54,7 @@ void BasicComputePipeline::setupDescriptors(const ComputeDescriptorInfo& descrip resourceManager.setupDescriptorBufferSampler(samplerDescriptorBuffer, imageDescriptor, 0); } -void BasicComputePipeline::draw(VkCommandBuffer cmd, ComputeDrawInfo drawInfo) const +void BasicComputePipeline::draw(VkCommandBuffer cmd, const ComputeDrawInfo drawInfo) const { vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); diff --git a/src/renderer/pipelines/basic_compute/basic_compute_pipeline.h b/src/renderer/pipelines/basic_compute/basic_compute_pipeline.h index 9393507f..c3c5c5fe 100644 --- a/src/renderer/pipelines/basic_compute/basic_compute_pipeline.h +++ b/src/renderer/pipelines/basic_compute/basic_compute_pipeline.h @@ -5,22 +5,19 @@ #ifndef BASIC_COMPUTE_PIPELINE_H #define BASIC_COMPUTE_PIPELINE_H -#include "src/renderer/resource_manager.h" -#include "src/renderer/vulkan_context.h" -#include "src/renderer/descriptor_buffer/descriptor_buffer_sampler.h" +#include +#include "src/renderer/descriptor_buffer/descriptor_buffer_sampler.h" -namespace will_engine::basic_compute -{ -struct ComputeDescriptorInfo +namespace will_engine { - VkImageView inputImage; -}; +class ResourceManager; +} -struct ComputeDrawInfo +namespace will_engine::basic_compute_pipeline { - VkExtent2D renderExtent; -}; +struct ComputeDrawInfo; +struct ComputeDescriptorInfo; class BasicComputePipeline { diff --git a/src/renderer/pipelines/basic_compute/basic_compute_pipeline_types.h b/src/renderer/pipelines/basic_compute/basic_compute_pipeline_types.h new file mode 100644 index 00000000..a6dfdf30 --- /dev/null +++ b/src/renderer/pipelines/basic_compute/basic_compute_pipeline_types.h @@ -0,0 +1,23 @@ +// +// Created by William on 2025-04-14. +// + +#ifndef BASIC_COMPUTE_PIPELINE_TYPES_H +#define BASIC_COMPUTE_PIPELINE_TYPES_H + +#include + +namespace will_engine::basic_compute_pipeline +{ +struct ComputeDescriptorInfo +{ + VkImageView inputImage; +}; + +struct ComputeDrawInfo +{ + VkExtent2D renderExtent; +}; +} + +#endif //BASIC_COMPUTE_PIPELINE_TYPES_H diff --git a/src/renderer/pipelines/basic_render/basic_render_pipeline.cpp b/src/renderer/pipelines/basic_render/basic_render_pipeline.cpp index d097a07d..44a7cd96 100644 --- a/src/renderer/pipelines/basic_render/basic_render_pipeline.cpp +++ b/src/renderer/pipelines/basic_render/basic_render_pipeline.cpp @@ -4,14 +4,15 @@ #include "basic_render_pipeline.h" -#include "volk/volk.h" +#include "basic_render_pipeline_types.h" #include "src/renderer/renderer_constants.h" +#include "src/renderer/resource_manager.h" #include "src/renderer/vk_descriptors.h" #include "src/renderer/vk_helpers.h" #include "src/renderer/vk_pipelines.h" -will_engine::basic_render::BasicRenderPipeline::BasicRenderPipeline(ResourceManager& resourceManager) : resourceManager(resourceManager) +will_engine::basic_render_pipeline::BasicRenderPipeline::BasicRenderPipeline(ResourceManager& resourceManager) : resourceManager(resourceManager) { DescriptorLayoutBuilder layoutBuilder; layoutBuilder.addBinding(0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); @@ -37,7 +38,7 @@ will_engine::basic_render::BasicRenderPipeline::BasicRenderPipeline(ResourceMana createPipeline(); } -will_engine::basic_render::BasicRenderPipeline::~BasicRenderPipeline() +will_engine::basic_render_pipeline::BasicRenderPipeline::~BasicRenderPipeline() { resourceManager.destroyPipeline(pipeline); resourceManager.destroyPipelineLayout(pipelineLayout); @@ -45,7 +46,7 @@ will_engine::basic_render::BasicRenderPipeline::~BasicRenderPipeline() resourceManager.destroyDescriptorBuffer(samplerDescriptorBuffer); } -void will_engine::basic_render::BasicRenderPipeline::setupDescriptors(const RenderDescriptorInfo& descriptorInfo) +void will_engine::basic_render_pipeline::BasicRenderPipeline::setupDescriptors(const RenderDescriptorInfo& descriptorInfo) { std::vector imageDescriptor; imageDescriptor.reserve(1); @@ -59,7 +60,7 @@ void will_engine::basic_render::BasicRenderPipeline::setupDescriptors(const Rend resourceManager.setupDescriptorBufferSampler(samplerDescriptorBuffer, imageDescriptor, 0); } -void will_engine::basic_render::BasicRenderPipeline::draw(VkCommandBuffer cmd, const RenderDrawInfo& drawInfo) const +void will_engine::basic_render_pipeline::BasicRenderPipeline::draw(VkCommandBuffer cmd, const RenderDrawInfo& drawInfo) const { if (drawInfo.drawImage == VK_NULL_HANDLE || drawInfo.depthImage == VK_NULL_HANDLE) { return; } constexpr VkClearValue colorClear = {.color = {0.0f, 0.0f, 0.0f, 0.0f}}; @@ -102,7 +103,6 @@ void will_engine::basic_render::BasicRenderPipeline::draw(VkCommandBuffer cmd, c vkCmdSetDescriptorBufferOffsetsEXT(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &imageBufferIndex, &ZERO_DEVICE_SIZE); vkCmdSetDescriptorBufferOffsetsEXT(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 1, 1, &sceneDataIndex, &sceneDataOffset); - const float time = static_cast(SDL_GetTicks()) / 1000.0f; RenderPushConstant push{}; push.currentFrame = drawInfo.currentFrame; vkCmdPushConstants(cmd, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(RenderPushConstant), &push); @@ -110,7 +110,7 @@ void will_engine::basic_render::BasicRenderPipeline::draw(VkCommandBuffer cmd, c vkCmdEndRendering(cmd); } -void will_engine::basic_render::BasicRenderPipeline::createPipeline() +void will_engine::basic_render_pipeline::BasicRenderPipeline::createPipeline() { resourceManager.destroyPipeline(pipeline); VkShaderModule vertShader = resourceManager.createShaderModule("shaders/basic/vertex.vert"); diff --git a/src/renderer/pipelines/basic_render/basic_render_pipeline.h b/src/renderer/pipelines/basic_render/basic_render_pipeline.h index e1362ea4..ff525c24 100644 --- a/src/renderer/pipelines/basic_render/basic_render_pipeline.h +++ b/src/renderer/pipelines/basic_render/basic_render_pipeline.h @@ -4,34 +4,20 @@ #ifndef BASIC_RENDER_PIPELINE_H #define BASIC_RENDER_PIPELINE_H -#include "src/renderer/resource_manager.h" -#include "src/renderer/vulkan_context.h" -#include "src/renderer/descriptor_buffer/descriptor_buffer_sampler.h" +#include -namespace will_engine::basic_render -{ -struct RenderDescriptorInfo -{ - VkSampler sampler{VK_NULL_HANDLE}; - VkImageView texture{VK_NULL_HANDLE}; -}; +#include "src/renderer/descriptor_buffer/descriptor_buffer_sampler.h" -struct RenderDrawInfo +namespace will_engine { - VkExtent2D renderExtent{}; - VkImageView drawImage{VK_NULL_HANDLE}; - VkImageView depthImage{VK_NULL_HANDLE}; - VkDescriptorBufferBindingInfoEXT sceneDataBinding{}; - VkDeviceSize sceneDataOffset{0}; - int32_t currentFrame{}; -}; +class ResourceManager; +} -struct RenderPushConstant +namespace will_engine::basic_render_pipeline { - int32_t currentFrame; -}; - +struct RenderDrawInfo; +struct RenderDescriptorInfo; class BasicRenderPipeline { diff --git a/src/renderer/pipelines/basic_render/basic_render_pipeline_types.h b/src/renderer/pipelines/basic_render/basic_render_pipeline_types.h new file mode 100644 index 00000000..7a94ed1a --- /dev/null +++ b/src/renderer/pipelines/basic_render/basic_render_pipeline_types.h @@ -0,0 +1,34 @@ +// +// Created by William on 2025-04-14. +// + +#ifndef BASIC_RENDER_PIPELINE_TYPES_H +#define BASIC_RENDER_PIPELINE_TYPES_H + +#include + +namespace will_engine::basic_render_pipeline +{ +struct RenderDescriptorInfo +{ + VkSampler sampler{VK_NULL_HANDLE}; + VkImageView texture{VK_NULL_HANDLE}; +}; + +struct RenderDrawInfo +{ + VkExtent2D renderExtent{}; + VkImageView drawImage{VK_NULL_HANDLE}; + VkImageView depthImage{VK_NULL_HANDLE}; + VkDescriptorBufferBindingInfoEXT sceneDataBinding{}; + VkDeviceSize sceneDataOffset{0}; + int32_t currentFrame{}; +}; + +struct RenderPushConstant +{ + int32_t currentFrame; +}; +} + +#endif //BASIC_RENDER_PIPELINE_TYPES_H diff --git a/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.cpp b/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.cpp new file mode 100644 index 00000000..bd935ca3 --- /dev/null +++ b/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.cpp @@ -0,0 +1,13 @@ +// +// Created by William on 2025-04-14. +// + +#include "contact_shadows_pipeline.h" + +namespace will_engine::contact_shadows_pipeline +{ +ContactShadowsPipeline::ContactShadowsPipeline(ResourceManager& resourceManager) : resourceManager(resourceManager) +{ + +} +} diff --git a/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.h b/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.h new file mode 100644 index 00000000..9a577fe4 --- /dev/null +++ b/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.h @@ -0,0 +1,23 @@ +// +// Created by William on 2025-04-14. +// + +#ifndef CONTACT_SHADOWS_H +#define CONTACT_SHADOWS_H + +class ResourceManager; + +namespace will_engine::contact_shadows_pipeline +{ + +class ContactShadowsPipeline { +public: + ContactShadowsPipeline(ResourceManager& resourceManager); + +private: + ResourceManager& resourceManager; +}; + +} + +#endif //CONTACT_SHADOWS_H diff --git a/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline_types.h b/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline_types.h new file mode 100644 index 00000000..1e2416cc --- /dev/null +++ b/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline_types.h @@ -0,0 +1,24 @@ +// +// Created by William on 2025-04-14. +// + +#ifndef CONTACT_SHADOW_TYPES_H +#define CONTACT_SHADOW_TYPES_H + +#include + +namespace will_engine::contact_shadows_pipeline +{ + +struct ContactShadowsPushConstants +{ + float surfaceThickness{0.005}; + float bilinearThreshold{0.02}; + float shadowContrast{4}; + int32_t ignoreEdgePixels{0}; + +}; + +} + +#endif //CONTACT_SHADOW_TYPES_H diff --git a/src/renderer/pipelines/deferred_mrt/deferred_mrt.h b/src/renderer/pipelines/deferred_mrt/deferred_mrt.h deleted file mode 100644 index aa5b9dbf..00000000 --- a/src/renderer/pipelines/deferred_mrt/deferred_mrt.h +++ /dev/null @@ -1,53 +0,0 @@ -// -// Created by William on 2025-01-24. -// - -#ifndef DEFERRED_MRT_H -#define DEFERRED_MRT_H - -#include - -#include "src/renderer/resource_manager.h" -#include "src/renderer/assets/render_object/render_object.h" - -namespace will_engine::deferred_mrt -{ -struct DeferredMrtDrawInfo -{ - bool bClearColor{true}; - int32_t currentFrameOverlap{0}; - glm::vec2 viewportExtents{RENDER_EXTENT_WIDTH, RENDER_EXTENT_HEIGHT}; - const std::vector& renderObjects{}; - VkImageView normalTarget{VK_NULL_HANDLE}; - VkImageView albedoTarget{VK_NULL_HANDLE}; - VkImageView pbrTarget{VK_NULL_HANDLE}; - VkImageView velocityTarget{VK_NULL_HANDLE}; - VkImageView depthTarget{VK_NULL_HANDLE}; - VkDescriptorBufferBindingInfoEXT sceneDataBinding{}; - VkDeviceSize sceneDataOffset{0}; -}; - -class DeferredMrtPipeline -{ -public: - explicit DeferredMrtPipeline(ResourceManager& resourceManager); - - ~DeferredMrtPipeline(); - - void draw(VkCommandBuffer cmd, const DeferredMrtDrawInfo& drawInfo) const; - - void reloadShaders() { createPipeline(); } - -private: - void createPipeline(); - -private: - ResourceManager& resourceManager; - - VkPipelineLayout pipelineLayout{VK_NULL_HANDLE}; - VkPipeline pipeline{VK_NULL_HANDLE}; -}; -} - - -#endif //DEFERRED_MRT_H diff --git a/src/renderer/pipelines/deferred_mrt/deferred_mrt.cpp b/src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline.cpp similarity index 96% rename from src/renderer/pipelines/deferred_mrt/deferred_mrt.cpp rename to src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline.cpp index d8916ea7..99191ea4 100644 --- a/src/renderer/pipelines/deferred_mrt/deferred_mrt.cpp +++ b/src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline.cpp @@ -2,15 +2,14 @@ // Created by William on 2025-01-24. // -#include "deferred_mrt.h" +#include "deferred_mrt_pipeline.h" #include -#include - -#include "volk/volk.h" +#include "deferred_mrt_pipeline_types.h" #include "src/renderer/renderer_constants.h" #include "src/renderer/resource_manager.h" +#include "src/renderer/assets/render_object/render_object.h" #include "src/renderer/assets/render_object/render_object_types.h" will_engine::deferred_mrt::DeferredMrtPipeline::DeferredMrtPipeline(ResourceManager& resourceManager) : resourceManager(resourceManager) @@ -101,7 +100,7 @@ void will_engine::deferred_mrt::DeferredMrtPipeline::draw(VkCommandBuffer cmd, c for (RenderObject* renderObject : drawInfo.renderObjects) { if (!renderObject->canDraw()) { continue; } - std::array descriptorBufferBindingInfos{ + std::array descriptorBufferBindingInfos{ drawInfo.sceneDataBinding, renderObject->getAddressesDescriptorBuffer().getDescriptorBufferBindingInfo(), renderObject->getTextureDescriptorBuffer().getDescriptorBufferBindingInfo(), @@ -111,7 +110,7 @@ void will_engine::deferred_mrt::DeferredMrtPipeline::draw(VkCommandBuffer cmd, c constexpr std::array indices{0, 1, 2}; - std::array offsets{ + std::array offsets{ drawInfo.sceneDataOffset, renderObject->getAddressesDescriptorBuffer().getDescriptorBufferSize() * drawInfo.currentFrameOverlap, ZERO_DEVICE_SIZE diff --git a/src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline.h b/src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline.h new file mode 100644 index 00000000..757c2e5e --- /dev/null +++ b/src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline.h @@ -0,0 +1,43 @@ +// +// Created by William on 2025-01-24. +// + +#ifndef DEFERRED_MRT_H +#define DEFERRED_MRT_H + +#include + +namespace will_engine +{ +class ResourceManager; +class RenderObject; +} + +namespace will_engine::deferred_mrt +{ +struct DeferredMrtDrawInfo; + +class DeferredMrtPipeline +{ +public: + explicit DeferredMrtPipeline(ResourceManager& resourceManager); + + ~DeferredMrtPipeline(); + + void draw(VkCommandBuffer cmd, const DeferredMrtDrawInfo& drawInfo) const; + + void reloadShaders() { createPipeline(); } + +private: + void createPipeline(); + +private: + ResourceManager& resourceManager; + + VkPipelineLayout pipelineLayout{VK_NULL_HANDLE}; + VkPipeline pipeline{VK_NULL_HANDLE}; +}; +} + + +#endif //DEFERRED_MRT_H diff --git a/src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline_types.h b/src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline_types.h new file mode 100644 index 00000000..cc4f8cac --- /dev/null +++ b/src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline_types.h @@ -0,0 +1,30 @@ +// +// Created by William on 2025-04-14. +// + +#ifndef DEFERRED_MRT_TYPES_H +#define DEFERRED_MRT_TYPES_H + +#include + +#include "src/renderer/renderer_constants.h" + +namespace will_engine::deferred_mrt +{ +struct DeferredMrtDrawInfo +{ + bool bClearColor{true}; + int32_t currentFrameOverlap{0}; + glm::vec2 viewportExtents{RENDER_EXTENT_WIDTH, RENDER_EXTENT_HEIGHT}; + const std::vector& renderObjects{}; + VkImageView normalTarget{VK_NULL_HANDLE}; + VkImageView albedoTarget{VK_NULL_HANDLE}; + VkImageView pbrTarget{VK_NULL_HANDLE}; + VkImageView velocityTarget{VK_NULL_HANDLE}; + VkImageView depthTarget{VK_NULL_HANDLE}; + VkDescriptorBufferBindingInfoEXT sceneDataBinding{}; + VkDeviceSize sceneDataOffset{0}; +}; +} // deferred_mrt::will_engine + +#endif //DEFERRED_MRT_TYPES_H diff --git a/src/renderer/pipelines/deferred_resolve/deferred_resolve.cpp b/src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline.cpp similarity index 97% rename from src/renderer/pipelines/deferred_resolve/deferred_resolve.cpp rename to src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline.cpp index faea01fe..1a92774d 100644 --- a/src/renderer/pipelines/deferred_resolve/deferred_resolve.cpp +++ b/src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline.cpp @@ -2,14 +2,15 @@ // Created by William on 2025-01-25. // -#include "deferred_resolve.h" +#include "deferred_resolve_pipeline.h" #include -#include "volk/volk.h" +#include "deferred_resolve_pipeline_types.h" #include "src/renderer/renderer_constants.h" #include "src/renderer/resource_manager.h" + will_engine::deferred_resolve::DeferredResolvePipeline::DeferredResolvePipeline(ResourceManager& resourceManager, VkDescriptorSetLayout environmentIBLLayout, VkDescriptorSetLayout cascadeUniformLayout, @@ -133,13 +134,7 @@ void will_engine::deferred_resolve::DeferredResolvePipeline::draw(VkCommandBuffe bindingInfos[4] = drawInfo.cascadeSamplerBinding; vkCmdBindDescriptorBuffersEXT(cmd, 5, bindingInfos); - constexpr std::array indices{ - 0, - 1, - 2, - 3, - 4 - }; + constexpr std::array indices{0, 1, 2, 3, 4}; const std::array offsets{ drawInfo.sceneDataOffset, ZERO_DEVICE_SIZE, diff --git a/src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline.h b/src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline.h new file mode 100644 index 00000000..a7f66eff --- /dev/null +++ b/src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline.h @@ -0,0 +1,53 @@ +// +// Created by William on 2025-01-25. +// + +#ifndef DEFERRED_RESOLVE_H +#define DEFERRED_RESOLVE_H + +#include + +#include "src/renderer/descriptor_buffer/descriptor_buffer_sampler.h" + +namespace will_engine +{ +class ResourceManager; +class DescriptorBuffer; +class DescriptorBufferSampler; +} + +namespace will_engine::deferred_resolve +{ +struct DeferredResolveDrawInfo; +struct DeferredResolveDescriptor; + +class DeferredResolvePipeline +{ +public: + explicit DeferredResolvePipeline(ResourceManager& resourceManager, VkDescriptorSetLayout environmentIBLLayout, + VkDescriptorSetLayout cascadeUniformLayout, + VkDescriptorSetLayout cascadeSamplerLayout); + + ~DeferredResolvePipeline(); + + void setupDescriptorBuffer(const DeferredResolveDescriptor& drawInfo); + + void draw(VkCommandBuffer cmd, const DeferredResolveDrawInfo& drawInfo) const; + + void reloadShaders() { createPipeline(); } + +private: + void createPipeline(); + +private: + ResourceManager& resourceManager; + + VkPipelineLayout pipelineLayout{VK_NULL_HANDLE}; + VkPipeline pipeline{VK_NULL_HANDLE}; + + DescriptorBufferSampler resolveDescriptorBuffer; +}; +} + + +#endif //DEFERRED_RESOLVE_H diff --git a/src/renderer/pipelines/deferred_resolve/deferred_resolve.h b/src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline_types.h similarity index 50% rename from src/renderer/pipelines/deferred_resolve/deferred_resolve.h rename to src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline_types.h index ada68554..e0e5fb10 100644 --- a/src/renderer/pipelines/deferred_resolve/deferred_resolve.h +++ b/src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline_types.h @@ -1,14 +1,11 @@ // -// Created by William on 2025-01-25. +// Created by William on 2025-04-14. // -#ifndef DEFERRED_RESOLVE_H -#define DEFERRED_RESOLVE_H -#include - -#include "src/renderer/resource_manager.h" -#include "src/renderer/descriptor_buffer/descriptor_buffer_sampler.h" +#ifndef DEFERRED_RESOLVE_TYPES_H +#define DEFERRED_RESOLVE_TYPES_H +#include namespace will_engine::deferred_resolve { @@ -50,33 +47,6 @@ struct DeferredResolveDrawInfo float nearPlane{1000.0f}; float farPlane{0.1f}; }; - -class DeferredResolvePipeline -{ -public: - explicit DeferredResolvePipeline(ResourceManager& resourceManager, VkDescriptorSetLayout environmentIBLLayout, VkDescriptorSetLayout cascadeUniformLayout, - VkDescriptorSetLayout cascadeSamplerLayout); - - ~DeferredResolvePipeline(); - - void setupDescriptorBuffer(const DeferredResolveDescriptor& drawInfo); - - void draw(VkCommandBuffer cmd, const DeferredResolveDrawInfo& drawInfo) const; - - void reloadShaders() { createPipeline(); } - -private: - void createPipeline(); - -private: - ResourceManager& resourceManager; - - VkPipelineLayout pipelineLayout{VK_NULL_HANDLE}; - VkPipeline pipeline{VK_NULL_HANDLE}; - - DescriptorBufferSampler resolveDescriptorBuffer; -}; } - -#endif //DEFERRED_RESOLVE_H +#endif //DEFERRED_RESOLVE_TYPES_H diff --git a/src/renderer/pipelines/environment/environment_pipeline.cpp b/src/renderer/pipelines/environment/environment_pipeline.cpp index 8fe74266..7acab329 100644 --- a/src/renderer/pipelines/environment/environment_pipeline.cpp +++ b/src/renderer/pipelines/environment/environment_pipeline.cpp @@ -4,9 +4,11 @@ #include "environment_pipeline.h" -#include "volk/volk.h" +#include "environment_pipeline_types.h" #include "src/renderer/renderer_constants.h" #include "src/renderer/resource_manager.h" +#include "src/renderer/vk_helpers.h" +#include "src/renderer/vk_pipelines.h" will_engine::environment_pipeline::EnvironmentPipeline::EnvironmentPipeline(ResourceManager& resourceManager, VkDescriptorSetLayout environmentMapLayout) : resourceManager(resourceManager) { diff --git a/src/renderer/pipelines/environment/environment_pipeline.h b/src/renderer/pipelines/environment/environment_pipeline.h index c734eaa7..9be9e7c6 100644 --- a/src/renderer/pipelines/environment/environment_pipeline.h +++ b/src/renderer/pipelines/environment/environment_pipeline.h @@ -4,27 +4,17 @@ #ifndef ENVIRONMENT_PIPELINE_H #define ENVIRONMENT_PIPELINE_H -#include -#include "src/renderer/resource_manager.h" +#include +namespace will_engine +{ +class ResourceManager; +} namespace will_engine::environment_pipeline { -struct EnvironmentDrawInfo -{ - bool bClearColor{false}; - VkImageView normalTarget{VK_NULL_HANDLE}; - VkImageView albedoTarget{VK_NULL_HANDLE}; - VkImageView pbrTarget{VK_NULL_HANDLE}; - VkImageView velocityTarget{VK_NULL_HANDLE}; - VkImageView depthTarget{VK_NULL_HANDLE}; - VkDescriptorBufferBindingInfoEXT sceneDataBinding{}; - VkDeviceSize sceneDataOffset; - VkDescriptorBufferBindingInfoEXT environmentMapBinding{}; - VkDeviceSize environmentMapOffset; -}; - +struct EnvironmentDrawInfo; class EnvironmentPipeline { diff --git a/src/renderer/pipelines/environment/environment_pipeline_types.h b/src/renderer/pipelines/environment/environment_pipeline_types.h new file mode 100644 index 00000000..cd86a5f6 --- /dev/null +++ b/src/renderer/pipelines/environment/environment_pipeline_types.h @@ -0,0 +1,27 @@ +// +// Created by William on 2025-04-14. +// + +#ifndef ENVIRONMENT_PIPELINE_TYPES_H +#define ENVIRONMENT_PIPELINE_TYPES_H + +#include + +namespace will_engine::environment_pipeline +{ +struct EnvironmentDrawInfo +{ + bool bClearColor{false}; + VkImageView normalTarget{VK_NULL_HANDLE}; + VkImageView albedoTarget{VK_NULL_HANDLE}; + VkImageView pbrTarget{VK_NULL_HANDLE}; + VkImageView velocityTarget{VK_NULL_HANDLE}; + VkImageView depthTarget{VK_NULL_HANDLE}; + VkDescriptorBufferBindingInfoEXT sceneDataBinding{}; + VkDeviceSize sceneDataOffset{}; + VkDescriptorBufferBindingInfoEXT environmentMapBinding{}; + VkDeviceSize environmentMapOffset{}; +}; +} + +#endif //ENVIRONMENT_PIPELINE_TYPES_H diff --git a/src/renderer/pipelines/post_process/post_process_pipeline.cpp b/src/renderer/pipelines/post_process/post_process_pipeline.cpp index 6810c0ed..a9fbb350 100644 --- a/src/renderer/pipelines/post_process/post_process_pipeline.cpp +++ b/src/renderer/pipelines/post_process/post_process_pipeline.cpp @@ -5,9 +5,12 @@ #include "post_process_pipeline.h" #include +#include -#include "volk/volk.h" +#include "post_process_pipeline_types.h" #include "src/renderer/renderer_constants.h" +#include "src/renderer/resource_manager.h" +#include "src/renderer/vk_descriptors.h" will_engine::post_process_pipeline::PostProcessPipeline::PostProcessPipeline(ResourceManager& resourceManager) : resourceManager(resourceManager) @@ -16,7 +19,8 @@ will_engine::post_process_pipeline::PostProcessPipeline::PostProcessPipeline(Res layoutBuilder.addBinding(0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); // taa resolve image layoutBuilder.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); // post process result - descriptorSetLayout = resourceManager.createDescriptorSetLayout(layoutBuilder, VK_SHADER_STAGE_COMPUTE_BIT, VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT); + descriptorSetLayout = resourceManager.createDescriptorSetLayout(layoutBuilder, VK_SHADER_STAGE_COMPUTE_BIT, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT); VkPushConstantRange pushConstants{}; pushConstants.offset = 0; diff --git a/src/renderer/pipelines/post_process/post_process_pipeline.h b/src/renderer/pipelines/post_process/post_process_pipeline.h index d28a2659..4b988303 100644 --- a/src/renderer/pipelines/post_process/post_process_pipeline.h +++ b/src/renderer/pipelines/post_process/post_process_pipeline.h @@ -4,33 +4,20 @@ #ifndef POST_PROCESS_PIPELINE_H #define POST_PROCESS_PIPELINE_H -#include "src/renderer/resource_manager.h" -#include "src/renderer/post_process/post_process_types.h" +#include -namespace will_engine::post_process_pipeline -{ -struct PostProcessDescriptor -{ - VkImageView inputImage; - VkImageView outputImage; - VkSampler sampler; -}; +#include "src/renderer/descriptor_buffer/descriptor_buffer_sampler.h" -struct PostProcessPushConstants +namespace will_engine { - int32_t width; - int32_t height; - uint32_t postProcessFlags; - int32_t padding; -}; +class ResourceManager; +} -struct PostProcessDrawInfo +namespace will_engine::post_process_pipeline { - post_process::PostProcessType postProcessFlags{post_process::PostProcessType::ALL}; - VkDescriptorBufferBindingInfoEXT sceneDataBinding{}; - VkDeviceSize sceneDataOffset{0}; -}; +struct PostProcessDrawInfo; +struct PostProcessDescriptor; class PostProcessPipeline { diff --git a/src/renderer/pipelines/post_process/post_process_pipeline_types.h b/src/renderer/pipelines/post_process/post_process_pipeline_types.h new file mode 100644 index 00000000..908abf66 --- /dev/null +++ b/src/renderer/pipelines/post_process/post_process_pipeline_types.h @@ -0,0 +1,70 @@ +// +// Created by William on 2025-04-14. +// + +#ifndef POST_PROCESS_PIPELINE_TYPES_H +#define POST_PROCESS_PIPELINE_TYPES_H + +#include + +namespace will_engine::post_process_pipeline +{ +enum class PostProcessType : uint32_t +{ + None = 0x00000000, + Tonemapping = 1 << 0, + Sharpening = 1 << 1, + FXAA = 1 << 2, + ALL = 0xFFFFFFFF +}; + +inline PostProcessType operator|(PostProcessType a, PostProcessType b) +{ + return static_cast(static_cast(a) | static_cast(b)); +} + +inline PostProcessType operator&(PostProcessType a, PostProcessType b) +{ + return static_cast(static_cast(a) & static_cast(b)); +} + +inline PostProcessType operator~(PostProcessType a) +{ + return static_cast(~static_cast(a)); +} + +inline PostProcessType& operator|=(PostProcessType& a, PostProcessType b) +{ + return a = a | b; +} + +inline PostProcessType& operator&=(PostProcessType& a, PostProcessType b) +{ + return a = a & b; +} + + +struct PostProcessDescriptor +{ + VkImageView inputImage; + VkImageView outputImage; + VkSampler sampler; +}; + +struct PostProcessPushConstants +{ + int32_t width; + int32_t height; + uint32_t postProcessFlags; + int32_t padding; +}; + +struct PostProcessDrawInfo +{ + PostProcessType postProcessFlags{PostProcessType::ALL}; + VkDescriptorBufferBindingInfoEXT sceneDataBinding{}; + VkDeviceSize sceneDataOffset{0}; +}; +} + +#endif //POST_PROCESS_PIPELINE_TYPES_H diff --git a/src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline.cpp b/src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline.cpp index 3b188961..2450bb59 100644 --- a/src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline.cpp +++ b/src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline.cpp @@ -4,8 +4,11 @@ #include "temporal_antialiasing_pipeline.h" -#include "volk/volk.h" +#include "temporal_antialiasing_pipeline_types.h" #include "src/renderer/renderer_constants.h" +#include "src/renderer/resource_manager.h" +#include "src/renderer/vk_descriptors.h" + will_engine::temporal_antialiasing_pipeline::TemporalAntialiasingPipeline::TemporalAntialiasingPipeline(ResourceManager& resourceManager) : resourceManager(resourceManager) diff --git a/src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline.h b/src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline.h index e3541bbc..9eb46d68 100644 --- a/src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline.h +++ b/src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline.h @@ -4,34 +4,20 @@ #ifndef TEMPORAL_ANTIALIASING_PIPELINE_H #define TEMPORAL_ANTIALIASING_PIPELINE_H -#include "src/renderer/resource_manager.h" +#include -namespace will_engine::temporal_antialiasing_pipeline -{ -struct TemporalAntialiasingPushConstants -{ - float blendValue; - int32_t taaDebug; -}; +#include "src/renderer/descriptor_buffer/descriptor_buffer_sampler.h" -struct TemporalAntialiasingDescriptor +namespace will_engine { - VkImageView drawImage; - VkImageView historyBuffer; - VkImageView depthBuffer; - VkImageView velocityBuffer; - VkImageView outputTarget; - VkSampler sampler; -}; +class ResourceManager; +} -struct TemporalAntialiasingDrawInfo +namespace will_engine::temporal_antialiasing_pipeline { - float blendValue{}; - int32_t debugMode{}; - VkDescriptorBufferBindingInfoEXT sceneDataBinding{}; - VkDeviceSize sceneDataOffset{0}; -}; +struct TemporalAntialiasingDrawInfo; +struct TemporalAntialiasingDescriptor; class TemporalAntialiasingPipeline { diff --git a/src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline_types.h b/src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline_types.h new file mode 100644 index 00000000..1bf125a6 --- /dev/null +++ b/src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline_types.h @@ -0,0 +1,37 @@ +// +// Created by William on 2025-04-14. +// + +#ifndef TEMPORAL_ANTIALIASING_PIPELINE_TYPES_H +#define TEMPORAL_ANTIALIASING_PIPELINE_TYPES_H + +#include + +namespace will_engine::temporal_antialiasing_pipeline +{ +struct TemporalAntialiasingPushConstants +{ + float blendValue{0.1f}; + int32_t taaDebug{0}; +}; + +struct TemporalAntialiasingDescriptor +{ + VkImageView drawImage{VK_NULL_HANDLE}; + VkImageView historyBuffer{VK_NULL_HANDLE}; + VkImageView depthBuffer{VK_NULL_HANDLE}; + VkImageView velocityBuffer{VK_NULL_HANDLE}; + VkImageView outputTarget{VK_NULL_HANDLE}; + VkSampler sampler{VK_NULL_HANDLE}; +}; + +struct TemporalAntialiasingDrawInfo +{ + float blendValue{}; + int32_t debugMode{}; + VkDescriptorBufferBindingInfoEXT sceneDataBinding{}; + VkDeviceSize sceneDataOffset{0}; +}; +} // temporal_antialiasing_pipeline + +#endif //TEMPORAL_ANTIALIASING_PIPELINE_TYPES_H diff --git a/src/renderer/pipelines/terrain/terrain_pipeline.cpp b/src/renderer/pipelines/terrain/terrain_pipeline.cpp index cd9eeebe..cb112f2f 100644 --- a/src/renderer/pipelines/terrain/terrain_pipeline.cpp +++ b/src/renderer/pipelines/terrain/terrain_pipeline.cpp @@ -4,9 +4,11 @@ #include "terrain_pipeline.h" -#include - -#include "src/renderer/renderer_constants.h" +#include "terrain_pipeline_types.h" +#include "src/core/game_object/terrain.h" +#include "src/renderer/resource_manager.h" +#include "src/renderer/vk_helpers.h" +#include "src/renderer/vk_pipelines.h" #include "src/renderer/terrain/terrain_chunk.h" #include "src/renderer/terrain/terrain_types.h" diff --git a/src/renderer/pipelines/terrain/terrain_pipeline.h b/src/renderer/pipelines/terrain/terrain_pipeline.h index 15b63813..9a86e0e4 100644 --- a/src/renderer/pipelines/terrain/terrain_pipeline.h +++ b/src/renderer/pipelines/terrain/terrain_pipeline.h @@ -4,35 +4,20 @@ #ifndef TERRAIN_PIPELINE_H #define TERRAIN_PIPELINE_H -#include "src/core/game_object/terrain.h" -#include "src/renderer/renderer_constants.h" -#include "src/renderer/resource_manager.h" +#include -namespace will_engine::terrain -{ -class TerrainChunk; +#include "src/renderer/descriptor_buffer/descriptor_buffer_sampler.h" -struct TerrainPushConstants +namespace will_engine { - float tessLevel; -}; +class ResourceManager; +} -struct TerrainDrawInfo +namespace will_engine::terrain { - bool bClearColor{true}; - bool bDrawLinesOnly{false}; - int32_t currentFrameOverlap{0}; - glm::vec2 viewportExtents{RENDER_EXTENT_WIDTH, RENDER_EXTENT_HEIGHT}; - const std::unordered_set& terrains; - VkImageView normalTarget{VK_NULL_HANDLE}; - VkImageView albedoTarget{VK_NULL_HANDLE}; - VkImageView pbrTarget{VK_NULL_HANDLE}; - VkImageView velocityTarget{VK_NULL_HANDLE}; - VkImageView depthTarget{VK_NULL_HANDLE}; - VkDescriptorBufferBindingInfoEXT sceneDataBinding{}; - VkDeviceSize sceneDataOffset{0}; -}; +struct TerrainDrawInfo; +class TerrainChunk; class TerrainPipeline { @@ -41,8 +26,6 @@ class TerrainPipeline ~TerrainPipeline(); - //void setupDescriptorBuffer(const TerrainDescriptor& descriptor); - void draw(VkCommandBuffer cmd, const TerrainDrawInfo& drawInfo) const; void reloadShaders() diff --git a/src/renderer/pipelines/terrain/terrain_pipeline_types.h b/src/renderer/pipelines/terrain/terrain_pipeline_types.h new file mode 100644 index 00000000..0feacbc9 --- /dev/null +++ b/src/renderer/pipelines/terrain/terrain_pipeline_types.h @@ -0,0 +1,43 @@ +// +// Created by William on 2025-04-14. +// + +#ifndef TERRAIN_PIPELINE_TYPES_H +#define TERRAIN_PIPELINE_TYPES_H + +#include +#include +#include + +#include "src/renderer/renderer_constants.h" + +namespace will_engine +{ +class ITerrain; +} + +namespace will_engine::terrain +{ +struct TerrainPushConstants +{ + float tessLevel; +}; + +struct TerrainDrawInfo +{ + bool bClearColor{true}; + bool bDrawLinesOnly{false}; + int32_t currentFrameOverlap{0}; + glm::vec2 viewportExtents{RENDER_EXTENT_WIDTH, RENDER_EXTENT_HEIGHT}; + const std::unordered_set& terrains; + VkImageView normalTarget{VK_NULL_HANDLE}; + VkImageView albedoTarget{VK_NULL_HANDLE}; + VkImageView pbrTarget{VK_NULL_HANDLE}; + VkImageView velocityTarget{VK_NULL_HANDLE}; + VkImageView depthTarget{VK_NULL_HANDLE}; + VkDescriptorBufferBindingInfoEXT sceneDataBinding{}; + VkDeviceSize sceneDataOffset{0}; +}; +} + +#endif //TERRAIN_PIPELINE_TYPES_H diff --git a/src/renderer/pipelines/transparent_pipeline/transparent_pipeline.cpp b/src/renderer/pipelines/transparent_pipeline/transparent_pipeline.cpp index d297b08d..e95902b7 100644 --- a/src/renderer/pipelines/transparent_pipeline/transparent_pipeline.cpp +++ b/src/renderer/pipelines/transparent_pipeline/transparent_pipeline.cpp @@ -5,9 +5,13 @@ #include "transparent_pipeline.h" #include -#include +#include "transparent_pipeline_types.h" #include "src/renderer/renderer_constants.h" +#include "src/renderer/resource_manager.h" +#include "src/renderer/vk_descriptors.h" +#include "src/renderer/vk_helpers.h" +#include "src/renderer/vk_pipelines.h" #include "src/renderer/assets/render_object/render_object.h" #include "src/renderer/assets/render_object/render_object_types.h" @@ -127,7 +131,6 @@ void TransparentPipeline::drawAccumulate(VkCommandBuffer cmd, const TransparentA constexpr VkClearValue revealageClear = {.color = {1.0f, 1.0f, 1.0f, 1.0f}}; - VkRenderingAttachmentInfo accumulationAttachment = vk_helpers::attachmentInfo(accumulationImage.imageView, &colorClear, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); VkRenderingAttachmentInfo revealageAttachment = vk_helpers::attachmentInfo(revealageImage.imageView, &revealageClear, diff --git a/src/renderer/pipelines/transparent_pipeline/transparent_pipeline.h b/src/renderer/pipelines/transparent_pipeline/transparent_pipeline.h index 2bebe982..a9062ac0 100644 --- a/src/renderer/pipelines/transparent_pipeline/transparent_pipeline.h +++ b/src/renderer/pipelines/transparent_pipeline/transparent_pipeline.h @@ -4,41 +4,22 @@ #ifndef TRANSPARENT_PIPELINE_H #define TRANSPARENT_PIPELINE_H -#include "src/renderer/imgui_wrapper.h" -#include "src/renderer/resource_manager.h" + +#include + +#include "src/renderer/vk_types.h" +#include "src/renderer/descriptor_buffer/descriptor_buffer_sampler.h" namespace will_engine { +class ResourceManager; class RenderObject; } namespace will_engine::transparent_pipeline { -struct TransparentsPushConstants -{ - int32_t bEnabled; - int32_t bReceivesShadows{true}; -}; - -struct TransparentAccumulateDrawInfo -{ - bool enabled{true}; - VkImageView depthTarget{VK_NULL_HANDLE}; - int32_t currentFrameOverlap{0}; - const std::vector& renderObjects{}; - VkDescriptorBufferBindingInfoEXT sceneDataBinding{}; - VkDeviceSize sceneDataOffset{0}; - VkDescriptorBufferBindingInfoEXT environmentIBLBinding{}; - VkDeviceSize environmentIBLOffset{0}; - VkDescriptorBufferBindingInfoEXT cascadeUniformBinding{}; - VkDeviceSize cascadeUniformOffset{0}; - VkDescriptorBufferBindingInfoEXT cascadeSamplerBinding{}; -}; - -struct TransparentCompositeDrawInfo -{ - VkImageView opaqueImage; -}; +struct TransparentCompositeDrawInfo; +struct TransparentAccumulateDrawInfo; class TransparentPipeline { @@ -82,8 +63,6 @@ class TransparentPipeline void createCompositePipeline(); - // todo: remove - friend void ImguiWrapper::imguiInterface(Engine* engine); }; } diff --git a/src/renderer/pipelines/transparent_pipeline/transparent_pipeline_types.h b/src/renderer/pipelines/transparent_pipeline/transparent_pipeline_types.h new file mode 100644 index 00000000..c5e7414a --- /dev/null +++ b/src/renderer/pipelines/transparent_pipeline/transparent_pipeline_types.h @@ -0,0 +1,46 @@ +// +// Created by William on 2025-04-14. +// + +#ifndef TRANSPARENT_PIPELINE_TYPES_H +#define TRANSPARENT_PIPELINE_TYPES_H + +#include + +#include "volk/volk.h" + +namespace will_engine +{ +class RenderObject; +} + +namespace will_engine::transparent_pipeline +{ +struct TransparentsPushConstants +{ + int32_t bEnabled{true}; + int32_t bReceivesShadows{true}; +}; + +struct TransparentAccumulateDrawInfo +{ + bool enabled{true}; + VkImageView depthTarget{VK_NULL_HANDLE}; + int32_t currentFrameOverlap{0}; + const std::vector& renderObjects{}; + VkDescriptorBufferBindingInfoEXT sceneDataBinding{}; + VkDeviceSize sceneDataOffset{0}; + VkDescriptorBufferBindingInfoEXT environmentIBLBinding{}; + VkDeviceSize environmentIBLOffset{0}; + VkDescriptorBufferBindingInfoEXT cascadeUniformBinding{}; + VkDeviceSize cascadeUniformOffset{0}; + VkDescriptorBufferBindingInfoEXT cascadeSamplerBinding{}; +}; + +struct TransparentCompositeDrawInfo +{ + VkImageView opaqueImage; +}; +} + +#endif //TRANSPARENT_PIPELINE_TYPES_H diff --git a/src/renderer/pipelines/visibility_pass/visibility_pass.cpp b/src/renderer/pipelines/visibility_pass/visibility_pass_pipeline.cpp similarity index 80% rename from src/renderer/pipelines/visibility_pass/visibility_pass.cpp rename to src/renderer/pipelines/visibility_pass/visibility_pass_pipeline.cpp index 528fce14..d2c3223c 100644 --- a/src/renderer/pipelines/visibility_pass/visibility_pass.cpp +++ b/src/renderer/pipelines/visibility_pass/visibility_pass_pipeline.cpp @@ -2,16 +2,17 @@ // Created by William on 2025-01-26. // -#include "visibility_pass.h" +#include "visibility_pass_pipeline.h" #include -#include - -#include "volk/volk.h" +#include +#include "visibility_pass_pipeline_types.h" +#include "src/renderer/resource_manager.h" +#include "src/renderer/vk_helpers.h" #include "src/renderer/assets/render_object/render_object.h" -will_engine::visibility_pass::VisibilityPassPipeline::VisibilityPassPipeline(ResourceManager& resourceManager) +will_engine::visibility_pass_pipeline::VisibilityPassPipeline::VisibilityPassPipeline(ResourceManager& resourceManager) : resourceManager(resourceManager) { VkDescriptorSetLayout layouts[3]; @@ -36,13 +37,13 @@ will_engine::visibility_pass::VisibilityPassPipeline::VisibilityPassPipeline(Res createPipeline(); } -will_engine::visibility_pass::VisibilityPassPipeline::~VisibilityPassPipeline() +will_engine::visibility_pass_pipeline::VisibilityPassPipeline::~VisibilityPassPipeline() { resourceManager.destroyPipeline(pipeline); resourceManager.destroyPipelineLayout(pipelineLayout); } -void will_engine::visibility_pass::VisibilityPassPipeline::draw(VkCommandBuffer cmd, const VisibilityPassDrawInfo& drawInfo) const +void will_engine::visibility_pass_pipeline::VisibilityPassPipeline::draw(VkCommandBuffer cmd, const VisibilityPassDrawInfo& drawInfo) const { VkDebugUtilsLabelEXT label = {}; label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; @@ -61,7 +62,8 @@ void will_engine::visibility_pass::VisibilityPassPipeline::draw(VkCommandBuffer for (RenderObject* renderObject : drawInfo.renderObjects) { if (drawInfo.bIsOpaque) { if (!renderObject->canDrawOpaque()) { continue; } - } else { + } + else { if (!renderObject->canDrawTransparent()) { continue; } } @@ -84,14 +86,16 @@ void will_engine::visibility_pass::VisibilityPassPipeline::draw(VkCommandBuffer vkCmdDispatch(cmd, static_cast(std::ceil(static_cast(renderObject->getOpaqueDrawIndirectCommandCount()) / 64.0f)), 1, 1); - vk_helpers::synchronizeUniform(cmd, renderObject->getOpaqueIndirectBuffer(drawInfo.currentFrameOverlap), VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_WRITE_BIT, VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT, VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT); + vk_helpers::synchronizeUniform(cmd, renderObject->getOpaqueIndirectBuffer(drawInfo.currentFrameOverlap), + VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_WRITE_BIT, VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT, + VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT); } vkCmdEndDebugUtilsLabelEXT(cmd); } -void will_engine::visibility_pass::VisibilityPassPipeline::createPipeline() +void will_engine::visibility_pass_pipeline::VisibilityPassPipeline::createPipeline() { resourceManager.destroyPipeline(pipeline); VkShaderModule computeShader = resourceManager.createShaderModule("shaders/visibility_pass.comp"); diff --git a/src/renderer/pipelines/visibility_pass/visibility_pass.h b/src/renderer/pipelines/visibility_pass/visibility_pass_pipeline.h similarity index 58% rename from src/renderer/pipelines/visibility_pass/visibility_pass.h rename to src/renderer/pipelines/visibility_pass/visibility_pass_pipeline.h index 071e7d1a..cd31dfcd 100644 --- a/src/renderer/pipelines/visibility_pass/visibility_pass.h +++ b/src/renderer/pipelines/visibility_pass/visibility_pass_pipeline.h @@ -4,32 +4,19 @@ #ifndef VISIBILITY_PASS_PIPELINE_H #define VISIBILITY_PASS_PIPELINE_H -#include "src/renderer/resource_manager.h" +#include namespace will_engine { +class ResourceManager; class RenderObject; } -namespace will_engine::visibility_pass +namespace will_engine::visibility_pass_pipeline { -struct VisibilityPassPushConstants -{ - int32_t enable{}; - int32_t shadowPass{}; -}; +struct VisibilityPassDrawInfo; -struct VisibilityPassDrawInfo -{ - int32_t currentFrameOverlap{0}; - const std::vector& renderObjects{}; - VkDescriptorBufferBindingInfoEXT sceneDataBinding{}; - VkDeviceSize sceneDataOffset{0}; - bool bEnableFrustumCulling{}; - bool bIsShadowPass{}; - bool bIsOpaque{}; -}; class VisibilityPassPipeline { diff --git a/src/renderer/pipelines/visibility_pass/visibility_pass_pipeline_types.h b/src/renderer/pipelines/visibility_pass/visibility_pass_pipeline_types.h new file mode 100644 index 00000000..0d65a5a6 --- /dev/null +++ b/src/renderer/pipelines/visibility_pass/visibility_pass_pipeline_types.h @@ -0,0 +1,36 @@ +// +// Created by William on 2025-04-14. +// + +#ifndef VISIBILITY_PASS_PIPELINE_TYPES_H +#define VISIBILITY_PASS_PIPELINE_TYPES_H + +#include +#include + +namespace will_engine +{ +class RenderObject; +} + +namespace will_engine::visibility_pass_pipeline +{ +struct VisibilityPassPushConstants +{ + int32_t enable{}; + int32_t shadowPass{}; +}; + +struct VisibilityPassDrawInfo +{ + int32_t currentFrameOverlap{0}; + const std::vector& renderObjects{}; + VkDescriptorBufferBindingInfoEXT sceneDataBinding{}; + VkDeviceSize sceneDataOffset{0}; + bool bEnableFrustumCulling{}; + bool bIsShadowPass{}; + bool bIsOpaque{}; +}; +} + +#endif //VISIBILITY_PASS_PIPELINE_TYPES_H diff --git a/src/renderer/post_process/post_process_types.h b/src/renderer/post_process/post_process_types.h deleted file mode 100644 index 1067a186..00000000 --- a/src/renderer/post_process/post_process_types.h +++ /dev/null @@ -1,41 +0,0 @@ -// -// Created by William on 2025-01-25. -// - -#ifndef POST_PROCESS_TYPES_H -#define POST_PROCESS_TYPES_H - -namespace post_process -{ -enum class PostProcessType : uint32_t -{ - None = 0x00000000, - Tonemapping = 1 << 0, - Sharpening = 1 << 1, - FXAA = 1 << 2, - ALL = 0xFFFFFFFF -}; - -inline PostProcessType operator|(PostProcessType a, PostProcessType b) { - return static_cast(static_cast(a) | static_cast(b)); -} - -inline PostProcessType operator&(PostProcessType a, PostProcessType b) { - return static_cast(static_cast(a) & static_cast(b)); -} - -inline PostProcessType operator~(PostProcessType a) { - return static_cast(~static_cast(a)); -} - -inline PostProcessType& operator|=(PostProcessType& a, PostProcessType b) { - return a = a | b; -} - -inline PostProcessType& operator&=(PostProcessType& a, PostProcessType b) { - return a = a & b; -} - -} - -#endif //POST_PROCESS_TYPES_H diff --git a/src/renderer/renderer_constants.h b/src/renderer/renderer_constants.h index c0d9611d..e77c7791 100644 --- a/src/renderer/renderer_constants.h +++ b/src/renderer/renderer_constants.h @@ -5,7 +5,8 @@ #ifndef RENDERER_CONSTANTS_H #define RENDERER_CONSTANTS_H #include - +namespace will_engine +{ constexpr int32_t FRAME_OVERLAP = 2; constexpr char ENGINE_NAME[] = "Will Engine"; constexpr bool USING_REVERSED_DEPTH_BUFFER = true; @@ -15,7 +16,6 @@ constexpr VkExtent2D RENDER_EXTENTS{2140, 1440}; //constexpr VkExtent2D RENDER_EXTENTS{3840, 2160}; constexpr float RENDER_EXTENT_WIDTH{RENDER_EXTENTS.width}; constexpr float RENDER_EXTENT_HEIGHT{RENDER_EXTENTS.height}; - constexpr VkFormat DRAW_FORMAT{VK_FORMAT_R16G16B16A16_SFLOAT}; constexpr VkFormat DEPTH_FORMAT{VK_FORMAT_D32_SFLOAT}; constexpr VkFormat VELOCITY_FORMAT{VK_FORMAT_R16G16_SFLOAT}; @@ -23,5 +23,7 @@ constexpr VkFormat NORMAL_FORMAT{VK_FORMAT_R16G16B16A16_SNORM}; // Be careful, environment map is in HDR format, so non-float formats wont work constexpr VkFormat ALBEDO_FORMAT{VK_FORMAT_R16G16B16A16_SFLOAT}; constexpr VkFormat PBR_FORMAT{VK_FORMAT_R8G8B8A8_UNORM}; +} + #endif // RENDERER_CONSTANTS_H From dc1f5ea9329173088f39ccbd13f86dd85beb3f7f Mon Sep 17 00:00:00 2001 From: Williscool13 Date: Mon, 14 Apr 2025 21:44:14 +0700 Subject: [PATCH 06/15] Contact shadow WIP1. --- assets/settings.willengine | 14 +++---- shaders/shadows/contact_shadow_pass.comp | 39 +++++-------------- .../contact_shadows_pipeline.cpp | 18 +++++++++ .../contact_shadow/contact_shadows_pipeline.h | 38 +++++++++++++++++- .../contact_shadows_pipeline_types.h | 18 ++++++++- 5 files changed, 88 insertions(+), 39 deletions(-) diff --git a/assets/settings.willengine b/assets/settings.willengine index 71153e5a..835596c9 100644 --- a/assets/settings.willengine +++ b/assets/settings.willengine @@ -19,15 +19,15 @@ }, "cameraProperties": { "position": [ - 62.77393341064453, - 81.94156646728516, - -87.18507385253906 + 66.781982421875, + 86.00987243652344, + -84.04193115234375 ], "rotation": [ - -0.06119464710354805, - -0.3182604908943176, - 0.020581098273396492, - -0.9458022713661194 + -0.011076380498707294, + 0.8989032506942749, + -0.02278568036854267, + -0.4374141991138458 ], "fov": 1.3089969158172607, "aspectRatio": 1.7777777910232544, diff --git a/shaders/shadows/contact_shadow_pass.comp b/shaders/shadows/contact_shadow_pass.comp index 61382fa9..3958df1e 100644 --- a/shaders/shadows/contact_shadow_pass.comp +++ b/shaders/shadows/contact_shadow_pass.comp @@ -7,12 +7,8 @@ layout(local_size_x = 64) in; // layout (std140, set = 0, binding = 0) uniform SceneData - scene.glsl layout (set = 1, binding = 0) uniform sampler2D depthImage; -layout (r16f, set = 1, binding = 1) uniform image2D outDepth0; -layout (r16f, set = 1, binding = 2) uniform image2D outDepth1; -layout (r16f, set = 1, binding = 3) uniform image2D outDepth2; -layout (r16f, set = 1, binding = 4) uniform image2D outDepth3; -layout (r16f, set = 1, binding = 5) uniform image2D outDepth4; -layout (rgba8, set = 1, binding = 6) uniform image2D debugImage; +layout (r8, set = 1, binding = 1) uniform image2D outDepth4; +layout (rgba8, set = 1, binding = 2) uniform image2D debugImage; #define SAMPLE_COUNT 60 @@ -24,32 +20,15 @@ layout (rgba8, set = 1, binding = 6) uniform image2D debugImage; layout (push_constant) uniform PushConstants { float surfaceThickness; float bilinearThreshold; - vec2 cameraTanHalfFOV; + float shadowContrast; + int bIgnoreEdgePixels; + int bUsePrecisionOffset; + int bBilinearSamplingOffsetMode; - vec2 ndcToViewMul; - vec2 ndcToViewAdd; + vec2 depthBounds; + int bUseEarlyOut; - vec2 ndcToViewMul_x_PixelSize; - - float depthLinearizeMult; - float depthLinearizeAdd; - - float effectRadius; - float effectFalloffRange; - float denoiseBlurBeta; - - float radiusMultiplier; - float sampleDistributionPower; - float thinOccluderCompensation; - float finalValuePower; - float depthMipSamplingOffset; - int noiseIndex; - int isFinalDenoisePass; - - float sliceCount; - float stepsPerSliceCount; - - int debug; + int debugMode; } pushConstants; diff --git a/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.cpp b/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.cpp index bd935ca3..a2cadf80 100644 --- a/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.cpp +++ b/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.cpp @@ -4,10 +4,28 @@ #include "contact_shadows_pipeline.h" +#include "src/renderer/resource_manager.h" + namespace will_engine::contact_shadows_pipeline { ContactShadowsPipeline::ContactShadowsPipeline(ResourceManager& resourceManager) : resourceManager(resourceManager) { +} + +ContactShadowsPipeline::~ContactShadowsPipeline() +{ + resourceManager.destroyImage(contactShadowImage); + resourceManager.destroyImage(debugImage); +} + +void ContactShadowsPipeline::draw(VkCommandBuffer cmd, const ContactShadowsDrawInfo& drawInfo) +{ + +} + +void ContactShadowsPipeline::createPipeline() +{ + } } diff --git a/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.h b/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.h index 9a577fe4..6fa50cde 100644 --- a/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.h +++ b/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.h @@ -5,16 +5,52 @@ #ifndef CONTACT_SHADOWS_H #define CONTACT_SHADOWS_H +#include + +#include "src/renderer/vk_types.h" +#include "src/renderer/descriptor_buffer/descriptor_buffer_sampler.h" + +namespace will_engine +{ class ResourceManager; +} namespace will_engine::contact_shadows_pipeline { +struct ContactShadowsDrawInfo; class ContactShadowsPipeline { public: - ContactShadowsPipeline(ResourceManager& resourceManager); + explicit ContactShadowsPipeline(ResourceManager& resourceManager); + + ~ContactShadowsPipeline(); + + void draw(VkCommandBuffer cmd, const ContactShadowsDrawInfo& drawInfo); + + void reloadShaders() + { + createPipeline(); + } + + AllocatedImage getContactShadowRenderTarget() const { return contactShadowImage; } + +private: + void createPipeline(); private: + VkDescriptorSetLayout descriptorSetLayout{VK_NULL_HANDLE}; + VkPipelineLayout pipelineLayout{VK_NULL_HANDLE}; + VkPipeline pipeline{VK_NULL_HANDLE}; + + VkFormat contactShadowFormat{VK_FORMAT_R8_UNORM}; + AllocatedImage contactShadowImage{VK_NULL_HANDLE}; + + DescriptorBufferSampler descriptorBufferSampler; + +private: // Debug + VkFormat debugFormat{VK_FORMAT_R8G8B8A8_SINT}; + AllocatedImage debugImage{VK_NULL_HANDLE}; + ResourceManager& resourceManager; }; diff --git a/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline_types.h b/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline_types.h index 1e2416cc..ac905596 100644 --- a/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline_types.h +++ b/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline_types.h @@ -5,20 +5,36 @@ #ifndef CONTACT_SHADOW_TYPES_H #define CONTACT_SHADOW_TYPES_H +#include #include namespace will_engine::contact_shadows_pipeline { +enum class ContactShadowsDebugMode : int32_t +{ + NONE = 0, +}; struct ContactShadowsPushConstants { float surfaceThickness{0.005}; float bilinearThreshold{0.02}; float shadowContrast{4}; - int32_t ignoreEdgePixels{0}; + int32_t bIgnoreEdgePixels{0}; + int32_t bUsePrecisionOffset{0}; + int32_t bBilinearSamplingOffsetMode{0}; + + glm::vec2 depthBounds{0, 1}; + int32_t bUseEarlyOut{0}; + + ContactShadowsDebugMode debugMode{ContactShadowsDebugMode::NONE}; }; +struct ContactShadowsDrawInfo +{ + +}; } #endif //CONTACT_SHADOW_TYPES_H From 90add80af24cff308c9cbe9f754a1d7d1e68a7ee Mon Sep 17 00:00:00 2001 From: Williscool13 Date: Tue, 15 Apr 2025 21:15:44 +0700 Subject: [PATCH 07/15] Restructure Files, SSCS skeleton WIP2. --- CMakeLists.txt | 76 ++++---- assets/settings.willengine | 16 +- shaders/shadows/contact_shadow_pass.comp | 4 +- src/core/engine.cpp | 52 +++--- src/core/engine.h | 17 +- src/renderer/assets/asset_manager.cpp | 2 +- .../assets/render_object/render_object.h | 1 - src/renderer/imgui_wrapper.cpp | 21 ++- .../basic_compute/basic_compute_pipeline.cpp | 0 .../basic_compute/basic_compute_pipeline.h | 0 .../basic_compute_pipeline_types.h | 0 .../basic_render/basic_render_pipeline.cpp | 0 .../basic_render/basic_render_pipeline.h | 0 .../basic_render_pipeline_types.h | 0 .../contact_shadows_pipeline.cpp | 31 ---- .../deferred_mrt/deferred_mrt_pipeline.cpp | 0 .../deferred_mrt/deferred_mrt_pipeline.h | 0 .../deferred_mrt_pipeline_types.h | 0 .../deferred_resolve_pipeline.cpp | 0 .../deferred_resolve_pipeline.h | 0 .../deferred_resolve_pipeline_types.h | 0 .../environment/environment_pipeline.cpp | 0 .../environment/environment_pipeline.h | 0 .../environment/environment_pipeline_types.h | 0 .../terrain/terrain_pipeline.cpp | 0 .../{ => geometry}/terrain/terrain_pipeline.h | 0 .../terrain/terrain_pipeline_types.h | 0 .../transparent_pipeline.cpp | 0 .../transparent_pipeline.h | 0 .../transparent_pipeline_types.h | 0 .../post_process/post_process_pipeline.cpp | 1 - .../post_process/post_process_pipeline.h | 4 +- .../post_process_pipeline_types.h | 0 .../temporal_antialiasing_pipeline.cpp | 1 - .../temporal_antialiasing_pipeline.h | 4 +- .../temporal_antialiasing_pipeline_types.h | 0 .../cascaded_shadow_map.cpp | 1 - .../cascaded_shadow_map.h | 0 .../cascaded_shadow_map}/shadow_constants.cpp | 0 .../cascaded_shadow_map}/shadow_constants.h | 0 .../cascaded_shadow_map}/shadow_types.h | 0 .../contact_shadows_pipeline.cpp | 165 ++++++++++++++++++ .../contact_shadow/contact_shadows_pipeline.h | 9 + .../contact_shadows_pipeline_types.h | 3 +- .../ambient_occlusion_types.h | 0 ...ound_truth_ambient_occlusion_pipeline.cpp} | 14 +- ...ground_truth_ambient_occlusion_pipeline.h} | 2 +- src/renderer/vk_helpers.cpp | 2 +- src/renderer/vk_helpers.h | 2 +- 49 files changed, 296 insertions(+), 132 deletions(-) rename src/renderer/pipelines/{ => basic}/basic_compute/basic_compute_pipeline.cpp (100%) rename src/renderer/pipelines/{ => basic}/basic_compute/basic_compute_pipeline.h (100%) rename src/renderer/pipelines/{ => basic}/basic_compute/basic_compute_pipeline_types.h (100%) rename src/renderer/pipelines/{ => basic}/basic_render/basic_render_pipeline.cpp (100%) rename src/renderer/pipelines/{ => basic}/basic_render/basic_render_pipeline.h (100%) rename src/renderer/pipelines/{ => basic}/basic_render/basic_render_pipeline_types.h (100%) delete mode 100644 src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.cpp rename src/renderer/pipelines/{ => geometry}/deferred_mrt/deferred_mrt_pipeline.cpp (100%) rename src/renderer/pipelines/{ => geometry}/deferred_mrt/deferred_mrt_pipeline.h (100%) rename src/renderer/pipelines/{ => geometry}/deferred_mrt/deferred_mrt_pipeline_types.h (100%) rename src/renderer/pipelines/{ => geometry}/deferred_resolve/deferred_resolve_pipeline.cpp (100%) rename src/renderer/pipelines/{ => geometry}/deferred_resolve/deferred_resolve_pipeline.h (100%) rename src/renderer/pipelines/{ => geometry}/deferred_resolve/deferred_resolve_pipeline_types.h (100%) rename src/renderer/pipelines/{ => geometry}/environment/environment_pipeline.cpp (100%) rename src/renderer/pipelines/{ => geometry}/environment/environment_pipeline.h (100%) rename src/renderer/pipelines/{ => geometry}/environment/environment_pipeline_types.h (100%) rename src/renderer/pipelines/{ => geometry}/terrain/terrain_pipeline.cpp (100%) rename src/renderer/pipelines/{ => geometry}/terrain/terrain_pipeline.h (100%) rename src/renderer/pipelines/{ => geometry}/terrain/terrain_pipeline_types.h (100%) rename src/renderer/pipelines/{ => geometry}/transparent_pipeline/transparent_pipeline.cpp (100%) rename src/renderer/pipelines/{ => geometry}/transparent_pipeline/transparent_pipeline.h (100%) rename src/renderer/pipelines/{ => geometry}/transparent_pipeline/transparent_pipeline_types.h (100%) rename src/renderer/pipelines/{ => post}/post_process/post_process_pipeline.cpp (99%) rename src/renderer/pipelines/{ => post}/post_process/post_process_pipeline.h (94%) rename src/renderer/pipelines/{ => post}/post_process/post_process_pipeline_types.h (100%) rename src/renderer/pipelines/{temporal_antialiasing_pipeline => post/temporal_antialiasing}/temporal_antialiasing_pipeline.cpp (99%) rename src/renderer/pipelines/{temporal_antialiasing_pipeline => post/temporal_antialiasing}/temporal_antialiasing_pipeline.h (93%) rename src/renderer/pipelines/{temporal_antialiasing_pipeline => post/temporal_antialiasing}/temporal_antialiasing_pipeline_types.h (100%) rename src/renderer/{lighting/shadows => pipelines/shadows/cascaded_shadow_map}/cascaded_shadow_map.cpp (99%) rename src/renderer/{lighting/shadows => pipelines/shadows/cascaded_shadow_map}/cascaded_shadow_map.h (100%) rename src/renderer/{lighting/shadows => pipelines/shadows/cascaded_shadow_map}/shadow_constants.cpp (100%) rename src/renderer/{lighting/shadows => pipelines/shadows/cascaded_shadow_map}/shadow_constants.h (100%) rename src/renderer/{lighting/shadows => pipelines/shadows/cascaded_shadow_map}/shadow_types.h (100%) create mode 100644 src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp rename src/renderer/pipelines/{ => shadows}/contact_shadow/contact_shadows_pipeline.h (84%) rename src/renderer/pipelines/{ => shadows}/contact_shadow/contact_shadows_pipeline_types.h (88%) rename src/renderer/{lighting/ambient_occlusion => pipelines/shadows/ground_truth_ambient_occlusion}/ambient_occlusion_types.h (100%) rename src/renderer/{lighting/ambient_occlusion/ground_truth/ground_truth_ambient_occlusion.cpp => pipelines/shadows/ground_truth_ambient_occlusion/ground_truth_ambient_occlusion_pipeline.cpp} (97%) rename src/renderer/{lighting/ambient_occlusion/ground_truth/ground_truth_ambient_occlusion.h => pipelines/shadows/ground_truth_ambient_occlusion/ground_truth_ambient_occlusion_pipeline.h} (97%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 60d0a94b..9a2c78d9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -156,31 +156,31 @@ set(RENDERER_SOURCES src/renderer/environment/environment.h src/renderer/environment/environment_constants.h src/renderer/environment/environment_types.h - src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline.cpp - src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline.h - src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline_types.h - src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline.cpp - src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline.h - src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline_types.h - src/renderer/pipelines/environment/environment_pipeline.cpp - src/renderer/pipelines/environment/environment_pipeline.h - src/renderer/pipelines/post_process/post_process_pipeline.cpp - src/renderer/pipelines/post_process/post_process_pipeline.h + src/renderer/pipelines/geometry/deferred_mrt/deferred_mrt_pipeline.cpp + src/renderer/pipelines/geometry/deferred_mrt/deferred_mrt_pipeline.h + src/renderer/pipelines/geometry/deferred_mrt/deferred_mrt_pipeline_types.h + src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline.cpp + src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline.h + src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline_types.h + src/renderer/pipelines/geometry/environment/environment_pipeline.cpp + src/renderer/pipelines/geometry/environment/environment_pipeline.h + src/renderer/pipelines/post/post_process/post_process_pipeline.cpp + src/renderer/pipelines/post/post_process/post_process_pipeline.h src/renderer/pipelines/visibility_pass/visibility_pass_pipeline.cpp src/renderer/pipelines/visibility_pass/visibility_pass_pipeline.h - src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline.cpp - src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline.h - src/renderer/pipelines/basic_compute/basic_compute_pipeline.cpp - src/renderer/pipelines/basic_compute/basic_compute_pipeline.h - src/renderer/pipelines/basic_render/basic_render_pipeline.cpp - src/renderer/pipelines/basic_render/basic_render_pipeline.h + src/renderer/pipelines/post/temporal_antialiasing/temporal_antialiasing_pipeline.cpp + src/renderer/pipelines/post/temporal_antialiasing/temporal_antialiasing_pipeline.h + src/renderer/pipelines/basic/basic_compute/basic_compute_pipeline.cpp + src/renderer/pipelines/basic/basic_compute/basic_compute_pipeline.h + src/renderer/pipelines/basic/basic_render/basic_render_pipeline.cpp + src/renderer/pipelines/basic/basic_render/basic_render_pipeline.h src/renderer/lighting/directional_light.h src/renderer/lighting/directional_light.cpp - src/renderer/lighting/shadows/cascaded_shadow_map.cpp - src/renderer/lighting/shadows/cascaded_shadow_map.h - src/renderer/lighting/shadows/shadow_constants.cpp - src/renderer/lighting/shadows/shadow_constants.h - src/renderer/lighting/shadows/shadow_types.h + src/renderer/pipelines/shadows/cascaded_shadow_map/cascaded_shadow_map.cpp + src/renderer/pipelines/shadows/cascaded_shadow_map/cascaded_shadow_map.h + src/renderer/pipelines/shadows/cascaded_shadow_map/shadow_constants.cpp + src/renderer/pipelines/shadows/cascaded_shadow_map/shadow_constants.h + src/renderer/pipelines/shadows/cascaded_shadow_map/shadow_types.h src/renderer/descriptor_buffer/descriptor_buffer.cpp src/renderer/descriptor_buffer/descriptor_buffer.h src/renderer/descriptor_buffer/descriptor_buffer_sampler.cpp @@ -223,8 +223,8 @@ set(TEMP_SOURCES src/util/noise_utils.h src/renderer/terrain/terrain_chunk.cpp src/renderer/terrain/terrain_chunk.h - src/renderer/pipelines/terrain/terrain_pipeline.cpp - src/renderer/pipelines/terrain/terrain_pipeline.h + src/renderer/pipelines/geometry/terrain/terrain_pipeline.cpp + src/renderer/pipelines/geometry/terrain/terrain_pipeline.h src/core/scene/map.cpp src/core/scene/map.h src/core/game_object/terrain.h @@ -242,23 +242,23 @@ set(TEMP_SOURCES src/renderer/assets/texture/texture_resource.cpp src/renderer/assets/texture/texture_resource.h src/renderer/assets/texture/texture_types.h - src/renderer/lighting/ambient_occlusion/ground_truth/ground_truth_ambient_occlusion.cpp - src/renderer/lighting/ambient_occlusion/ground_truth/ground_truth_ambient_occlusion.h - src/renderer/lighting/ambient_occlusion/ambient_occlusion_types.h - src/renderer/pipelines/transparent_pipeline/transparent_pipeline.cpp - src/renderer/pipelines/transparent_pipeline/transparent_pipeline.h + src/renderer/pipelines/shadows/ground_truth_ambient_occlusion/ground_truth_ambient_occlusion_pipeline.cpp + src/renderer/pipelines/shadows/ground_truth_ambient_occlusion/ground_truth_ambient_occlusion_pipeline.h + src/renderer/pipelines/shadows/ground_truth_ambient_occlusion/ambient_occlusion_types.h + src/renderer/pipelines/geometry/transparent_pipeline/transparent_pipeline.cpp + src/renderer/pipelines/geometry/transparent_pipeline/transparent_pipeline.h src/engine_constants.h - src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.cpp - src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.h - src/renderer/pipelines/contact_shadow/contact_shadows_pipeline_types.h + src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp + src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.h + src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h - src/renderer/pipelines/environment/environment_pipeline_types.h - src/renderer/pipelines/basic_render/basic_render_pipeline_types.h - src/renderer/pipelines/post_process/post_process_pipeline_types.h - src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline_types.h - src/renderer/pipelines/terrain/terrain_pipeline_types.h - src/renderer/pipelines/transparent_pipeline/transparent_pipeline_types.h - src/renderer/pipelines/basic_compute/basic_compute_pipeline_types.h + src/renderer/pipelines/geometry/environment/environment_pipeline_types.h + src/renderer/pipelines/basic/basic_render/basic_render_pipeline_types.h + src/renderer/pipelines/post/post_process/post_process_pipeline_types.h + src/renderer/pipelines/post/temporal_antialiasing/temporal_antialiasing_pipeline_types.h + src/renderer/pipelines/geometry/terrain/terrain_pipeline_types.h + src/renderer/pipelines/geometry/transparent_pipeline/transparent_pipeline_types.h + src/renderer/pipelines/basic/basic_compute/basic_compute_pipeline_types.h src/renderer/pipelines/visibility_pass/visibility_pass_pipeline_types.h ) diff --git a/assets/settings.willengine b/assets/settings.willengine index 835596c9..0e0e04db 100644 --- a/assets/settings.willengine +++ b/assets/settings.willengine @@ -19,20 +19,20 @@ }, "cameraProperties": { "position": [ - 66.781982421875, - 86.00987243652344, - -84.04193115234375 + 73.33120727539063, + 92.57952117919922, + -78.75091552734375 ], "rotation": [ - -0.011076380498707294, - 0.8989032506942749, - -0.02278568036854267, - -0.4374141991138458 + 0.014811295084655285, + 0.9218748211860657, + 0.03538305312395096, + -0.38558465242385864 ], "fov": 1.3089969158172607, "aspectRatio": 1.7777777910232544, "nearPlane": 1000.0, "farPlane": 0.10000000149011612 }, - "environmentMapIndex": 1 + "environmentMapIndex": 3 } \ No newline at end of file diff --git a/shaders/shadows/contact_shadow_pass.comp b/shaders/shadows/contact_shadow_pass.comp index 3958df1e..251509fa 100644 --- a/shaders/shadows/contact_shadow_pass.comp +++ b/shaders/shadows/contact_shadow_pass.comp @@ -7,7 +7,7 @@ layout(local_size_x = 64) in; // layout (std140, set = 0, binding = 0) uniform SceneData - scene.glsl layout (set = 1, binding = 0) uniform sampler2D depthImage; -layout (r8, set = 1, binding = 1) uniform image2D outDepth4; +layout (r8, set = 1, binding = 1) uniform image2D contactShadow; layout (rgba8, set = 1, binding = 2) uniform image2D debugImage; #define SAMPLE_COUNT 60 @@ -39,4 +39,6 @@ void main() { } + imageStore(debugImage, screenPos, vec4(1.0f, 0.0f, 0.0f, 1.0f)); + imageStore(contactShadow, screenPos, vec4(0.7f)); } diff --git a/src/core/engine.cpp b/src/core/engine.cpp index 013dad6c..d45956be 100644 --- a/src/core/engine.cpp +++ b/src/core/engine.cpp @@ -26,21 +26,21 @@ #include "src/renderer/assets/render_object/render_object.h" #include "src/renderer/descriptor_buffer/descriptor_buffer_uniform.h" #include "src/renderer/environment/environment.h" -#include "src/renderer/lighting/ambient_occlusion/ground_truth/ground_truth_ambient_occlusion.h" -#include "src/renderer/lighting/shadows/cascaded_shadow_map.h" -#include "src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline.h" -#include "src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline_types.h" -#include "src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline.h" -#include "src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline_types.h" -#include "src/renderer/pipelines/environment/environment_pipeline.h" -#include "src/renderer/pipelines/environment/environment_pipeline_types.h" +#include "../renderer/pipelines/shadows/cascaded_shadow_map/cascaded_shadow_map.h" +#include "src/renderer/pipelines/geometry/deferred_mrt/deferred_mrt_pipeline.h" +#include "src/renderer/pipelines/geometry/deferred_mrt/deferred_mrt_pipeline_types.h" +#include "src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline.h" +#include "src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline_types.h" +#include "src/renderer/pipelines/geometry/environment/environment_pipeline.h" +#include "src/renderer/pipelines/geometry/environment/environment_pipeline_types.h" +#include "src/renderer/pipelines/geometry/terrain/terrain_pipeline.h" +#include "src/renderer/pipelines/geometry/terrain/terrain_pipeline_types.h" +#include "src/renderer/pipelines/geometry/transparent_pipeline/transparent_pipeline_types.h" +#include "src/renderer/pipelines/post/post_process/post_process_pipeline.h" +#include "src/renderer/pipelines/post/temporal_antialiasing/temporal_antialiasing_pipeline.h" +#include "src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h" +#include "src/renderer/pipelines/shadows/ground_truth_ambient_occlusion/ground_truth_ambient_occlusion_pipeline.h" #include "src/renderer/pipelines/visibility_pass/visibility_pass_pipeline.h" -#include "src/renderer/pipelines/post_process/post_process_pipeline.h" -#include "src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline.h" -#include "src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline_types.h" -#include "src/renderer/pipelines/terrain/terrain_pipeline.h" -#include "src/renderer/pipelines/terrain/terrain_pipeline_types.h" -#include "src/renderer/pipelines/transparent_pipeline/transparent_pipeline_types.h" #include "src/renderer/pipelines/visibility_pass/visibility_pass_pipeline_types.h" #include "src/util/file.h" #include "src/util/halton.h" @@ -156,14 +156,13 @@ void Engine::init() startupProfiler.beginTimer("5Load Environment"); environmentMap->loadEnvironment("Overcast Sky", (envMapSource / "kloofendal_overcast_puresky_4k.hdr").string().c_str(), 2); - environmentMap->loadEnvironment("Wasteland", (envMapSource / "wasteland_clouds_puresky_4k.hdr").string().c_str(), 1); - environmentMap->loadEnvironment("Belfast Sunset", (envMapSource / "belfast_sunset_puresky_4k.hdr").string().c_str(), 0); - environmentMap->loadEnvironment("Rogland Clear Night", (envMapSource / "rogland_clear_night_4k.hdr").string().c_str(), 4); + // environmentMap->loadEnvironment("Wasteland", (envMapSource / "wasteland_clouds_puresky_4k.hdr").string().c_str(), 1); + // environmentMap->loadEnvironment("Belfast Sunset", (envMapSource / "belfast_sunset_puresky_4k.hdr").string().c_str(), 0); + // environmentMap->loadEnvironment("Rogland Clear Night", (envMapSource / "rogland_clear_night_4k.hdr").string().c_str(), 4); startupProfiler.endTimer("5Load Environment"); - startupProfiler.beginTimer("7Load CSM"); + cascadedShadowMap = new cascaded_shadows::CascadedShadowMap(*resourceManager); - startupProfiler.endTimer("7Load CSM"); if (engine_constants::useImgui) { imguiWrapper = new ImguiWrapper(*context, {window, swapchainImageFormat}); @@ -211,6 +210,7 @@ void Engine::initRenderer() terrainPipeline = new terrain::TerrainPipeline(*resourceManager); deferredMrtPipeline = new deferred_mrt::DeferredMrtPipeline(*resourceManager); ambientOcclusionPipeline = new ambient_occlusion::GroundTruthAmbientOcclusionPipeline(*resourceManager); + contactShadowsPipeline = new contact_shadows_pipeline::ContactShadowsPipeline(*resourceManager); deferredResolvePipeline = new deferred_resolve::DeferredResolvePipeline(*resourceManager, environmentMap->getDiffSpecMapDescriptorSetlayout(), cascadedShadowMap->getCascadedShadowMapUniformLayout(), cascadedShadowMap->getCascadedShadowMapSamplerLayout()); @@ -223,6 +223,7 @@ void Engine::initRenderer() ambientOcclusionPipeline->setupDepthPrefilterDescriptorBuffer(depthImage.imageView); ambientOcclusionPipeline->setupAmbientOcclusionDescriptorBuffer(normalRenderTarget.imageView); ambientOcclusionPipeline->setupSpatialFilteringDescriptorBuffer(); + contactShadowsPipeline->setupDescriptorBuffer(depthImage.imageView); const deferred_resolve::DeferredResolveDescriptor deferredResolveDescriptor{ normalRenderTarget.imageView, @@ -517,7 +518,7 @@ void Engine::draw(float deltaTime) cascadedShadowMap->draw(cmd, allRenderObjects, activeTerrains, currentFrameOverlap); - vk_helpers::clearColorImage(cmd, drawImage.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + vk_helpers::clearColorImage(cmd, VK_IMAGE_ASPECT_COLOR_BIT, drawImage.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); vk_helpers::transitionImage(cmd, depthImage.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_DEPTH_BIT); @@ -642,6 +643,12 @@ void Engine::draw(float deltaTime) }; ambientOcclusionPipeline->draw(cmd, gtaoDrawInfo); + contact_shadows_pipeline::ContactShadowsDrawInfo contactDrawInfo{ + sceneDataDescriptorBuffer.getDescriptorBufferBindingInfo(), + sceneDataDescriptorBuffer.getDescriptorBufferSize() * currentFrameOverlap + }; + contactShadowsPipeline->draw(cmd, contactDrawInfo); + const deferred_resolve::DeferredResolveDrawInfo deferredResolveDrawInfo{ deferredDebug, csmPcf, @@ -661,7 +668,9 @@ void Engine::draw(float deltaTime) transparent_pipeline::TransparentCompositeDrawInfo compositeDrawInfo{ drawImage.imageView }; - transparentPipeline->drawComposite(cmd, compositeDrawInfo); + if (!bHideTransparents) { + transparentPipeline->drawComposite(cmd, compositeDrawInfo); + } vk_helpers::transitionImage(cmd, drawImage.image, VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT); @@ -773,6 +782,7 @@ void Engine::cleanup() delete terrainPipeline; delete deferredMrtPipeline; delete ambientOcclusionPipeline; + delete contactShadowsPipeline; delete deferredResolvePipeline; delete temporalAntialiasingPipeline; delete transparentPipeline; diff --git a/src/core/engine.h b/src/core/engine.h index 3fdefa3e..8652a3ac 100644 --- a/src/core/engine.h +++ b/src/core/engine.h @@ -20,8 +20,9 @@ #include "src/renderer/assets/asset_manager.h" #include "src/renderer/descriptor_buffer/descriptor_buffer_uniform.h" #include "src/renderer/lighting/directional_light.h" -#include "src/renderer/pipelines/post_process/post_process_pipeline_types.h" -#include "src/renderer/pipelines/transparent_pipeline/transparent_pipeline.h" +#include "src/renderer/pipelines/post/post_process/post_process_pipeline_types.h" +#include "src/renderer/pipelines/geometry/transparent_pipeline/transparent_pipeline.h" +#include "src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.h" class ResourceManager; @@ -155,7 +156,6 @@ class Engine identifier::IdentifierManager* identifierManager = nullptr; environment::Environment* environmentMap{nullptr}; - cascaded_shadows::CascadedShadowMap* cascadedShadowMap{nullptr}; terrain::TerrainManager* terrainManager{nullptr}; ImguiWrapper* imguiWrapper = nullptr; @@ -185,7 +185,8 @@ class Engine bool bDrawTerrainLines{false}; bool bPausePhysics{true}; bool bDisableJitter{false}; - bool bRenderTransparents{true}; + bool bHideTransparents{true}; + bool bEnableGTAO{true}; void hotReloadShaders() const; @@ -218,13 +219,19 @@ class Engine private: // Pipelines visibility_pass_pipeline::VisibilityPassPipeline* visibilityPassPipeline{nullptr}; + environment_pipeline::EnvironmentPipeline* environmentPipeline{nullptr}; terrain::TerrainPipeline* terrainPipeline{nullptr}; deferred_mrt::DeferredMrtPipeline* deferredMrtPipeline{nullptr}; deferred_resolve::DeferredResolvePipeline* deferredResolvePipeline{nullptr}; + transparent_pipeline::TransparentPipeline* transparentPipeline{nullptr}; + + cascaded_shadows::CascadedShadowMap* cascadedShadowMap{nullptr}; + contact_shadows_pipeline::ContactShadowsPipeline* contactShadowsPipeline{nullptr}; ambient_occlusion::GroundTruthAmbientOcclusionPipeline* ambientOcclusionPipeline{nullptr}; + temporal_antialiasing_pipeline::TemporalAntialiasingPipeline* temporalAntialiasingPipeline{nullptr}; - transparent_pipeline::TransparentPipeline* transparentPipeline{nullptr}; + post_process_pipeline::PostProcessPipeline* postProcessPipeline{nullptr}; private: // Draw Resources diff --git a/src/renderer/assets/asset_manager.cpp b/src/renderer/assets/asset_manager.cpp index 683572b8..d36c38d0 100644 --- a/src/renderer/assets/asset_manager.cpp +++ b/src/renderer/assets/asset_manager.cpp @@ -69,7 +69,7 @@ std::vector will_engine::AssetManager::getAllTextures() std::ranges::transform(textures, std::back_inserter(result), [](const auto& pair) { return pair.second.get(); }); - return std::move(result); + return result; } will_engine::Texture* will_engine::AssetManager::getAnyTexture() const diff --git a/src/renderer/assets/render_object/render_object.h b/src/renderer/assets/render_object/render_object.h index 487a2cbd..6c92e820 100644 --- a/src/renderer/assets/render_object/render_object.h +++ b/src/renderer/assets/render_object/render_object.h @@ -12,7 +12,6 @@ #include "src/core/game_object/renderable.h" #include "src/renderer/renderer_constants.h" #include "src/renderer/resource_manager.h" -#include "src/renderer/pipelines/basic_compute/basic_compute_pipeline.h" namespace will_engine diff --git a/src/renderer/imgui_wrapper.cpp b/src/renderer/imgui_wrapper.cpp index 1ded8527..fedab212 100644 --- a/src/renderer/imgui_wrapper.cpp +++ b/src/renderer/imgui_wrapper.cpp @@ -12,10 +12,10 @@ #include "environment/environment.h" -#include "lighting/ambient_occlusion/ground_truth/ground_truth_ambient_occlusion.h" -#include "lighting/shadows/cascaded_shadow_map.h" -#include "lighting/shadows/shadow_constants.h" -#include "pipelines/post_process/post_process_pipeline_types.h" +#include "pipelines/post/post_process/post_process_pipeline_types.h" +#include "pipelines/shadows/cascaded_shadow_map/cascaded_shadow_map.h" +#include "pipelines/shadows/ground_truth_ambient_occlusion/ambient_occlusion_types.h" +#include "pipelines/shadows/ground_truth_ambient_occlusion/ground_truth_ambient_occlusion_pipeline.h" #include "src/core/engine.h" #include "src/core/time.h" #include "src/core/camera/free_camera.h" @@ -198,7 +198,15 @@ void ImguiWrapper::imguiInterface(Engine* engine) if (ImGui::Button("Hot-Reload Shaders")) { engine->hotReloadShaders(); } - ImGui::Checkbox("Enable Transparent Primitives", &engine->bRenderTransparents); + ImGui::Checkbox("Disable Transparent Primitives", &engine->bHideTransparents); + bool aoDisabled = engine->gtaoDebug == -1; + if (ImGui::Checkbox("Disable GTAO", &aoDisabled)) { + if (aoDisabled) { + engine->gtaoDebug = -1; + } else { + engine->gtaoDebug = 0; + } + } ImGui::Separator(); ImGui::Text("Main Directional Light"); float direction[3] = {engine->mainLight.direction.x, engine->mainLight.direction.y, engine->mainLight.direction.z}; @@ -211,7 +219,6 @@ void ImguiWrapper::imguiInterface(Engine* engine) } ImGui::DragFloat("Intensity", &engine->mainLight.intensity, 0.05f, 0.0f, 5.0f); - ImGui::Separator(); ImGui::Checkbox("Disable Physics", &engine->bPausePhysics); @@ -350,7 +357,7 @@ void ImguiWrapper::imguiInterface(Engine* engine) ImGui::Spacing(); ImGui::Text("Other Parameters"); ImGui::Separator(); - ImGui::InputInt("Debug Mode", >ao.debug); + ImGui::InputInt("Debug Mode", &engine->gtaoDebug); ImGui::Spacing(); if (ImGui::Button("Reset to Defaults")) { diff --git a/src/renderer/pipelines/basic_compute/basic_compute_pipeline.cpp b/src/renderer/pipelines/basic/basic_compute/basic_compute_pipeline.cpp similarity index 100% rename from src/renderer/pipelines/basic_compute/basic_compute_pipeline.cpp rename to src/renderer/pipelines/basic/basic_compute/basic_compute_pipeline.cpp diff --git a/src/renderer/pipelines/basic_compute/basic_compute_pipeline.h b/src/renderer/pipelines/basic/basic_compute/basic_compute_pipeline.h similarity index 100% rename from src/renderer/pipelines/basic_compute/basic_compute_pipeline.h rename to src/renderer/pipelines/basic/basic_compute/basic_compute_pipeline.h diff --git a/src/renderer/pipelines/basic_compute/basic_compute_pipeline_types.h b/src/renderer/pipelines/basic/basic_compute/basic_compute_pipeline_types.h similarity index 100% rename from src/renderer/pipelines/basic_compute/basic_compute_pipeline_types.h rename to src/renderer/pipelines/basic/basic_compute/basic_compute_pipeline_types.h diff --git a/src/renderer/pipelines/basic_render/basic_render_pipeline.cpp b/src/renderer/pipelines/basic/basic_render/basic_render_pipeline.cpp similarity index 100% rename from src/renderer/pipelines/basic_render/basic_render_pipeline.cpp rename to src/renderer/pipelines/basic/basic_render/basic_render_pipeline.cpp diff --git a/src/renderer/pipelines/basic_render/basic_render_pipeline.h b/src/renderer/pipelines/basic/basic_render/basic_render_pipeline.h similarity index 100% rename from src/renderer/pipelines/basic_render/basic_render_pipeline.h rename to src/renderer/pipelines/basic/basic_render/basic_render_pipeline.h diff --git a/src/renderer/pipelines/basic_render/basic_render_pipeline_types.h b/src/renderer/pipelines/basic/basic_render/basic_render_pipeline_types.h similarity index 100% rename from src/renderer/pipelines/basic_render/basic_render_pipeline_types.h rename to src/renderer/pipelines/basic/basic_render/basic_render_pipeline_types.h diff --git a/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.cpp b/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.cpp deleted file mode 100644 index a2cadf80..00000000 --- a/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// -// Created by William on 2025-04-14. -// - -#include "contact_shadows_pipeline.h" - -#include "src/renderer/resource_manager.h" - -namespace will_engine::contact_shadows_pipeline -{ -ContactShadowsPipeline::ContactShadowsPipeline(ResourceManager& resourceManager) : resourceManager(resourceManager) -{ - -} - -ContactShadowsPipeline::~ContactShadowsPipeline() -{ - resourceManager.destroyImage(contactShadowImage); - resourceManager.destroyImage(debugImage); -} - -void ContactShadowsPipeline::draw(VkCommandBuffer cmd, const ContactShadowsDrawInfo& drawInfo) -{ - -} - -void ContactShadowsPipeline::createPipeline() -{ - -} -} diff --git a/src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline.cpp b/src/renderer/pipelines/geometry/deferred_mrt/deferred_mrt_pipeline.cpp similarity index 100% rename from src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline.cpp rename to src/renderer/pipelines/geometry/deferred_mrt/deferred_mrt_pipeline.cpp diff --git a/src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline.h b/src/renderer/pipelines/geometry/deferred_mrt/deferred_mrt_pipeline.h similarity index 100% rename from src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline.h rename to src/renderer/pipelines/geometry/deferred_mrt/deferred_mrt_pipeline.h diff --git a/src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline_types.h b/src/renderer/pipelines/geometry/deferred_mrt/deferred_mrt_pipeline_types.h similarity index 100% rename from src/renderer/pipelines/deferred_mrt/deferred_mrt_pipeline_types.h rename to src/renderer/pipelines/geometry/deferred_mrt/deferred_mrt_pipeline_types.h diff --git a/src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline.cpp b/src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline.cpp similarity index 100% rename from src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline.cpp rename to src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline.cpp diff --git a/src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline.h b/src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline.h similarity index 100% rename from src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline.h rename to src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline.h diff --git a/src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline_types.h b/src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline_types.h similarity index 100% rename from src/renderer/pipelines/deferred_resolve/deferred_resolve_pipeline_types.h rename to src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline_types.h diff --git a/src/renderer/pipelines/environment/environment_pipeline.cpp b/src/renderer/pipelines/geometry/environment/environment_pipeline.cpp similarity index 100% rename from src/renderer/pipelines/environment/environment_pipeline.cpp rename to src/renderer/pipelines/geometry/environment/environment_pipeline.cpp diff --git a/src/renderer/pipelines/environment/environment_pipeline.h b/src/renderer/pipelines/geometry/environment/environment_pipeline.h similarity index 100% rename from src/renderer/pipelines/environment/environment_pipeline.h rename to src/renderer/pipelines/geometry/environment/environment_pipeline.h diff --git a/src/renderer/pipelines/environment/environment_pipeline_types.h b/src/renderer/pipelines/geometry/environment/environment_pipeline_types.h similarity index 100% rename from src/renderer/pipelines/environment/environment_pipeline_types.h rename to src/renderer/pipelines/geometry/environment/environment_pipeline_types.h diff --git a/src/renderer/pipelines/terrain/terrain_pipeline.cpp b/src/renderer/pipelines/geometry/terrain/terrain_pipeline.cpp similarity index 100% rename from src/renderer/pipelines/terrain/terrain_pipeline.cpp rename to src/renderer/pipelines/geometry/terrain/terrain_pipeline.cpp diff --git a/src/renderer/pipelines/terrain/terrain_pipeline.h b/src/renderer/pipelines/geometry/terrain/terrain_pipeline.h similarity index 100% rename from src/renderer/pipelines/terrain/terrain_pipeline.h rename to src/renderer/pipelines/geometry/terrain/terrain_pipeline.h diff --git a/src/renderer/pipelines/terrain/terrain_pipeline_types.h b/src/renderer/pipelines/geometry/terrain/terrain_pipeline_types.h similarity index 100% rename from src/renderer/pipelines/terrain/terrain_pipeline_types.h rename to src/renderer/pipelines/geometry/terrain/terrain_pipeline_types.h diff --git a/src/renderer/pipelines/transparent_pipeline/transparent_pipeline.cpp b/src/renderer/pipelines/geometry/transparent_pipeline/transparent_pipeline.cpp similarity index 100% rename from src/renderer/pipelines/transparent_pipeline/transparent_pipeline.cpp rename to src/renderer/pipelines/geometry/transparent_pipeline/transparent_pipeline.cpp diff --git a/src/renderer/pipelines/transparent_pipeline/transparent_pipeline.h b/src/renderer/pipelines/geometry/transparent_pipeline/transparent_pipeline.h similarity index 100% rename from src/renderer/pipelines/transparent_pipeline/transparent_pipeline.h rename to src/renderer/pipelines/geometry/transparent_pipeline/transparent_pipeline.h diff --git a/src/renderer/pipelines/transparent_pipeline/transparent_pipeline_types.h b/src/renderer/pipelines/geometry/transparent_pipeline/transparent_pipeline_types.h similarity index 100% rename from src/renderer/pipelines/transparent_pipeline/transparent_pipeline_types.h rename to src/renderer/pipelines/geometry/transparent_pipeline/transparent_pipeline_types.h diff --git a/src/renderer/pipelines/post_process/post_process_pipeline.cpp b/src/renderer/pipelines/post/post_process/post_process_pipeline.cpp similarity index 99% rename from src/renderer/pipelines/post_process/post_process_pipeline.cpp rename to src/renderer/pipelines/post/post_process/post_process_pipeline.cpp index a9fbb350..33c10344 100644 --- a/src/renderer/pipelines/post_process/post_process_pipeline.cpp +++ b/src/renderer/pipelines/post/post_process/post_process_pipeline.cpp @@ -7,7 +7,6 @@ #include #include -#include "post_process_pipeline_types.h" #include "src/renderer/renderer_constants.h" #include "src/renderer/resource_manager.h" #include "src/renderer/vk_descriptors.h" diff --git a/src/renderer/pipelines/post_process/post_process_pipeline.h b/src/renderer/pipelines/post/post_process/post_process_pipeline.h similarity index 94% rename from src/renderer/pipelines/post_process/post_process_pipeline.h rename to src/renderer/pipelines/post/post_process/post_process_pipeline.h index 4b988303..c55b8f46 100644 --- a/src/renderer/pipelines/post_process/post_process_pipeline.h +++ b/src/renderer/pipelines/post/post_process/post_process_pipeline.h @@ -7,6 +7,7 @@ #include +#include "post_process_pipeline_types.h" #include "src/renderer/descriptor_buffer/descriptor_buffer_sampler.h" namespace will_engine @@ -16,9 +17,6 @@ class ResourceManager; namespace will_engine::post_process_pipeline { -struct PostProcessDrawInfo; -struct PostProcessDescriptor; - class PostProcessPipeline { public: diff --git a/src/renderer/pipelines/post_process/post_process_pipeline_types.h b/src/renderer/pipelines/post/post_process/post_process_pipeline_types.h similarity index 100% rename from src/renderer/pipelines/post_process/post_process_pipeline_types.h rename to src/renderer/pipelines/post/post_process/post_process_pipeline_types.h diff --git a/src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline.cpp b/src/renderer/pipelines/post/temporal_antialiasing/temporal_antialiasing_pipeline.cpp similarity index 99% rename from src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline.cpp rename to src/renderer/pipelines/post/temporal_antialiasing/temporal_antialiasing_pipeline.cpp index 2450bb59..54521d61 100644 --- a/src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline.cpp +++ b/src/renderer/pipelines/post/temporal_antialiasing/temporal_antialiasing_pipeline.cpp @@ -4,7 +4,6 @@ #include "temporal_antialiasing_pipeline.h" -#include "temporal_antialiasing_pipeline_types.h" #include "src/renderer/renderer_constants.h" #include "src/renderer/resource_manager.h" #include "src/renderer/vk_descriptors.h" diff --git a/src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline.h b/src/renderer/pipelines/post/temporal_antialiasing/temporal_antialiasing_pipeline.h similarity index 93% rename from src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline.h rename to src/renderer/pipelines/post/temporal_antialiasing/temporal_antialiasing_pipeline.h index 9eb46d68..e52e3ba6 100644 --- a/src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline.h +++ b/src/renderer/pipelines/post/temporal_antialiasing/temporal_antialiasing_pipeline.h @@ -7,6 +7,7 @@ #include +#include "temporal_antialiasing_pipeline_types.h" #include "src/renderer/descriptor_buffer/descriptor_buffer_sampler.h" namespace will_engine @@ -16,9 +17,6 @@ class ResourceManager; namespace will_engine::temporal_antialiasing_pipeline { -struct TemporalAntialiasingDrawInfo; -struct TemporalAntialiasingDescriptor; - class TemporalAntialiasingPipeline { public: diff --git a/src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline_types.h b/src/renderer/pipelines/post/temporal_antialiasing/temporal_antialiasing_pipeline_types.h similarity index 100% rename from src/renderer/pipelines/temporal_antialiasing_pipeline/temporal_antialiasing_pipeline_types.h rename to src/renderer/pipelines/post/temporal_antialiasing/temporal_antialiasing_pipeline_types.h diff --git a/src/renderer/lighting/shadows/cascaded_shadow_map.cpp b/src/renderer/pipelines/shadows/cascaded_shadow_map/cascaded_shadow_map.cpp similarity index 99% rename from src/renderer/lighting/shadows/cascaded_shadow_map.cpp rename to src/renderer/pipelines/shadows/cascaded_shadow_map/cascaded_shadow_map.cpp index 0b2e6c45..2c40ad18 100644 --- a/src/renderer/lighting/shadows/cascaded_shadow_map.cpp +++ b/src/renderer/pipelines/shadows/cascaded_shadow_map/cascaded_shadow_map.cpp @@ -9,7 +9,6 @@ #include "volk/volk.h" #include "src/core/camera/camera.h" #include "src/renderer/renderer_constants.h" -#include "src/renderer/pipelines/terrain/terrain_pipeline.h" #include "src/renderer/assets/render_object/render_object_types.h" #include "src/renderer/terrain/terrain_chunk.h" #include "src/util/math_constants.h" diff --git a/src/renderer/lighting/shadows/cascaded_shadow_map.h b/src/renderer/pipelines/shadows/cascaded_shadow_map/cascaded_shadow_map.h similarity index 100% rename from src/renderer/lighting/shadows/cascaded_shadow_map.h rename to src/renderer/pipelines/shadows/cascaded_shadow_map/cascaded_shadow_map.h diff --git a/src/renderer/lighting/shadows/shadow_constants.cpp b/src/renderer/pipelines/shadows/cascaded_shadow_map/shadow_constants.cpp similarity index 100% rename from src/renderer/lighting/shadows/shadow_constants.cpp rename to src/renderer/pipelines/shadows/cascaded_shadow_map/shadow_constants.cpp diff --git a/src/renderer/lighting/shadows/shadow_constants.h b/src/renderer/pipelines/shadows/cascaded_shadow_map/shadow_constants.h similarity index 100% rename from src/renderer/lighting/shadows/shadow_constants.h rename to src/renderer/pipelines/shadows/cascaded_shadow_map/shadow_constants.h diff --git a/src/renderer/lighting/shadows/shadow_types.h b/src/renderer/pipelines/shadows/cascaded_shadow_map/shadow_types.h similarity index 100% rename from src/renderer/lighting/shadows/shadow_types.h rename to src/renderer/pipelines/shadows/cascaded_shadow_map/shadow_types.h diff --git a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp new file mode 100644 index 00000000..59c0ce63 --- /dev/null +++ b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp @@ -0,0 +1,165 @@ +// +// Created by William on 2025-04-14. +// + +#include "contact_shadows_pipeline.h" + +#include "contact_shadows_pipeline_types.h" +#include "src/renderer/resource_manager.h" + +namespace will_engine::contact_shadows_pipeline +{ +ContactShadowsPipeline::ContactShadowsPipeline(ResourceManager& resourceManager) : resourceManager(resourceManager) +{ + DescriptorLayoutBuilder layoutBuilder; + layoutBuilder.addBinding(0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); // MRT depth buffer + layoutBuilder.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); // ss contact shadows image + layoutBuilder.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); // debug image + + descriptorSetLayout = resourceManager.createDescriptorSetLayout(layoutBuilder, VK_SHADER_STAGE_COMPUTE_BIT, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT); + + VkPushConstantRange pushConstants{}; + pushConstants.offset = 0; + pushConstants.size = sizeof(ContactShadowsPushConstants); + pushConstants.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + + VkDescriptorSetLayout setLayouts[2]; + setLayouts[0] = resourceManager.getSceneDataLayout(); + setLayouts[1] = descriptorSetLayout; + + VkPipelineLayoutCreateInfo layoutInfo{}; + layoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + layoutInfo.pNext = nullptr; + layoutInfo.pSetLayouts = setLayouts; + layoutInfo.setLayoutCount = 2; + layoutInfo.pPushConstantRanges = &pushConstants; + layoutInfo.pushConstantRangeCount = 1; + + pipelineLayout = resourceManager.createPipelineLayout(layoutInfo); + createPipeline(); + + VkSamplerCreateInfo samplerInfo = {.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO}; + samplerInfo.magFilter = VK_FILTER_NEAREST; + samplerInfo.minFilter = VK_FILTER_NEAREST; + samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; + samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; + samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; + samplerInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK; + samplerInfo.anisotropyEnable = VK_FALSE; + samplerInfo.maxAnisotropy = 1.0f; + samplerInfo.compareEnable = VK_FALSE; + samplerInfo.minLod = 0.0f; + samplerInfo.maxLod = 0.0f; + + depthSampler = resourceManager.createSampler(samplerInfo); + + VkImageUsageFlags usage{}; + usage |= VK_IMAGE_USAGE_STORAGE_BIT; + usage |= VK_IMAGE_USAGE_SAMPLED_BIT; + usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; + + VkImageCreateInfo imgInfo = vk_helpers::imageCreateInfo(contactShadowFormat, usage, {RENDER_EXTENTS.width, RENDER_EXTENTS.height, 1}); + contactShadowImage = resourceManager.createImage(imgInfo); + + usage = {}; + usage |= VK_IMAGE_USAGE_STORAGE_BIT; + usage |= VK_IMAGE_USAGE_SAMPLED_BIT; + usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; + + imgInfo = vk_helpers::imageCreateInfo(debugFormat, usage, {RENDER_EXTENTS.width, RENDER_EXTENTS.height, 1}); + debugImage = resourceManager.createImage(imgInfo); + + descriptorBufferSampler = resourceManager.createDescriptorBufferSampler(descriptorSetLayout, 1); +} + +ContactShadowsPipeline::~ContactShadowsPipeline() +{ + resourceManager.destroyPipeline(pipeline); + resourceManager.destroyPipelineLayout(pipelineLayout); + resourceManager.destroyDescriptorSetLayout(descriptorSetLayout); + + resourceManager.destroySampler(depthSampler); + + resourceManager.destroyImage(contactShadowImage); + resourceManager.destroyImage(debugImage); + resourceManager.destroyDescriptorBuffer(descriptorBufferSampler); +} + +void ContactShadowsPipeline::setupDescriptorBuffer(const VkImageView& depthImageView) +{ + std::vector imageDescriptors{}; + imageDescriptors.reserve(3); + + imageDescriptors.push_back( + { + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + {depthSampler, depthImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}, + false + }); + imageDescriptors.push_back( + { + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + {VK_NULL_HANDLE, contactShadowImage.imageView, VK_IMAGE_LAYOUT_GENERAL}, + false + }); + imageDescriptors.push_back({ + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + {VK_NULL_HANDLE, debugImage.imageView, VK_IMAGE_LAYOUT_GENERAL}, + false + }); + + resourceManager.setupDescriptorBufferSampler(descriptorBufferSampler, imageDescriptors, 0); +} + +void ContactShadowsPipeline::draw(VkCommandBuffer cmd, const ContactShadowsDrawInfo& drawInfo) +{ + vk_helpers::transitionImage(cmd, debugImage.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_ASPECT_COLOR_BIT); + vk_helpers::clearColorImage(cmd, VK_IMAGE_ASPECT_COLOR_BIT, contactShadowImage.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL); + + ContactShadowsPushConstants push{}; + + vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); + vkCmdPushConstants(cmd, pipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(ContactShadowsPushConstants), &push); + + VkDescriptorBufferBindingInfoEXT bindingInfos[2] = {}; + bindingInfos[0] = drawInfo.sceneDataBinding; + bindingInfos[1] = descriptorBufferSampler.getDescriptorBufferBindingInfo(); + vkCmdBindDescriptorBuffersEXT(cmd, 2, bindingInfos); + + constexpr std::array indices{0, 1}; + const std::array offsets{drawInfo.sceneDataOffset, ZERO_DEVICE_SIZE}; + + vkCmdSetDescriptorBufferOffsetsEXT(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0, 2, indices.data(), offsets.data()); + + auto x = static_cast(std::ceil(RENDER_EXTENT_WIDTH / 16.0f)); + auto y = static_cast(std::ceil(RENDER_EXTENT_HEIGHT / 16.0f)); + vkCmdDispatch(cmd, x, y, 1); +} + +void ContactShadowsPipeline::createPipeline() +{ + resourceManager.destroyPipeline(pipeline); + VkShaderModule computeShader = resourceManager.createShaderModule("shaders/shadows/contact_shadow_pass.comp"); + + VkPipelineShaderStageCreateInfo stageInfo{}; + stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stageInfo.pNext = nullptr; + stageInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; + stageInfo.module = computeShader; + stageInfo.pName = "main"; + + VkComputePipelineCreateInfo pipelineInfo{}; + pipelineInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; + pipelineInfo.pNext = nullptr; + pipelineInfo.layout = pipelineLayout; + pipelineInfo.stage = stageInfo; + pipelineInfo.flags = VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT; + + pipeline = resourceManager.createComputePipeline(pipelineInfo); + resourceManager.destroyShaderModule(computeShader); + +} +} diff --git a/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.h b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.h similarity index 84% rename from src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.h rename to src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.h index 6fa50cde..53aecad2 100644 --- a/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline.h +++ b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.h @@ -7,6 +7,7 @@ #include +#include "src/renderer/imgui_wrapper.h" #include "src/renderer/vk_types.h" #include "src/renderer/descriptor_buffer/descriptor_buffer_sampler.h" @@ -25,6 +26,8 @@ class ContactShadowsPipeline { ~ContactShadowsPipeline(); + void setupDescriptorBuffer(const VkImageView& depthImageView); + void draw(VkCommandBuffer cmd, const ContactShadowsDrawInfo& drawInfo); void reloadShaders() @@ -42,6 +45,8 @@ class ContactShadowsPipeline { VkPipelineLayout pipelineLayout{VK_NULL_HANDLE}; VkPipeline pipeline{VK_NULL_HANDLE}; + VkSampler depthSampler{VK_NULL_HANDLE}; + VkFormat contactShadowFormat{VK_FORMAT_R8_UNORM}; AllocatedImage contactShadowImage{VK_NULL_HANDLE}; @@ -52,6 +57,10 @@ class ContactShadowsPipeline { AllocatedImage debugImage{VK_NULL_HANDLE}; ResourceManager& resourceManager; + +private: + //todo: remove + friend void ImguiWrapper::imguiInterface(Engine* engine); }; } diff --git a/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline_types.h b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h similarity index 88% rename from src/renderer/pipelines/contact_shadow/contact_shadows_pipeline_types.h rename to src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h index ac905596..a35cbf0c 100644 --- a/src/renderer/pipelines/contact_shadow/contact_shadows_pipeline_types.h +++ b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h @@ -33,7 +33,8 @@ struct ContactShadowsPushConstants struct ContactShadowsDrawInfo { - + VkDescriptorBufferBindingInfoEXT sceneDataBinding{}; + VkDeviceSize sceneDataOffset{0}; }; } diff --git a/src/renderer/lighting/ambient_occlusion/ambient_occlusion_types.h b/src/renderer/pipelines/shadows/ground_truth_ambient_occlusion/ambient_occlusion_types.h similarity index 100% rename from src/renderer/lighting/ambient_occlusion/ambient_occlusion_types.h rename to src/renderer/pipelines/shadows/ground_truth_ambient_occlusion/ambient_occlusion_types.h diff --git a/src/renderer/lighting/ambient_occlusion/ground_truth/ground_truth_ambient_occlusion.cpp b/src/renderer/pipelines/shadows/ground_truth_ambient_occlusion/ground_truth_ambient_occlusion_pipeline.cpp similarity index 97% rename from src/renderer/lighting/ambient_occlusion/ground_truth/ground_truth_ambient_occlusion.cpp rename to src/renderer/pipelines/shadows/ground_truth_ambient_occlusion/ground_truth_ambient_occlusion_pipeline.cpp index 55ee1b95..016cc3f1 100644 --- a/src/renderer/lighting/ambient_occlusion/ground_truth/ground_truth_ambient_occlusion.cpp +++ b/src/renderer/pipelines/shadows/ground_truth_ambient_occlusion/ground_truth_ambient_occlusion_pipeline.cpp @@ -2,13 +2,13 @@ // Created by William on 2025-03-23. // -#include "ground_truth_ambient_occlusion.h" +#include "ground_truth_ambient_occlusion_pipeline.h" #include #include "src/renderer/renderer_constants.h" #include "src/renderer/vk_descriptors.h" -#include "src/renderer/lighting/ambient_occlusion/ambient_occlusion_types.h" +#include "ambient_occlusion_types.h" will_engine::ambient_occlusion::GroundTruthAmbientOcclusionPipeline::GroundTruthAmbientOcclusionPipeline( ResourceManager& resourceManager) : resourceManager(resourceManager) @@ -370,6 +370,8 @@ void will_engine::ambient_occlusion::GroundTruthAmbientOcclusionPipeline::draw(V label.pLabelName = "GT Ambient Occlusion"; vkCmdBeginDebugUtilsLabelEXT(cmd, &label); + gtaoPush.debug = drawInfo.pushConstants.debug; + glm::mat4 projMatrix = drawInfo.camera->getProjMatrix(); gtaoPush.depthLinearizeMult = -projMatrix[3][2]; gtaoPush.depthLinearizeAdd = projMatrix[2][2]; @@ -390,7 +392,7 @@ void will_engine::ambient_occlusion::GroundTruthAmbientOcclusionPipeline::draw(V vk_helpers::transitionImage(cmd, debugImage.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_ASPECT_COLOR_BIT); - vk_helpers::clearColorImage(cmd, depthPrefilterImage.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL); + vk_helpers::clearColorImage(cmd, VK_IMAGE_ASPECT_COLOR_BIT, depthPrefilterImage.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL); // Depth Prefilter { vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, depthPrefilterPipeline); @@ -406,9 +408,9 @@ void will_engine::ambient_occlusion::GroundTruthAmbientOcclusionPipeline::draw(V vkCmdSetDescriptorBufferOffsetsEXT(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, depthPrefilterPipelineLayout, 0, 2, indices.data(), offsets.data()); - // shader only operates on 8,8 work groups, mip 0 will operate on 2x2 texels - auto x = static_cast(std::ceil(RENDER_EXTENT_WIDTH / 16.0f)); - auto y = static_cast(std::ceil(RENDER_EXTENT_HEIGHT / 16.0f)); + // shader only operates on 8,8 work groups, mip 0 will operate on 2x2 texels, so its 16x16 as expected + const auto x = static_cast(std::ceil(RENDER_EXTENT_WIDTH / 16.0f)); + const auto y = static_cast(std::ceil(RENDER_EXTENT_HEIGHT / 16.0f)); vkCmdDispatch(cmd, x, y, 1); } diff --git a/src/renderer/lighting/ambient_occlusion/ground_truth/ground_truth_ambient_occlusion.h b/src/renderer/pipelines/shadows/ground_truth_ambient_occlusion/ground_truth_ambient_occlusion_pipeline.h similarity index 97% rename from src/renderer/lighting/ambient_occlusion/ground_truth/ground_truth_ambient_occlusion.h rename to src/renderer/pipelines/shadows/ground_truth_ambient_occlusion/ground_truth_ambient_occlusion_pipeline.h index 9e96e565..192d26be 100644 --- a/src/renderer/lighting/ambient_occlusion/ground_truth/ground_truth_ambient_occlusion.h +++ b/src/renderer/pipelines/shadows/ground_truth_ambient_occlusion/ground_truth_ambient_occlusion_pipeline.h @@ -9,7 +9,7 @@ #include "src/renderer/imgui_wrapper.h" #include "src/renderer/resource_manager.h" -#include "src/renderer/lighting/ambient_occlusion/ambient_occlusion_types.h" +#include "ambient_occlusion_types.h" namespace will_engine::ambient_occlusion diff --git a/src/renderer/vk_helpers.cpp b/src/renderer/vk_helpers.cpp index 19ffca52..770aa956 100644 --- a/src/renderer/vk_helpers.cpp +++ b/src/renderer/vk_helpers.cpp @@ -265,7 +265,7 @@ VkDeviceSize will_engine::vk_helpers::getAlignedSize(const VkDeviceSize value, V return (value + alignment - 1) & ~(alignment - 1); } -void will_engine::vk_helpers::clearColorImage(VkCommandBuffer cmd, VkImage image, VkImageLayout srcLayout, VkImageLayout dstLayout, VkClearColorValue clearColor) +void will_engine::vk_helpers::clearColorImage(VkCommandBuffer cmd, VkImageAspectFlagBits aspectFlag, VkImage image, VkImageLayout srcLayout, VkImageLayout dstLayout, VkClearColorValue clearColor) { transitionImage(cmd, image, srcLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT); constexpr VkImageSubresourceRange range{ diff --git a/src/renderer/vk_helpers.h b/src/renderer/vk_helpers.h index 87c73eeb..9da7d68f 100644 --- a/src/renderer/vk_helpers.h +++ b/src/renderer/vk_helpers.h @@ -80,7 +80,7 @@ namespace vk_helpers */ VkDeviceSize getAlignedSize(VkDeviceSize value, VkDeviceSize alignment); - void clearColorImage(VkCommandBuffer cmd, VkImage image, VkImageLayout srcLayout, VkImageLayout dstLayout, + void clearColorImage(VkCommandBuffer cmd, VkImageAspectFlagBits aspectFlag, VkImage image, VkImageLayout srcLayout, VkImageLayout dstLayout, VkClearColorValue clearColor = {0.0f, 0.0f, 0.0f, 1.0f}); void transitionImage(VkCommandBuffer cmd, VkImage image, VkImageLayout currentLayout, VkImageLayout targetLayout, VkImageAspectFlags aspectMask); From ab21a89ec4f6450389bcdf3b6a12cbb3a11a2c1f Mon Sep 17 00:00:00 2001 From: Williscool13 Date: Wed, 16 Apr 2025 22:21:05 +0700 Subject: [PATCH 08/15] Contact shadow WIP3. --- assets/settings.willengine | 14 +- shaders/shadows/contact_shadow_pass.comp | 80 +++++++++-- src/renderer/imgui_wrapper.cpp | 14 +- src/renderer/imgui_wrapper.h | 2 +- .../contact_shadows_pipeline.cpp | 135 +++++++++++++++++- .../contact_shadow/contact_shadows_pipeline.h | 12 +- .../contact_shadows_pipeline_types.h | 21 +++ 7 files changed, 247 insertions(+), 31 deletions(-) diff --git a/assets/settings.willengine b/assets/settings.willengine index 0e0e04db..f9d165a7 100644 --- a/assets/settings.willengine +++ b/assets/settings.willengine @@ -19,15 +19,15 @@ }, "cameraProperties": { "position": [ - 73.33120727539063, - 92.57952117919922, - -78.75091552734375 + 92.20421600341797, + 80.86691284179688, + -30.049116134643555 ], "rotation": [ - 0.014811295084655285, - 0.9218748211860657, - 0.03538305312395096, - -0.38558465242385864 + -0.002585706301033497, + 0.0444491021335125, + 0.00012627220712602139, + 0.999008297920227 ], "fov": 1.3089969158172607, "aspectRatio": 1.7777777910232544, diff --git a/shaders/shadows/contact_shadow_pass.comp b/shaders/shadows/contact_shadow_pass.comp index 251509fa..4343903d 100644 --- a/shaders/shadows/contact_shadow_pass.comp +++ b/shaders/shadows/contact_shadow_pass.comp @@ -2,7 +2,9 @@ #include "scene.glsl" -layout(local_size_x = 64) in; +#define WAVE_SIZE 64 + +layout(local_size_x = WAVE_SIZE) in; // layout (std140, set = 0, binding = 0) uniform SceneData - scene.glsl @@ -22,23 +24,83 @@ layout (push_constant) uniform PushConstants { float bilinearThreshold; float shadowContrast; int bIgnoreEdgePixels; + int bUsePrecisionOffset; int bBilinearSamplingOffsetMode; - vec2 depthBounds; - int bUseEarlyOut; + int bUseEarlyOut; int debugMode; + ivec2 waveOffset; + vec4 lightCoordinate; + } pushConstants; +void ComputeWavefrontExtents(ivec2 waveOffset, vec4 lightCoordinate, ivec3 inGroupID, uint inGroupThreadID, +out vec2 outDeltaXY, out vec2 outPixelXY, out float outPixelDistance, out bool outMajorAxisX) +{ + ivec2 xy = inGroupID.yz * WAVE_SIZE + waveOffset.xy; + + // Integer light position / fractional component + vec2 light_xy = floor(lightCoordinate.xy) + 0.5; + vec2 light_xy_fraction = lightCoordinate.xy - light_xy; + bool reverse_direction = lightCoordinate.w > 0.0; + + ivec2 sign_xy = ivec2(sign(vec2(xy))); + bool horizontal = abs(xy.x + sign_xy.y) < abs(xy.y - sign_xy.x); + + ivec2 axis; + axis.x = horizontal ? (+sign_xy.y) : (0); + axis.y = horizontal ? (0) : (-sign_xy.x); + + // Apply wave offset + xy = axis * int(inGroupID.x) + xy; + vec2 xy_f = vec2(xy); + + // For interpolation to the light center, we only really care about the larger of the two axis + bool x_axis_major = abs(xy_f.x) > abs(xy_f.y); + float major_axis = x_axis_major ? xy_f.x : xy_f.y; + + float major_axis_start = abs(major_axis); + float major_axis_end = abs(major_axis) - float(WAVE_SIZE); + + float ma_light_frac = x_axis_major ? light_xy_fraction.x : light_xy_fraction.y; + ma_light_frac = major_axis > 0.0 ? -ma_light_frac : ma_light_frac; + + // Back in to screen direction + vec2 start_xy = xy_f + light_xy; + + // For the very inner most ring, we need to interpolate to a pixel centered UV, + // so the UV->pixel rounding doesn't skip output pixels + vec2 end_xy = mix(lightCoordinate.xy, start_xy, + (major_axis_end + ma_light_frac) / (major_axis_start + ma_light_frac)); + + // The major axis should be a round number + vec2 xy_delta = (start_xy - end_xy); + + // Inverse the read order when reverse direction is true + float thread_step = float(inGroupThreadID ^ (reverse_direction ? 0u : (WAVE_SIZE - 1u))); + + vec2 pixel_xy = mix(start_xy, end_xy, thread_step / float(WAVE_SIZE)); + float pixel_distance = major_axis_start - thread_step + ma_light_frac; + + outPixelXY = pixel_xy; + outPixelDistance = pixel_distance; + outDeltaXY = xy_delta; + outMajorAxisX = x_axis_major; +} + void main() { - const ivec2 screenPos = ivec2(gl_GlobalInvocationID.xy) * ivec2(2, 1); - if (screenPos.x > sceneData.renderTargetSize.x || screenPos.y > sceneData.renderTargetSize.y) { - return; - } + vec2 xy_delta; + vec2 pixel_xy; + float pixel_distance; + bool x_axis_major; + + ComputeWavefrontExtents(pushConstants.waveOffset, pushConstants.lightCoordinate, ivec3(gl_WorkGroupID), gl_LocalInvocationID.x, + xy_delta, pixel_xy, pixel_distance, x_axis_major); - imageStore(debugImage, screenPos, vec4(1.0f, 0.0f, 0.0f, 1.0f)); - imageStore(contactShadow, screenPos, vec4(0.7f)); + imageStore(debugImage, ivec2(pixel_xy), vec4(1.0f, 0.0f, 0.0f, 1.0f)); + imageStore(contactShadow, ivec2(pixel_xy), vec4(0.7f)); } diff --git a/src/renderer/imgui_wrapper.cpp b/src/renderer/imgui_wrapper.cpp index fedab212..2b4af1fb 100644 --- a/src/renderer/imgui_wrapper.cpp +++ b/src/renderer/imgui_wrapper.cpp @@ -1085,18 +1085,18 @@ void ImguiWrapper::imguiInterface(Engine* engine) ImGui::End(); if (ImGui::Begin("Discardable Debug")) { - if (postProcessOutputImguiId == VK_NULL_HANDLE) { - if (engine->postProcessOutputBuffer.imageView != VK_NULL_HANDLE) { - postProcessOutputImguiId = ImGui_ImplVulkan_AddTexture( + if (contactShadowsOutputImguiId == VK_NULL_HANDLE) { + if (engine->contactShadowsPipeline->contactShadowImage.imageView != VK_NULL_HANDLE) { + contactShadowsOutputImguiId = ImGui_ImplVulkan_AddTexture( engine->resourceManager->getDefaultSamplerNearest(), - engine->postProcessOutputBuffer.imageView, + engine->contactShadowsPipeline->contactShadowImage.imageView, VK_IMAGE_LAYOUT_GENERAL); } } ImGui::Separator(); - if (postProcessOutputImguiId == VK_NULL_HANDLE) { + if (contactShadowsOutputImguiId == VK_NULL_HANDLE) { ImGui::TextColored(ImVec4(1.0f, 0.3f, 0.3f, 1.0f), "Debug texture not available."); } else { @@ -1104,12 +1104,12 @@ void ImguiWrapper::imguiInterface(Engine* engine) float maxSize = ImGui::GetContentRegionAvail().x; maxSize = glm::min(maxSize, 1024.0f); - VkExtent3D imageExtent = engine->postProcessOutputBuffer.imageExtent; + VkExtent3D imageExtent = engine->contactShadowsPipeline->contactShadowImage.imageExtent; float width = std::min(maxSize, static_cast(imageExtent.width)); float aspectRatio = static_cast(imageExtent.width) / static_cast(imageExtent.height); float height = width / aspectRatio; - ImGui::Image(reinterpret_cast(postProcessOutputImguiId), ImVec2(width, height)); + ImGui::Image(reinterpret_cast(contactShadowsOutputImguiId), ImVec2(width, height)); } } diff --git a/src/renderer/imgui_wrapper.h b/src/renderer/imgui_wrapper.h index 942a1f19..a3aae996 100644 --- a/src/renderer/imgui_wrapper.h +++ b/src/renderer/imgui_wrapper.h @@ -85,7 +85,7 @@ class ImguiWrapper bool showGtaoDebugPreview = false; VkDescriptorSet aoDebugTextureImguiId{VK_NULL_HANDLE}; - VkDescriptorSet postProcessOutputImguiId{VK_NULL_HANDLE}; + VkDescriptorSet contactShadowsOutputImguiId{VK_NULL_HANDLE}; }; } diff --git a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp index 59c0ce63..1403bb7e 100644 --- a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp +++ b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp @@ -6,6 +6,8 @@ #include "contact_shadows_pipeline_types.h" #include "src/renderer/resource_manager.h" +#include "src/core/camera/camera.h" +#include "src/renderer/lighting/directional_light.h" namespace will_engine::contact_shadows_pipeline { @@ -17,7 +19,7 @@ ContactShadowsPipeline::ContactShadowsPipeline(ResourceManager& resourceManager) layoutBuilder.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); // debug image descriptorSetLayout = resourceManager.createDescriptorSetLayout(layoutBuilder, VK_SHADER_STAGE_COMPUTE_BIT, - VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT); + VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT); VkPushConstantRange pushConstants{}; pushConstants.offset = 0; @@ -134,9 +136,9 @@ void ContactShadowsPipeline::draw(VkCommandBuffer cmd, const ContactShadowsDrawI vkCmdSetDescriptorBufferOffsetsEXT(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0, 2, indices.data(), offsets.data()); - auto x = static_cast(std::ceil(RENDER_EXTENT_WIDTH / 16.0f)); - auto y = static_cast(std::ceil(RENDER_EXTENT_HEIGHT / 16.0f)); - vkCmdDispatch(cmd, x, y, 1); + + const auto x = static_cast(std::ceil(RENDER_EXTENT_WIDTH * RENDER_EXTENT_HEIGHT / static_cast(CONTACT_SHADOW_WAVE_COUNT))); + vkCmdDispatch(cmd, x, 1, 1); } void ContactShadowsPipeline::createPipeline() @@ -160,6 +162,131 @@ void ContactShadowsPipeline::createPipeline() pipeline = resourceManager.createComputePipeline(pipelineInfo); resourceManager.destroyShaderModule(computeShader); +} +DispatchList ContactShadowsPipeline::buildDispatchList(const Camera* camera, const DirectionalLight& mainLight) +{ + DispatchList result = {}; + + glm::vec4 lightProjection = camera->getViewProjMatrix() * glm::vec4(mainLight.getDirection(), 0.0f); + + // Floating point division in the shader has a practical limit for precision when the light is *very* far off screen (~1m pixels+) + // So when computing the light XY coordinate, use an adjusted w value to handle these extreme values + float xy_light_w = lightProjection[3]; + const float FP_limit = 0.000002f * static_cast(CONTACT_SHADOW_WAVE_COUNT); + + if (xy_light_w >= 0 && xy_light_w < FP_limit) xy_light_w = FP_limit; + else if (xy_light_w < 0 && xy_light_w > -FP_limit) xy_light_w = -FP_limit; + + // Need precise XY pixel coordinates of the light + result.LightCoordinate_Shader[0] = ((lightProjection[0] / xy_light_w) * +0.5f + 0.5f) * RENDER_EXTENT_WIDTH; + result.LightCoordinate_Shader[1] = ((lightProjection[1] / xy_light_w) * -0.5f + 0.5f) * RENDER_EXTENT_HEIGHT; + result.LightCoordinate_Shader[2] = lightProjection[3] == 0 ? 0 : (lightProjection[2] / lightProjection[3]); + result.LightCoordinate_Shader[3] = lightProjection[3] > 0 ? 1 : -1; + + int32_t light_xy[2] = {static_cast(result.LightCoordinate_Shader[0] + 0.5f), static_cast(result.LightCoordinate_Shader[1] + 0.5f)}; + + // Make the bounds inclusive, relative to the light + const int32_t biased_bounds[4] = + { + 0 - light_xy[0], + -static_cast(RENDER_EXTENT_HEIGHT - light_xy[1]), + static_cast(RENDER_EXTENT_WIDTH - light_xy[0]), + -(0 - light_xy[1]), + }; + + // Process 4 quadrants around the light center, + // They each form a rectangle with one corner on the light XY coordinate + // If the rectangle isn't square, it will need breaking in two on the larger axis + // 0 = bottom left, 1 = bottom right, 2 = top left, 2 = top right + for (int q = 0; q < 4; q++) { + // Quads 0 and 3 needs to be +1 vertically, 1 and 2 need to be +1 horizontally + bool vertical = q == 0 || q == 3; + + // Bounds relative to the quadrant + const int bounds[4] = + { + bend_max(0, ((q & 1) ? biased_bounds[0] : -biased_bounds[2])) / CONTACT_SHADOW_WAVE_COUNT, + bend_max(0, ((q & 2) ? biased_bounds[1] : -biased_bounds[3])) / CONTACT_SHADOW_WAVE_COUNT, + bend_max(0, (((q & 1) ? biased_bounds[2] : -biased_bounds[0]) + CONTACT_SHADOW_WAVE_COUNT * (vertical ? 1 : 2) - 1)) / CONTACT_SHADOW_WAVE_COUNT, + bend_max(0, (((q & 2) ? biased_bounds[3] : -biased_bounds[1]) + CONTACT_SHADOW_WAVE_COUNT * (vertical ? 2 : 1) - 1)) / CONTACT_SHADOW_WAVE_COUNT, + }; + + if ((bounds[2] - bounds[0]) > 0 && (bounds[3] - bounds[1]) > 0) { + int bias_x = (q == 2 || q == 3) ? 1 : 0; + int bias_y = (q == 1 || q == 3) ? 1 : 0; + + DispatchData& disp = result.Dispatch[result.DispatchCount++]; + + disp.WaveCount[0] = CONTACT_SHADOW_WAVE_COUNT; + disp.WaveCount[1] = bounds[2] - bounds[0]; + disp.WaveCount[2] = bounds[3] - bounds[1]; + disp.WaveOffset_Shader[0] = ((q & 1) ? bounds[0] : -bounds[2]) + bias_x; + disp.WaveOffset_Shader[1] = ((q & 2) ? -bounds[3] : bounds[1]) + bias_y; + + // We want the far corner of this quadrant relative to the light, + // as we need to know where the diagonal light ray intersects with the edge of the bounds + int axis_delta = +biased_bounds[0] - biased_bounds[1]; + if (q == 1) axis_delta = +biased_bounds[2] + biased_bounds[1]; + if (q == 2) axis_delta = -biased_bounds[0] - biased_bounds[3]; + if (q == 3) axis_delta = -biased_bounds[2] + biased_bounds[3]; + + axis_delta = (axis_delta + CONTACT_SHADOW_WAVE_COUNT - 1) / CONTACT_SHADOW_WAVE_COUNT; + + if (axis_delta > 0) { + DispatchData& disp2 = result.Dispatch[result.DispatchCount++]; + + // Take copy of current volume + disp2 = disp; + + if (q == 0) { + // Split on Y, split becomes -1 larger on x + disp2.WaveCount[2] = bend_min(disp.WaveCount[2], axis_delta); + disp.WaveCount[2] -= disp2.WaveCount[2]; + disp2.WaveOffset_Shader[1] = disp.WaveOffset_Shader[1] + disp.WaveCount[2]; + disp2.WaveOffset_Shader[0]--; + disp2.WaveCount[1]++; + } + if (q == 1) { + // Split on X, split becomes +1 larger on y + disp2.WaveCount[1] = bend_min(disp.WaveCount[1], axis_delta); + disp.WaveCount[1] -= disp2.WaveCount[1]; + disp2.WaveOffset_Shader[0] = disp.WaveOffset_Shader[0] + disp.WaveCount[1]; + disp2.WaveCount[2]++; + } + if (q == 2) { + // Split on X, split becomes -1 larger on y + disp2.WaveCount[1] = bend_min(disp.WaveCount[1], axis_delta); + disp.WaveCount[1] -= disp2.WaveCount[1]; + disp.WaveOffset_Shader[0] += disp2.WaveCount[1]; + disp2.WaveCount[2]++; + disp2.WaveOffset_Shader[1]--; + } + if (q == 3) { + // Split on Y, split becomes +1 larger on x + disp2.WaveCount[2] = bend_min(disp.WaveCount[2], axis_delta); + disp.WaveCount[2] -= disp2.WaveCount[2]; + disp.WaveOffset_Shader[1] += disp2.WaveCount[2]; + disp2.WaveCount[1]++; + } + + // Remove if too small + if (disp2.WaveCount[1] <= 0 || disp2.WaveCount[2] <= 0) { + disp2 = result.Dispatch[--result.DispatchCount]; + } + if (disp.WaveCount[1] <= 0 || disp.WaveCount[2] <= 0) { + disp = result.Dispatch[--result.DispatchCount]; + } + } + } + } + + // Scale the shader values by the wave count, the shader expects this + for (int i = 0; i < result.DispatchCount; i++) { + result.Dispatch[i].WaveOffset_Shader[0] *= CONTACT_SHADOW_WAVE_COUNT; + result.Dispatch[i].WaveOffset_Shader[1] *= CONTACT_SHADOW_WAVE_COUNT; + } + + return result; } } diff --git a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.h b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.h index 53aecad2..a6cd4090 100644 --- a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.h +++ b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.h @@ -7,19 +7,20 @@ #include +#include "contact_shadows_pipeline_types.h" #include "src/renderer/imgui_wrapper.h" #include "src/renderer/vk_types.h" #include "src/renderer/descriptor_buffer/descriptor_buffer_sampler.h" + namespace will_engine { -class ResourceManager; +class Camera; +class DirectionalLight; } namespace will_engine::contact_shadows_pipeline { -struct ContactShadowsDrawInfo; - class ContactShadowsPipeline { public: explicit ContactShadowsPipeline(ResourceManager& resourceManager); @@ -40,6 +41,11 @@ class ContactShadowsPipeline { private: void createPipeline(); + static static DispatchList buildDispatchList(const Camera* camera, const DirectionalLight& mainLight); + + static int32_t bend_min(const int32_t a, const int32_t b) { return a > b ? b : a; } + static int32_t bend_max(const int32_t a, const int32_t b) { return a > b ? a : b; } + private: VkDescriptorSetLayout descriptorSetLayout{VK_NULL_HANDLE}; VkPipelineLayout pipelineLayout{VK_NULL_HANDLE}; diff --git a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h index a35cbf0c..f1bb678d 100644 --- a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h +++ b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h @@ -10,11 +10,29 @@ namespace will_engine::contact_shadows_pipeline { + +static constexpr int32_t CONTACT_SHADOW_WAVE_COUNT = 64; + enum class ContactShadowsDebugMode : int32_t { NONE = 0, }; +struct DispatchData +{ + int32_t WaveCount[3]; // Compute Shader Dispatch(X,Y,Z) wave counts X/Y/Z + int32_t WaveOffset_Shader[2]; // This value is passed in to shader. It will be different for each dispatch +}; + +struct DispatchList +{ + float LightCoordinate_Shader[4]; // This value is passed in to shader, this will be the same value for all dispatches for this light + + DispatchData Dispatch[8]; // List of dispatches (max count is 8) + int32_t DispatchCount; // Number of compute dispatches written to the list +}; + + struct ContactShadowsPushConstants { float surfaceThickness{0.005}; @@ -29,6 +47,9 @@ struct ContactShadowsPushConstants int32_t bUseEarlyOut{0}; ContactShadowsDebugMode debugMode{ContactShadowsDebugMode::NONE}; + + glm::ivec2 waveOffset{0}; + glm::vec4 lightCoordinate{0.0f}; }; struct ContactShadowsDrawInfo From c699444d807d78d9f8df8ffcd794843ac734277d Mon Sep 17 00:00:00 2001 From: Williscool13 Date: Thu, 17 Apr 2025 20:14:57 +0700 Subject: [PATCH 09/15] Contact shadow compile WIP4. --- shaders/shadows/contact_shadow_pass.comp | 273 ++++++++++++++++++++++- 1 file changed, 268 insertions(+), 5 deletions(-) diff --git a/shaders/shadows/contact_shadow_pass.comp b/shaders/shadows/contact_shadow_pass.comp index 4343903d..91317577 100644 --- a/shaders/shadows/contact_shadow_pass.comp +++ b/shaders/shadows/contact_shadow_pass.comp @@ -14,11 +14,19 @@ layout (rgba8, set = 1, binding = 2) uniform image2D debugImage; #define SAMPLE_COUNT 60 +// Number of bilinear sample reads performed per-thread +#define READ_COUNT (SAMPLE_COUNT / WAVE_SIZE + 2) + // samples requires for hard shadow #define HARD_SHADOW_SAMPLES 4 // shadow fade at shadow edges #define FADE_OUT_SAMPLES 8 +#define FAR_DEPTH_VALUE 0 +#define NEAR_DEPTH_VALUE 1 + +#define DEPTH_BOUNDS vec2(0, 1) + layout (push_constant) uniform PushConstants { float surfaceThickness; float bilinearThreshold; @@ -26,7 +34,7 @@ layout (push_constant) uniform PushConstants { int bIgnoreEdgePixels; int bUsePrecisionOffset; - int bBilinearSamplingOffsetMode; + int bilinearSamplingOffsetMode; vec2 depthBounds; int bUseEarlyOut; @@ -36,6 +44,8 @@ layout (push_constant) uniform PushConstants { } pushConstants; +shared float DepthData[READ_COUNT * WAVE_SIZE]; +shared bool LdsEarlyOut; void ComputeWavefrontExtents(ivec2 waveOffset, vec4 lightCoordinate, ivec3 inGroupID, uint inGroupThreadID, out vec2 outDeltaXY, out vec2 outPixelXY, out float outPixelDistance, out bool outMajorAxisX) @@ -80,7 +90,7 @@ out vec2 outDeltaXY, out vec2 outPixelXY, out float outPixelDistance, out bool o vec2 xy_delta = (start_xy - end_xy); // Inverse the read order when reverse direction is true - float thread_step = float(inGroupThreadID ^ (reverse_direction ? 0u : (WAVE_SIZE - 1u))); + float thread_step = float(gl_LocalInvocationID.x ^ (reverse_direction ? 0u : (WAVE_SIZE - 1u))); vec2 pixel_xy = mix(start_xy, end_xy, thread_step / float(WAVE_SIZE)); float pixel_distance = major_axis_start - thread_step + ma_light_frac; @@ -91,6 +101,21 @@ out vec2 outDeltaXY, out vec2 outPixelXY, out float outPixelDistance, out bool o outMajorAxisX = x_axis_major; } + +bool EarlyOutPixel(vec2 depthBounds, vec2 pixel_xy, float depth) +{ + //OPTIONAL TODO; customize this function to return true if the pixel should early-out for custom reasons. E.g., A shadow map pass already found the pixel was in shadow / backfaced, etc. + // Recommended to keep this code very simple! + + // Example: + // return inParameters.CustomShadowMapTerm[pixel_xy] == 0; + + // (void)pixel_xy; //unused by this implementation, avoid potential compiler warning. + + // The compiled code will be more optimal if the 'depth' value is not referenced. + return depth >= depthBounds.y || depth <= depthBounds.x; +} + void main() { vec2 xy_delta; vec2 pixel_xy; @@ -98,9 +123,247 @@ void main() { bool x_axis_major; ComputeWavefrontExtents(pushConstants.waveOffset, pushConstants.lightCoordinate, ivec3(gl_WorkGroupID), gl_LocalInvocationID.x, - xy_delta, pixel_xy, pixel_distance, x_axis_major); + xy_delta, pixel_xy, pixel_distance, x_axis_major); + + + // Read in the depth values + float sampling_depth[READ_COUNT]; + float shadowing_depth[READ_COUNT]; + float depth_thickness_scale[READ_COUNT]; + float sample_distance[READ_COUNT]; + + const float direction = -pushConstants.lightCoordinate.w; + const float z_sign = NEAR_DEPTH_VALUE > FAR_DEPTH_VALUE ? -1 : +1; + + int i; + bool is_edge = false; + bool skip_pixel = false; + vec2 write_xy = floor(pixel_xy); + + for (i = 0; i < READ_COUNT; i++) + { + // We sample depth twice per pixel per sample, and interpolate with an edge detect filter + // Interpolation should only occur on the minor axis of the ray - major axis coordinates should be at pixel centers + vec2 read_xy = floor(pixel_xy); + float minor_axis = x_axis_major ? pixel_xy.y : pixel_xy.x; + + // If a pixel has been detected as an edge, then optionally (inParameters.IgnoreEdgePixels) don't include it in the shadow + const float edge_skip = 1e20;// if edge skipping is enabled, apply an extreme value/blend on edge samples to push the value out of range + + vec2 depths; + float bilinear = fract(minor_axis) - 0.5; + + //#if USE_HALF_PIXEL_OFFSET + //read_xy += 0.5; + //#endif + + //#if USE_UV_PIXEL_BIAS + //float bias = bilinear > 0 ? 1 : -1; + //vec2 offset_xy = float2(x_axis_major ? 0 : bias, x_axis_major ? bias : 0); + + // HLSL enforces that a pixel offset is a compile-time constant, which isn't strictly required (and can sometimes be a bit faster) + // So this fallback will use a manual uv offset instead + //depths.x = inParameters.DepthTexture.SampleLevel(inParameters.PointBorderSampler, read_xy * inParameters.InvDepthTextureSize, 0); + //depths.y = inParameters.DepthTexture.SampleLevel(inParameters.PointBorderSampler, (read_xy + offset_xy) * inParameters.InvDepthTextureSize, 0); + //#else + int bias = bilinear > 0 ? 1 : -1; + ivec2 offset_xy = ivec2(x_axis_major ? 0 : bias, x_axis_major ? bias : 0); + + depths.x = texture(depthImage, read_xy * sceneData.texelSize, 0).r; + depths.y = texture(depthImage, (read_xy + offset_xy) * sceneData.texelSize, 0).r; + //#endif + + // Depth thresholds (bilinear/shadow thickness) are based on a fractional ratio of the difference between sampled depth and the far clip depth + depth_thickness_scale[i] = abs(FAR_DEPTH_VALUE - depths.x); + + // If depth variance is more than a specific threshold, then just use point filtering + bool use_point_filter = abs(depths.x - depths.y) > depth_thickness_scale[i] * pushConstants.bilinearThreshold; + + // Store for debug output when inParameters.DebugOutputEdgeMask is true + if (i == 0) is_edge = use_point_filter; + + if (pushConstants.bilinearSamplingOffsetMode == 1) + { + bilinear = use_point_filter ? 0 : bilinear; + //both shadow depth and starting depth are the same in this mode, unless shadow skipping edges + sampling_depth[i] = mix(depths.x, depths.y, abs(bilinear)); + shadowing_depth[i] = (pushConstants.bIgnoreEdgePixels == 1 && use_point_filter) ? edge_skip : sampling_depth[i]; + } + else + { + // The pixel starts sampling at this depth + sampling_depth[i] = depths.x; + + float edge_depth = pushConstants.bIgnoreEdgePixels == 1 ? edge_skip : depths.x; + // Any sample in this wavefront is possibly interpolated towards the bilinear sample + // So use should use a shadowing depth that is further away, based on the difference between the two samples + float shadow_depth = depths.x + abs(depths.x - depths.y) * z_sign; + + // Shadows cast from this depth + shadowing_depth[i] = use_point_filter ? edge_depth : shadow_depth; + } + + // Store for later + sample_distance[i] = pixel_distance + (WAVE_SIZE * i) * direction; + + // Iterate to the next pixel along the ray. This will be WAVE_SIZE pixels along the ray... + pixel_xy += xy_delta * direction; + } + + // Using early out, and no debug mode is enabled? + // if (pushConstants.bUseEarlyOut == 1 && (inParameters.DebugOutputWaveIndex == false && inParameters.DebugOutputThreadIndex == false && inParameters.DebugOutputEdgeMask == false)) + // { + // // read the depth of the pixel we are shadowing, and early-out + // // The compiler will typically rearrange this code to put it directly after the first depth read + // skip_pixel = EarlyOutPixel(DEPTH_BOUNDS, write_xy, sampling_depth[0]); + // + // // are all threads in this wave out of bounds? + // bool early_out = WaveActiveAnyTrue(!skip_pixel) == false; + // + // // WaveGetLaneCount returns the hardware wave size + // if (WaveGetLaneCount() == WAVE_SIZE) + // { + // // Optimal case: + // // If each wavefront is just a single wave, then we can trivially early-out. + // if (early_out == true){ + // return; + // } + // + // } + // else + // { + // // This wavefront is made up of multiple small waves, so we need to coordinate them for all to early-out together. + // // Doing this can make the worst case (all pixels drawn) a bit more expensive (~15%), but the best-case (all early-out) is typically 2-3x better. + // LdsEarlyOut = true; + // + // memoryBarrierShared(); + // barrier(); + // + // if (early_out == false){ + // LdsEarlyOut = false; + // } + // + // + // memoryBarrierShared(); + // barrier(); + // + // if (LdsEarlyOut) + // return; + // } + // } + + // Write the shadow depths to LDS + for (i = 0; i < READ_COUNT; i++) + { + // Perspective correct the shadowing depth, in this space, all light rays are parallel + float stored_depth = (shadowing_depth[i] - pushConstants.lightCoordinate.z) / sample_distance[i]; + + if (i != 0) + { + // For pixels within sampling distance of the light, it is possible that sampling will + // overshoot the light coordinate for extended reads. We want to ignore these samples + stored_depth = sample_distance[i] > 0 ? stored_depth : 1e10; + } + + // Store the depth values in groupshared + int idx = (i * WAVE_SIZE) + int(gl_LocalInvocationID.x); + DepthData[idx] = stored_depth; + } + + // Sync wavefronts now groupshared DepthData is written + memoryBarrierShared(); + barrier(); + + // If the starting depth isn't in depth bounds, then we don't need a shadow + if (skip_pixel){ + return; + } + + + float start_depth = sampling_depth[0]; + + // lerp away from far depth by a tiny fraction? + if (pushConstants.bUsePrecisionOffset == 1) + start_depth = mix(start_depth, FAR_DEPTH_VALUE, -1.0 / 0xFFFF); + + // perspective correct the depth + start_depth = (start_depth - pushConstants.lightCoordinate.z) / sample_distance[0]; + + // Start by reading the next value + int sample_index = int(gl_LocalInvocationID.x) + 1; + + vec4 shadow_value = vec4(1.0f); + float hard_shadow = 1; + + // This is the inverse of how large the shadowing window is for the projected sample data. + // All values in the LDS sample list are scaled by 1.0 / sample_distance, such that all light directions become parallel. + // The multiply by sample_distance[0] here is to compensate for the projection divide in the data. + // The 1.0 / inParameters.SurfaceThickness is to adjust user selected thickness. So a 0.5% thickness will scale depth values from [0,1] to [0,200]. The shadow window is always 1 wide. + // 1.0 / depth_thickness_scale[0] is because SurfaceThickness is percentage of remaining depth between the sample and the far clip - not a percentage of the full depth range. + // The min() function is to make sure the window is a minimum width when very close to the light. The +direction term will bias the result so the pixel at the very center of the light is either fully lit or shadowed + float depth_scale = min(sample_distance[0] + direction, 1.0 / pushConstants.surfaceThickness) * sample_distance[0] / depth_thickness_scale[0]; + + start_depth = start_depth * depth_scale - z_sign; + + // The first number of hard shadow samples, a single pixel can produce a full shadow + for (i = 0; i < HARD_SHADOW_SAMPLES; i++) + { + float depth_delta = abs(start_depth - DepthData[sample_index + i] * depth_scale); + + // We want to find the distance of the sample that is closest to the reference depth + hard_shadow = min(hard_shadow, depth_delta); + } + + // Brute force go! + // The main shadow samples, averaged in to a set of 4 shadow values + for (i = HARD_SHADOW_SAMPLES; i < SAMPLE_COUNT - FADE_OUT_SAMPLES; i++) + { + float depth_delta = abs(start_depth - DepthData[sample_index + i] * depth_scale); + + // Do the same as the hard_shadow code above, but this will accumulate to 4 separate values. + // By using 4 values, the average shadow can be taken, which can help soften single-pixel shadows. + shadow_value[i & 3] = min(shadow_value[i & 3], depth_delta); + } + + // Final fade out samples + for (i = SAMPLE_COUNT - FADE_OUT_SAMPLES; i < SAMPLE_COUNT; i++) + { + float depth_delta = abs(start_depth - DepthData[sample_index + i] * depth_scale); + + // Add the fade value to these samples + const float fade_out = float(i + 1 - (SAMPLE_COUNT - FADE_OUT_SAMPLES)) / float((FADE_OUT_SAMPLES + 1) * 0.75); + + shadow_value[i & 3] = min(shadow_value[i & 3], depth_delta + fade_out); + } + + // Apply the contrast value. + // A value of 0 indicates a sample was exactly matched to the reference depth (and the result is fully shadowed) + // We want some boost to this range, so samples don't have to exactly match to produce a full shadow. + shadow_value = clamp(shadow_value * (pushConstants.shadowContrast) + (1 - pushConstants.shadowContrast), 0, 1); + hard_shadow = clamp(hard_shadow * (pushConstants.shadowContrast) + (1 - pushConstants.shadowContrast), 0, 1); + + float result = 0; + + // Take the average of 4 samples, this is useful to reduces aliasing noise in the source depth, especially with long shadows. + result = dot(shadow_value, vec4(0.25)); + + // If the first samples are always producing a hard shadow, then compute this value separately. + result = min(hard_shadow, result); + //write the result + { + switch (pushConstants.debugMode){ + case 1: + result = is_edge ? 1 : 0; + break; + case 2: + result = (gl_LocalInvocationID.x / float(WAVE_SIZE)); + break; + case 3: + result = fract(ivec3(gl_WorkGroupID).x / float(WAVE_SIZE)); + break; + } - imageStore(debugImage, ivec2(pixel_xy), vec4(1.0f, 0.0f, 0.0f, 1.0f)); - imageStore(contactShadow, ivec2(pixel_xy), vec4(0.7f)); + imageStore(debugImage, ivec2(pixel_xy), vec4(vec3(result), 1.0f)); + } } From 4ff5287e932a96ab18e4faade84e68338e487558 Mon Sep 17 00:00:00 2001 From: Williscool13 Date: Fri, 18 Apr 2025 14:33:13 +0700 Subject: [PATCH 10/15] Contact shadows debug WIP5. --- assets/settings.willengine | 14 +++--- shaders/shadows/contact_shadow_pass.comp | 21 ++++---- src/core/engine.cpp | 3 ++ src/core/engine.h | 1 + src/renderer/imgui_wrapper.cpp | 36 +++++++++++--- .../contact_shadows_pipeline.cpp | 48 +++++++++++-------- .../contact_shadow/contact_shadows_pipeline.h | 4 +- .../contact_shadows_pipeline_types.h | 11 ++++- 8 files changed, 93 insertions(+), 45 deletions(-) diff --git a/assets/settings.willengine b/assets/settings.willengine index f9d165a7..18bcbc18 100644 --- a/assets/settings.willengine +++ b/assets/settings.willengine @@ -19,15 +19,15 @@ }, "cameraProperties": { "position": [ - 92.20421600341797, - 80.86691284179688, - -30.049116134643555 + 93.61461639404297, + 88.9618911743164, + -54.77859115600586 ], "rotation": [ - -0.002585706301033497, - 0.0444491021335125, - 0.00012627220712602139, - 0.999008297920227 + -0.15127433836460114, + 0.1024111807346344, + 0.01577099598944187, + 0.9830459952354431 ], "fov": 1.3089969158172607, "aspectRatio": 1.7777777910232544, diff --git a/shaders/shadows/contact_shadow_pass.comp b/shaders/shadows/contact_shadow_pass.comp index 91317577..8678434d 100644 --- a/shaders/shadows/contact_shadow_pass.comp +++ b/shaders/shadows/contact_shadow_pass.comp @@ -4,7 +4,7 @@ #define WAVE_SIZE 64 -layout(local_size_x = WAVE_SIZE) in; +layout(local_size_x = WAVE_SIZE, local_size_y = 1, local_size_z = 1) in; // layout (std140, set = 0, binding = 0) uniform SceneData - scene.glsl @@ -31,14 +31,16 @@ layout (push_constant) uniform PushConstants { float surfaceThickness; float bilinearThreshold; float shadowContrast; - int bIgnoreEdgePixels; + int bIgnoreEdgePixels; int bUsePrecisionOffset; int bilinearSamplingOffsetMode; - vec2 depthBounds; + vec2 depthBounds; int bUseEarlyOut; + int debugMode; + ivec2 waveOffset; vec4 lightCoordinate; @@ -83,14 +85,13 @@ out vec2 outDeltaXY, out vec2 outPixelXY, out float outPixelDistance, out bool o // For the very inner most ring, we need to interpolate to a pixel centered UV, // so the UV->pixel rounding doesn't skip output pixels - vec2 end_xy = mix(lightCoordinate.xy, start_xy, - (major_axis_end + ma_light_frac) / (major_axis_start + ma_light_frac)); + vec2 end_xy = mix(lightCoordinate.xy, start_xy, (major_axis_end + ma_light_frac) / (major_axis_start + ma_light_frac)); // The major axis should be a round number vec2 xy_delta = (start_xy - end_xy); // Inverse the read order when reverse direction is true - float thread_step = float(gl_LocalInvocationID.x ^ (reverse_direction ? 0u : (WAVE_SIZE - 1u))); + float thread_step = float(inGroupThreadID ^ (reverse_direction ? 0u : (WAVE_SIZE - 1u))); vec2 pixel_xy = mix(start_xy, end_xy, thread_step / float(WAVE_SIZE)); float pixel_distance = major_axis_start - thread_step + ma_light_frac; @@ -122,6 +123,8 @@ void main() { float pixel_distance; bool x_axis_major; + + ComputeWavefrontExtents(pushConstants.waveOffset, pushConstants.lightCoordinate, ivec3(gl_WorkGroupID), gl_LocalInvocationID.x, xy_delta, pixel_xy, pixel_distance, x_axis_major); @@ -169,8 +172,8 @@ void main() { int bias = bilinear > 0 ? 1 : -1; ivec2 offset_xy = ivec2(x_axis_major ? 0 : bias, x_axis_major ? bias : 0); - depths.x = texture(depthImage, read_xy * sceneData.texelSize, 0).r; - depths.y = texture(depthImage, (read_xy + offset_xy) * sceneData.texelSize, 0).r; + depths.x = textureLod(depthImage, read_xy * sceneData.texelSize, 0).r; + depths.y = textureLod(depthImage, (read_xy + offset_xy) * sceneData.texelSize, 0).r; //#endif // Depth thresholds (bilinear/shadow thickness) are based on a fractional ratio of the difference between sampled depth and the far clip depth @@ -364,6 +367,6 @@ void main() { break; } - imageStore(debugImage, ivec2(pixel_xy), vec4(vec3(result), 1.0f)); + imageStore(debugImage, ivec2(write_xy), vec4(vec3(result), 1.0f)); } } diff --git a/src/core/engine.cpp b/src/core/engine.cpp index d45956be..4693645e 100644 --- a/src/core/engine.cpp +++ b/src/core/engine.cpp @@ -644,6 +644,9 @@ void Engine::draw(float deltaTime) ambientOcclusionPipeline->draw(cmd, gtaoDrawInfo); contact_shadows_pipeline::ContactShadowsDrawInfo contactDrawInfo{ + camera, + mainLight, + contactShadowDebug, sceneDataDescriptorBuffer.getDescriptorBufferBindingInfo(), sceneDataDescriptorBuffer.getDescriptorBufferSize() * currentFrameOverlap }; diff --git a/src/core/engine.h b/src/core/engine.h index 8652a3ac..a3c3a1d0 100644 --- a/src/core/engine.h +++ b/src/core/engine.h @@ -182,6 +182,7 @@ class Engine int32_t csmPcf{1}; int32_t deferredDebug{0}; int32_t gtaoDebug{4}; + int32_t contactShadowDebug{0}; bool bDrawTerrainLines{false}; bool bPausePhysics{true}; bool bDisableJitter{false}; diff --git a/src/renderer/imgui_wrapper.cpp b/src/renderer/imgui_wrapper.cpp index 2b4af1fb..f6ca0204 100644 --- a/src/renderer/imgui_wrapper.cpp +++ b/src/renderer/imgui_wrapper.cpp @@ -1085,17 +1085,17 @@ void ImguiWrapper::imguiInterface(Engine* engine) ImGui::End(); if (ImGui::Begin("Discardable Debug")) { + ImGui::SliderInt("Contact Shadow Debug", &engine->contactShadowDebug, 0, 3); + if (contactShadowsOutputImguiId == VK_NULL_HANDLE) { - if (engine->contactShadowsPipeline->contactShadowImage.imageView != VK_NULL_HANDLE) { + if (engine->contactShadowsPipeline->debugImage.imageView != VK_NULL_HANDLE) { contactShadowsOutputImguiId = ImGui_ImplVulkan_AddTexture( engine->resourceManager->getDefaultSamplerNearest(), - engine->contactShadowsPipeline->contactShadowImage.imageView, + engine->contactShadowsPipeline->debugImage.imageView, VK_IMAGE_LAYOUT_GENERAL); } } - ImGui::Separator(); - if (contactShadowsOutputImguiId == VK_NULL_HANDLE) { ImGui::TextColored(ImVec4(1.0f, 0.3f, 0.3f, 1.0f), "Debug texture not available."); } @@ -1104,14 +1104,38 @@ void ImguiWrapper::imguiInterface(Engine* engine) float maxSize = ImGui::GetContentRegionAvail().x; maxSize = glm::min(maxSize, 1024.0f); - VkExtent3D imageExtent = engine->contactShadowsPipeline->contactShadowImage.imageExtent; + VkExtent3D imageExtent = engine->contactShadowsPipeline->debugImage.imageExtent; float width = std::min(maxSize, static_cast(imageExtent.width)); float aspectRatio = static_cast(imageExtent.width) / static_cast(imageExtent.height); float height = width / aspectRatio; ImGui::Image(reinterpret_cast(contactShadowsOutputImguiId), ImVec2(width, height)); - } + if (ImGui::Button("Save SCSS Debug Image")) { + if (file::getOrCreateDirectory(file::imagesSavePath)) { + const std::filesystem::path path = file::imagesSavePath / "scss_debug.png"; + + vk_helpers::saveImageR8G8B8A8UNORM( + *engine->resourceManager, + *engine->immediate, + engine->contactShadowsPipeline->debugImage, + VK_IMAGE_LAYOUT_GENERAL, + path.string().c_str(), + 0 + ); + + ImGui::OpenPopup("SaveConfirmation"); + } + } + + if (ImGui::BeginPopupModal("SaveConfirmation", NULL, ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::Text("Image saved to %s/gtao_debug.png", file::imagesSavePath.string().c_str()); + if (ImGui::Button("OK", ImVec2(120, 0))) { + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + } } ImGui::End(); diff --git a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp index 1403bb7e..ccedada7 100644 --- a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp +++ b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp @@ -121,24 +121,32 @@ void ContactShadowsPipeline::draw(VkCommandBuffer cmd, const ContactShadowsDrawI vk_helpers::transitionImage(cmd, debugImage.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_ASPECT_COLOR_BIT); vk_helpers::clearColorImage(cmd, VK_IMAGE_ASPECT_COLOR_BIT, contactShadowImage.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL); + vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); + ContactShadowsPushConstants push{}; + push.debugMode = static_cast(drawInfo.debug); - vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); - vkCmdPushConstants(cmd, pipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(ContactShadowsPushConstants), &push); + const DispatchList dispatchList = buildDispatchList(drawInfo.camera, drawInfo.light); - VkDescriptorBufferBindingInfoEXT bindingInfos[2] = {}; - bindingInfos[0] = drawInfo.sceneDataBinding; - bindingInfos[1] = descriptorBufferSampler.getDescriptorBufferBindingInfo(); - vkCmdBindDescriptorBuffersEXT(cmd, 2, bindingInfos); + push.lightCoordinate = glm::vec4(dispatchList.LightCoordinate_Shader[0], dispatchList.LightCoordinate_Shader[1], dispatchList.LightCoordinate_Shader[2], dispatchList.LightCoordinate_Shader[3]); + for (int32_t i = 0; i < dispatchList.DispatchCount; ++i) { + push.waveOffset = glm::ivec2(dispatchList.Dispatch[i].WaveOffset_Shader[0], dispatchList.Dispatch[i].WaveOffset_Shader[1]); - constexpr std::array indices{0, 1}; - const std::array offsets{drawInfo.sceneDataOffset, ZERO_DEVICE_SIZE}; + vkCmdPushConstants(cmd, pipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(ContactShadowsPushConstants), &push); - vkCmdSetDescriptorBufferOffsetsEXT(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0, 2, indices.data(), offsets.data()); + VkDescriptorBufferBindingInfoEXT bindingInfos[2] = {}; + bindingInfos[0] = drawInfo.sceneDataBinding; + bindingInfos[1] = descriptorBufferSampler.getDescriptorBufferBindingInfo(); + vkCmdBindDescriptorBuffersEXT(cmd, 2, bindingInfos); + constexpr std::array indices{0, 1}; + const std::array offsets{drawInfo.sceneDataOffset, ZERO_DEVICE_SIZE}; - const auto x = static_cast(std::ceil(RENDER_EXTENT_WIDTH * RENDER_EXTENT_HEIGHT / static_cast(CONTACT_SHADOW_WAVE_COUNT))); - vkCmdDispatch(cmd, x, 1, 1); + vkCmdSetDescriptorBufferOffsetsEXT(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0, 2, indices.data(), offsets.data()); + + const int32_t* waveCount = dispatchList.Dispatch[i].WaveCount; + vkCmdDispatch(cmd, waveCount[0], waveCount[1], waveCount[2]); + } } void ContactShadowsPipeline::createPipeline() @@ -173,7 +181,7 @@ DispatchList ContactShadowsPipeline::buildDispatchList(const Camera* camera, con // Floating point division in the shader has a practical limit for precision when the light is *very* far off screen (~1m pixels+) // So when computing the light XY coordinate, use an adjusted w value to handle these extreme values float xy_light_w = lightProjection[3]; - const float FP_limit = 0.000002f * static_cast(CONTACT_SHADOW_WAVE_COUNT); + const float FP_limit = 0.000002f * static_cast(CONTACT_SHADOW_WAVE_SIZE); if (xy_light_w >= 0 && xy_light_w < FP_limit) xy_light_w = FP_limit; else if (xy_light_w < 0 && xy_light_w > -FP_limit) xy_light_w = -FP_limit; @@ -206,10 +214,10 @@ DispatchList ContactShadowsPipeline::buildDispatchList(const Camera* camera, con // Bounds relative to the quadrant const int bounds[4] = { - bend_max(0, ((q & 1) ? biased_bounds[0] : -biased_bounds[2])) / CONTACT_SHADOW_WAVE_COUNT, - bend_max(0, ((q & 2) ? biased_bounds[1] : -biased_bounds[3])) / CONTACT_SHADOW_WAVE_COUNT, - bend_max(0, (((q & 1) ? biased_bounds[2] : -biased_bounds[0]) + CONTACT_SHADOW_WAVE_COUNT * (vertical ? 1 : 2) - 1)) / CONTACT_SHADOW_WAVE_COUNT, - bend_max(0, (((q & 2) ? biased_bounds[3] : -biased_bounds[1]) + CONTACT_SHADOW_WAVE_COUNT * (vertical ? 2 : 1) - 1)) / CONTACT_SHADOW_WAVE_COUNT, + bend_max(0, ((q & 1) ? biased_bounds[0] : -biased_bounds[2])) / CONTACT_SHADOW_WAVE_SIZE, + bend_max(0, ((q & 2) ? biased_bounds[1] : -biased_bounds[3])) / CONTACT_SHADOW_WAVE_SIZE, + bend_max(0, (((q & 1) ? biased_bounds[2] : -biased_bounds[0]) + CONTACT_SHADOW_WAVE_SIZE * (vertical ? 1 : 2) - 1)) / CONTACT_SHADOW_WAVE_SIZE, + bend_max(0, (((q & 2) ? biased_bounds[3] : -biased_bounds[1]) + CONTACT_SHADOW_WAVE_SIZE * (vertical ? 2 : 1) - 1)) / CONTACT_SHADOW_WAVE_SIZE, }; if ((bounds[2] - bounds[0]) > 0 && (bounds[3] - bounds[1]) > 0) { @@ -218,7 +226,7 @@ DispatchList ContactShadowsPipeline::buildDispatchList(const Camera* camera, con DispatchData& disp = result.Dispatch[result.DispatchCount++]; - disp.WaveCount[0] = CONTACT_SHADOW_WAVE_COUNT; + disp.WaveCount[0] = CONTACT_SHADOW_WAVE_SIZE; disp.WaveCount[1] = bounds[2] - bounds[0]; disp.WaveCount[2] = bounds[3] - bounds[1]; disp.WaveOffset_Shader[0] = ((q & 1) ? bounds[0] : -bounds[2]) + bias_x; @@ -231,7 +239,7 @@ DispatchList ContactShadowsPipeline::buildDispatchList(const Camera* camera, con if (q == 2) axis_delta = -biased_bounds[0] - biased_bounds[3]; if (q == 3) axis_delta = -biased_bounds[2] + biased_bounds[3]; - axis_delta = (axis_delta + CONTACT_SHADOW_WAVE_COUNT - 1) / CONTACT_SHADOW_WAVE_COUNT; + axis_delta = (axis_delta + CONTACT_SHADOW_WAVE_SIZE - 1) / CONTACT_SHADOW_WAVE_SIZE; if (axis_delta > 0) { DispatchData& disp2 = result.Dispatch[result.DispatchCount++]; @@ -283,8 +291,8 @@ DispatchList ContactShadowsPipeline::buildDispatchList(const Camera* camera, con // Scale the shader values by the wave count, the shader expects this for (int i = 0; i < result.DispatchCount; i++) { - result.Dispatch[i].WaveOffset_Shader[0] *= CONTACT_SHADOW_WAVE_COUNT; - result.Dispatch[i].WaveOffset_Shader[1] *= CONTACT_SHADOW_WAVE_COUNT; + result.Dispatch[i].WaveOffset_Shader[0] *= CONTACT_SHADOW_WAVE_SIZE; + result.Dispatch[i].WaveOffset_Shader[1] *= CONTACT_SHADOW_WAVE_SIZE; } return result; diff --git a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.h b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.h index a6cd4090..7138c05c 100644 --- a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.h +++ b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.h @@ -41,7 +41,7 @@ class ContactShadowsPipeline { private: void createPipeline(); - static static DispatchList buildDispatchList(const Camera* camera, const DirectionalLight& mainLight); + static DispatchList buildDispatchList(const Camera* camera, const DirectionalLight& mainLight); static int32_t bend_min(const int32_t a, const int32_t b) { return a > b ? b : a; } static int32_t bend_max(const int32_t a, const int32_t b) { return a > b ? a : b; } @@ -59,7 +59,7 @@ class ContactShadowsPipeline { DescriptorBufferSampler descriptorBufferSampler; private: // Debug - VkFormat debugFormat{VK_FORMAT_R8G8B8A8_SINT}; + VkFormat debugFormat{VK_FORMAT_R8G8B8A8_UNORM}; AllocatedImage debugImage{VK_NULL_HANDLE}; ResourceManager& resourceManager; diff --git a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h index f1bb678d..9f3ed417 100644 --- a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h +++ b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h @@ -8,14 +8,20 @@ #include #include +#include "src/core/camera/camera.h" +#include "src/renderer/lighting/directional_light.h" + namespace will_engine::contact_shadows_pipeline { -static constexpr int32_t CONTACT_SHADOW_WAVE_COUNT = 64; +static constexpr int32_t CONTACT_SHADOW_WAVE_SIZE = 64; enum class ContactShadowsDebugMode : int32_t { NONE = 0, + EDGE = 1, + INVOCATION_ID = 2, + WORK_GROUP_ID = 3 }; struct DispatchData @@ -54,6 +60,9 @@ struct ContactShadowsPushConstants struct ContactShadowsDrawInfo { + Camera* camera; + DirectionalLight light; + int32_t debug; VkDescriptorBufferBindingInfoEXT sceneDataBinding{}; VkDeviceSize sceneDataOffset{0}; }; From af8179d105faa823fa6922c0f1651ea0e40c8fd3 Mon Sep 17 00:00:00 2001 From: Williscool13 Date: Fri, 18 Apr 2025 19:50:18 +0700 Subject: [PATCH 11/15] Contact shadow experimentation WIP6. --- assets/settings.willengine | 20 ++++---- shaders/shadows/contact_shadow_pass.comp | 47 +++++++++---------- src/core/engine.cpp | 2 + src/core/engine.h | 1 + src/renderer/imgui_wrapper.cpp | 1 + .../contact_shadows_pipeline.cpp | 1 + .../contact_shadows_pipeline_types.h | 5 +- 7 files changed, 39 insertions(+), 38 deletions(-) diff --git a/assets/settings.willengine b/assets/settings.willengine index 18bcbc18..d4456c7c 100644 --- a/assets/settings.willengine +++ b/assets/settings.willengine @@ -6,9 +6,9 @@ }, "mainLight": { "direction": [ - -0.4728662669658661, - -0.7881104350090027, - -0.39405521750450134 + -0.2588678002357483, + -0.9482336640357971, + -0.18395733833312988 ], "color": [ 0.20000000298023224, @@ -19,15 +19,15 @@ }, "cameraProperties": { "position": [ - 93.61461639404297, - 88.9618911743164, - -54.77859115600586 + 108.51939392089844, + 135.32415771484375, + -53.729923248291016 ], "rotation": [ - -0.15127433836460114, - 0.1024111807346344, - 0.01577099598944187, - 0.9830459952354431 + 0.10572174191474915, + -0.3543924391269684, + -0.04037834703922272, + -0.9282233715057373 ], "fov": 1.3089969158172607, "aspectRatio": 1.7777777910232544, diff --git a/shaders/shadows/contact_shadow_pass.comp b/shaders/shadows/contact_shadow_pass.comp index 8678434d..8619a211 100644 --- a/shaders/shadows/contact_shadow_pass.comp +++ b/shaders/shadows/contact_shadow_pass.comp @@ -22,11 +22,15 @@ layout (rgba8, set = 1, binding = 2) uniform image2D debugImage; // shadow fade at shadow edges #define FADE_OUT_SAMPLES 8 -#define FAR_DEPTH_VALUE 0 +// Main camera depth bounds #define NEAR_DEPTH_VALUE 1 +#define FAR_DEPTH_VALUE 0 +// Light VP dpeth bounds #define DEPTH_BOUNDS vec2(0, 1) +#define USE_HALF_PIXEL_OFFSET 1 + layout (push_constant) uniform PushConstants { float surfaceThickness; float bilinearThreshold; @@ -123,12 +127,9 @@ void main() { float pixel_distance; bool x_axis_major; - - ComputeWavefrontExtents(pushConstants.waveOffset, pushConstants.lightCoordinate, ivec3(gl_WorkGroupID), gl_LocalInvocationID.x, xy_delta, pixel_xy, pixel_distance, x_axis_major); - // Read in the depth values float sampling_depth[READ_COUNT]; float shadowing_depth[READ_COUNT]; @@ -156,25 +157,17 @@ void main() { vec2 depths; float bilinear = fract(minor_axis) - 0.5; - //#if USE_HALF_PIXEL_OFFSET - //read_xy += 0.5; - //#endif - - //#if USE_UV_PIXEL_BIAS - //float bias = bilinear > 0 ? 1 : -1; - //vec2 offset_xy = float2(x_axis_major ? 0 : bias, x_axis_major ? bias : 0); + #if USE_HALF_PIXEL_OFFSET + read_xy += 0.5; + #endif // HLSL enforces that a pixel offset is a compile-time constant, which isn't strictly required (and can sometimes be a bit faster) // So this fallback will use a manual uv offset instead - //depths.x = inParameters.DepthTexture.SampleLevel(inParameters.PointBorderSampler, read_xy * inParameters.InvDepthTextureSize, 0); - //depths.y = inParameters.DepthTexture.SampleLevel(inParameters.PointBorderSampler, (read_xy + offset_xy) * inParameters.InvDepthTextureSize, 0); - //#else int bias = bilinear > 0 ? 1 : -1; - ivec2 offset_xy = ivec2(x_axis_major ? 0 : bias, x_axis_major ? bias : 0); + vec2 offset_xy = vec2(x_axis_major ? 0 : bias, x_axis_major ? bias : 0); depths.x = textureLod(depthImage, read_xy * sceneData.texelSize, 0).r; depths.y = textureLod(depthImage, (read_xy + offset_xy) * sceneData.texelSize, 0).r; - //#endif // Depth thresholds (bilinear/shadow thickness) are based on a fractional ratio of the difference between sampled depth and the far clip depth depth_thickness_scale[i] = abs(FAR_DEPTH_VALUE - depths.x); @@ -183,7 +176,9 @@ void main() { bool use_point_filter = abs(depths.x - depths.y) > depth_thickness_scale[i] * pushConstants.bilinearThreshold; // Store for debug output when inParameters.DebugOutputEdgeMask is true - if (i == 0) is_edge = use_point_filter; + if (i == 0) { + is_edge = use_point_filter; + } if (pushConstants.bilinearSamplingOffsetMode == 1) { @@ -282,12 +277,12 @@ void main() { return; } - float start_depth = sampling_depth[0]; // lerp away from far depth by a tiny fraction? - if (pushConstants.bUsePrecisionOffset == 1) - start_depth = mix(start_depth, FAR_DEPTH_VALUE, -1.0 / 0xFFFF); + if (pushConstants.bUsePrecisionOffset == 1){ + start_depth = mix(start_depth, FAR_DEPTH_VALUE, -1.0 / 0xFFFF); + } // perspective correct the depth start_depth = (start_depth - pushConstants.lightCoordinate.z) / sample_distance[0]; @@ -357,14 +352,14 @@ void main() { { switch (pushConstants.debugMode){ case 1: - result = is_edge ? 1 : 0; - break; + result = is_edge ? 1 : 0; + break; case 2: - result = (gl_LocalInvocationID.x / float(WAVE_SIZE)); - break; + result = (gl_LocalInvocationID.x / float(WAVE_SIZE)); + break; case 3: - result = fract(ivec3(gl_WorkGroupID).x / float(WAVE_SIZE)); - break; + result = fract(ivec3(gl_WorkGroupID).x / float(WAVE_SIZE)); + break; } imageStore(debugImage, ivec2(write_xy), vec4(vec3(result), 1.0f)); diff --git a/src/core/engine.cpp b/src/core/engine.cpp index 4693645e..b92a0a9c 100644 --- a/src/core/engine.cpp +++ b/src/core/engine.cpp @@ -647,6 +647,7 @@ void Engine::draw(float deltaTime) camera, mainLight, contactShadowDebug, + bilinearThreshold, sceneDataDescriptorBuffer.getDescriptorBufferBindingInfo(), sceneDataDescriptorBuffer.getDescriptorBufferSize() * currentFrameOverlap }; @@ -1082,6 +1083,7 @@ void Engine::hotReloadShaders() const deferredMrtPipeline->reloadShaders(); transparentPipeline->reloadShaders(); ambientOcclusionPipeline->reloadShaders(); + contactShadowsPipeline->reloadShaders(); deferredResolvePipeline->reloadShaders(); temporalAntialiasingPipeline->reloadShaders(); postProcessPipeline->reloadShaders(); diff --git a/src/core/engine.h b/src/core/engine.h index a3c3a1d0..c2c25251 100644 --- a/src/core/engine.h +++ b/src/core/engine.h @@ -183,6 +183,7 @@ class Engine int32_t deferredDebug{0}; int32_t gtaoDebug{4}; int32_t contactShadowDebug{0}; + float bilinearThreshold{0.2f}; bool bDrawTerrainLines{false}; bool bPausePhysics{true}; bool bDisableJitter{false}; diff --git a/src/renderer/imgui_wrapper.cpp b/src/renderer/imgui_wrapper.cpp index f6ca0204..44f82f94 100644 --- a/src/renderer/imgui_wrapper.cpp +++ b/src/renderer/imgui_wrapper.cpp @@ -1086,6 +1086,7 @@ void ImguiWrapper::imguiInterface(Engine* engine) if (ImGui::Begin("Discardable Debug")) { ImGui::SliderInt("Contact Shadow Debug", &engine->contactShadowDebug, 0, 3); + ImGui::InputFloat("Blinear Threshold", &engine->bilinearThreshold); if (contactShadowsOutputImguiId == VK_NULL_HANDLE) { if (engine->contactShadowsPipeline->debugImage.imageView != VK_NULL_HANDLE) { diff --git a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp index ccedada7..1a1b0636 100644 --- a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp +++ b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp @@ -125,6 +125,7 @@ void ContactShadowsPipeline::draw(VkCommandBuffer cmd, const ContactShadowsDrawI ContactShadowsPushConstants push{}; push.debugMode = static_cast(drawInfo.debug); + push.bilinearThreshold = drawInfo.v; const DispatchList dispatchList = buildDispatchList(drawInfo.camera, drawInfo.light); diff --git a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h index 9f3ed417..f737b6d0 100644 --- a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h +++ b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h @@ -43,9 +43,9 @@ struct ContactShadowsPushConstants { float surfaceThickness{0.005}; float bilinearThreshold{0.02}; - float shadowContrast{4}; + float shadowContrast{2}; - int32_t bIgnoreEdgePixels{0}; + int32_t bIgnoreEdgePixels{1}; int32_t bUsePrecisionOffset{0}; int32_t bBilinearSamplingOffsetMode{0}; @@ -63,6 +63,7 @@ struct ContactShadowsDrawInfo Camera* camera; DirectionalLight light; int32_t debug; + float v; VkDescriptorBufferBindingInfoEXT sceneDataBinding{}; VkDeviceSize sceneDataOffset{0}; }; From e80f6f1fe5001301641e47e220aa90a8b6aa9e15 Mon Sep 17 00:00:00 2001 From: Williscool13 Date: Mon, 21 Apr 2025 21:54:39 +0700 Subject: [PATCH 12/15] Contact shadows almost fully functional. WIP7 --- assets/maps/sampleScene.willmap | 96 ++++++++++++++++++- assets/settings.willengine | 20 ++-- shaders/shadows/contact_shadow_pass.comp | 15 ++- src/core/engine.cpp | 4 +- src/core/engine.h | 3 +- src/renderer/imgui_wrapper.cpp | 12 ++- .../contact_shadows_pipeline.cpp | 6 +- .../contact_shadows_pipeline_types.h | 8 +- 8 files changed, 134 insertions(+), 30 deletions(-) diff --git a/assets/maps/sampleScene.willmap b/assets/maps/sampleScene.willmap index a869bb05..2aedd3a7 100644 --- a/assets/maps/sampleScene.willmap +++ b/assets/maps/sampleScene.willmap @@ -6,7 +6,7 @@ }, "metadata": { "name": "sampleScene", - "created": "2025-04-06 11:32:54", + "created": "2025-04-21 21:26:24", "formatVersion": 1 }, "rootComponents": { @@ -236,7 +236,7 @@ "transform": { "position": { "x": 0.0, - "y": 41.5, + "y": 38.79999923706055, "z": 0.0 }, "rotation": { @@ -262,7 +262,7 @@ "RigidBodyComponent": { "properties": { "isActive": true, - "motionType": 1, + "motionType": 2, "layer": 1, "shapeType": 0, "shapeParams": { @@ -653,6 +653,96 @@ } } ] + }, + { + "id": 15, + "name": "GameObject_15", + "transform": { + "position": { + "x": 0.0, + "y": 37.70000076293945, + "z": 0.0 + }, + "rotation": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 1.0 + }, + "scale": { + "x": 20.0, + "y": 0.20000000298023224, + "z": 20.0 + } + }, + "components": { + "MeshRendererComponent": { + "renderReference": 3129368917, + "renderMeshIndex": 1, + "renderIsVisible": true, + "renderIsShadowCaster": true, + "componentName": "Mesh Renderer" + }, + "RigidBodyComponent": { + "properties": { + "isActive": true, + "motionType": 1, + "layer": 0, + "shapeType": 1, + "shapeParams": { + "x": 10.0, + "y": 0.10000000149011612, + "z": 10.0 + } + }, + "componentName": "New RigidBodyComponent" + } + } + }, + { + "id": 16, + "name": "GameObject_16", + "transform": { + "position": { + "x": -7.5, + "y": 38.79999923706055, + "z": 0.0 + }, + "rotation": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 1.0 + }, + "scale": { + "x": 1.0, + "y": 1.0, + "z": 1.0 + } + }, + "components": { + "MeshRendererComponent": { + "renderReference": 3129368917, + "renderMeshIndex": 0, + "renderIsVisible": true, + "renderIsShadowCaster": true, + "componentName": "Mesh Renderer" + }, + "RigidBodyComponent": { + "properties": { + "isActive": true, + "motionType": 2, + "layer": 1, + "shapeType": 0, + "shapeParams": { + "x": 1.0, + "y": 0.0, + "z": 0.0 + } + }, + "componentName": "New RigidBodyComponent" + } + } } ] } diff --git a/assets/settings.willengine b/assets/settings.willengine index d4456c7c..8e308370 100644 --- a/assets/settings.willengine +++ b/assets/settings.willengine @@ -6,9 +6,9 @@ }, "mainLight": { "direction": [ - -0.2588678002357483, - -0.9482336640357971, - -0.18395733833312988 + -0.20589105784893036, + -0.7541796565055847, + -0.6235559582710266 ], "color": [ 0.20000000298023224, @@ -19,15 +19,15 @@ }, "cameraProperties": { "position": [ - 108.51939392089844, - 135.32415771484375, - -53.729923248291016 + -12.019723892211914, + 43.62346267700195, + -4.528595447540283 ], "rotation": [ - 0.10572174191474915, - -0.3543924391269684, - -0.04037834703922272, - -0.9282233715057373 + 0.11933307349681854, + 0.8700804710388184, + 0.25767987966537476, + -0.4028905928134918 ], "fov": 1.3089969158172607, "aspectRatio": 1.7777777910232544, diff --git a/shaders/shadows/contact_shadow_pass.comp b/shaders/shadows/contact_shadow_pass.comp index 8619a211..3c3a3935 100644 --- a/shaders/shadows/contact_shadow_pass.comp +++ b/shaders/shadows/contact_shadow_pass.comp @@ -166,8 +166,14 @@ void main() { int bias = bilinear > 0 ? 1 : -1; vec2 offset_xy = vec2(x_axis_major ? 0 : bias, x_axis_major ? bias : 0); - depths.x = textureLod(depthImage, read_xy * sceneData.texelSize, 0).r; - depths.y = textureLod(depthImage, (read_xy + offset_xy) * sceneData.texelSize, 0).r; + vec2 read_xy_one = read_xy * sceneData.texelSize; + read_xy_one.y = 1 - read_xy_one.y; + vec2 read_xy_two = (read_xy + offset_xy) * sceneData.texelSize; + read_xy_two.y = 1 - read_xy_two.y; + //depths.x = textureLod(depthImage, read_xy * sceneData.texelSize, 0).r; + depths.x = textureLod(depthImage, read_xy_one, 0).r; + //depths.y = textureLod(depthImage, (read_xy + offset_xy) * sceneData.texelSize, 0).r; + depths.y = textureLod(depthImage, read_xy_two, 0).r; // Depth thresholds (bilinear/shadow thickness) are based on a fractional ratio of the difference between sampled depth and the far clip depth depth_thickness_scale[i] = abs(FAR_DEPTH_VALUE - depths.x); @@ -209,7 +215,7 @@ void main() { } // Using early out, and no debug mode is enabled? - // if (pushConstants.bUseEarlyOut == 1 && (inParameters.DebugOutputWaveIndex == false && inParameters.DebugOutputThreadIndex == false && inParameters.DebugOutputEdgeMask == false)) + // if (pushConstants.bUseEarlyOut == 1 && pushConstants.debugMode == 0) // { // // read the depth of the pixel we are shadowing, and early-out // // The compiler will typically rearrange this code to put it directly after the first depth read @@ -360,6 +366,9 @@ void main() { case 3: result = fract(ivec3(gl_WorkGroupID).x / float(WAVE_SIZE)); break; + case 4: + imageStore(debugImage, ivec2(write_xy), vec4(vec3(pixel_distance * sceneData.texelSize.x), 1.0f)); + return; } imageStore(debugImage, ivec2(write_xy), vec4(vec3(result), 1.0f)); diff --git a/src/core/engine.cpp b/src/core/engine.cpp index b92a0a9c..80840898 100644 --- a/src/core/engine.cpp +++ b/src/core/engine.cpp @@ -646,11 +646,11 @@ void Engine::draw(float deltaTime) contact_shadows_pipeline::ContactShadowsDrawInfo contactDrawInfo{ camera, mainLight, - contactShadowDebug, - bilinearThreshold, + sssPush, sceneDataDescriptorBuffer.getDescriptorBufferBindingInfo(), sceneDataDescriptorBuffer.getDescriptorBufferSize() * currentFrameOverlap }; + contactShadowsPipeline->draw(cmd, contactDrawInfo); const deferred_resolve::DeferredResolveDrawInfo deferredResolveDrawInfo{ diff --git a/src/core/engine.h b/src/core/engine.h index c2c25251..0dd498a8 100644 --- a/src/core/engine.h +++ b/src/core/engine.h @@ -182,8 +182,7 @@ class Engine int32_t csmPcf{1}; int32_t deferredDebug{0}; int32_t gtaoDebug{4}; - int32_t contactShadowDebug{0}; - float bilinearThreshold{0.2f}; + contact_shadows_pipeline::ContactShadowsPushConstants sssPush; bool bDrawTerrainLines{false}; bool bPausePhysics{true}; bool bDisableJitter{false}; diff --git a/src/renderer/imgui_wrapper.cpp b/src/renderer/imgui_wrapper.cpp index 44f82f94..2b5f3abb 100644 --- a/src/renderer/imgui_wrapper.cpp +++ b/src/renderer/imgui_wrapper.cpp @@ -1085,8 +1085,16 @@ void ImguiWrapper::imguiInterface(Engine* engine) ImGui::End(); if (ImGui::Begin("Discardable Debug")) { - ImGui::SliderInt("Contact Shadow Debug", &engine->contactShadowDebug, 0, 3); - ImGui::InputFloat("Blinear Threshold", &engine->bilinearThreshold); + ImGui::InputFloat("Blinear Threshold", &engine->sssPush.bilinearThreshold); + ImGui::InputFloat("Surface Thickness", &engine->sssPush.surfaceThickness); + ImGui::InputFloat("Shadow Contrast", &engine->sssPush.shadowContrast); + + ImGui::SliderInt("Contact Shadow Debug", &engine->sssPush.debugMode, 0, 4); + + ImGui::SliderInt("Ignore Edge Pixels", &engine->sssPush.bIgnoreEdgePixels, 0, 1); + ImGui::SliderInt("Use Precision Offset", &engine->sssPush.bUsePrecisionOffset, 0, 1); + ImGui::SliderInt("Bilinear Offset Sampling Mode", &engine->sssPush.bBilinearSamplingOffsetMode, 0, 1); + if (contactShadowsOutputImguiId == VK_NULL_HANDLE) { if (engine->contactShadowsPipeline->debugImage.imageView != VK_NULL_HANDLE) { diff --git a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp index 1a1b0636..b946f7da 100644 --- a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp +++ b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline.cpp @@ -123,9 +123,7 @@ void ContactShadowsPipeline::draw(VkCommandBuffer cmd, const ContactShadowsDrawI vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); - ContactShadowsPushConstants push{}; - push.debugMode = static_cast(drawInfo.debug); - push.bilinearThreshold = drawInfo.v; + ContactShadowsPushConstants push{drawInfo.push}; const DispatchList dispatchList = buildDispatchList(drawInfo.camera, drawInfo.light); @@ -177,7 +175,7 @@ DispatchList ContactShadowsPipeline::buildDispatchList(const Camera* camera, con { DispatchList result = {}; - glm::vec4 lightProjection = camera->getViewProjMatrix() * glm::vec4(mainLight.getDirection(), 0.0f); + glm::vec4 lightProjection = camera->getViewProjMatrix() * glm::vec4(-mainLight.getDirection(), 0.0f); // Floating point division in the shader has a practical limit for precision when the light is *very* far off screen (~1m pixels+) // So when computing the light XY coordinate, use an adjusted w value to handle these extreme values diff --git a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h index f737b6d0..d9fee6ab 100644 --- a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h +++ b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h @@ -50,9 +50,10 @@ struct ContactShadowsPushConstants int32_t bBilinearSamplingOffsetMode{0}; glm::vec2 depthBounds{0, 1}; - int32_t bUseEarlyOut{0}; + int32_t bUseEarlyOut{1}; - ContactShadowsDebugMode debugMode{ContactShadowsDebugMode::NONE}; + //ContactShadowsDebugMode debugMode{ContactShadowsDebugMode::NONE}; + int32_t debugMode{0}; glm::ivec2 waveOffset{0}; glm::vec4 lightCoordinate{0.0f}; @@ -62,8 +63,7 @@ struct ContactShadowsDrawInfo { Camera* camera; DirectionalLight light; - int32_t debug; - float v; + ContactShadowsPushConstants push; VkDescriptorBufferBindingInfoEXT sceneDataBinding{}; VkDeviceSize sceneDataOffset{0}; }; From 4e2c43c228620951f99ab8f889424b5b0fcefd92 Mon Sep 17 00:00:00 2001 From: Williscool13 Date: Mon, 21 Apr 2025 22:27:37 +0700 Subject: [PATCH 13/15] Contact shadow passed to deferred resolve. --- assets/settings.willengine | 14 ++++----- shaders/deferredResolve.comp | 8 ++++- shaders/shadows/contact_shadow_pass.comp | 29 ++++++++++++------- src/core/engine.cpp | 1 + src/renderer/imgui_wrapper.cpp | 4 +-- .../deferred_resolve_pipeline.cpp | 8 ++++- .../deferred_resolve_pipeline_types.h | 1 + src/renderer/resource_manager.cpp | 3 +- 8 files changed, 45 insertions(+), 23 deletions(-) diff --git a/assets/settings.willengine b/assets/settings.willengine index 8e308370..544f484b 100644 --- a/assets/settings.willengine +++ b/assets/settings.willengine @@ -19,15 +19,15 @@ }, "cameraProperties": { "position": [ - -12.019723892211914, - 43.62346267700195, - -4.528595447540283 + 97.62080383300781, + 85.33240509033203, + -62.117923736572266 ], "rotation": [ - 0.11933307349681854, - 0.8700804710388184, - 0.25767987966537476, - -0.4028905928134918 + -0.05187241733074188, + -0.3708416819572449, + -0.020737167447805405, + 0.9270144104957581 ], "fov": 1.3089969158172607, "aspectRatio": 1.7777777910232544, diff --git a/shaders/deferredResolve.comp b/shaders/deferredResolve.comp index 517fed8a..b4cbff63 100644 --- a/shaders/deferredResolve.comp +++ b/shaders/deferredResolve.comp @@ -17,8 +17,9 @@ layout (set = 1, binding = 2) uniform sampler2D pbrRenderTarget; layout (set = 1, binding = 3) uniform sampler2D depthBuffer; layout (set = 1, binding = 4) uniform sampler2D velocityBuffer;// velocity buffer is not actually used in this deferred resolve layout (set = 1, binding = 5) uniform sampler2D aoBuffer; +layout (set = 1, binding = 6) uniform sampler2D contactShadowBuffer; -layout (rgba16f, set = 1, binding = 6) uniform image2D outputImage; +layout (rgba16f, set = 1, binding = 7) uniform image2D outputImage; layout (set = 2, binding = 0) uniform samplerCube environmentDiffuseAndSpecular; layout (set = 2, binding = 1) uniform sampler2D lut; @@ -192,5 +193,10 @@ void main() { float ao = texture(aoBuffer, uv).r; imageStore(outputImage, screenPos, vec4(vec3(ao), 1.0f)); break; + case 10: + float contactShadow = texture(contactShadowBuffer, uv).r; + imageStore(outputImage, screenPos, vec4(vec3(contactShadow), 1.0f)); + break; + } } \ No newline at end of file diff --git a/shaders/shadows/contact_shadow_pass.comp b/shaders/shadows/contact_shadow_pass.comp index 3c3a3935..b9602452 100644 --- a/shaders/shadows/contact_shadow_pass.comp +++ b/shaders/shadows/contact_shadow_pass.comp @@ -1,4 +1,6 @@ #version 460 +//#extension GL_KHR_shader_subgroup_vote : require +//#extension GL_KHR_shader_subgroup_basic : require #include "scene.glsl" @@ -143,6 +145,8 @@ void main() { bool is_edge = false; bool skip_pixel = false; vec2 write_xy = floor(pixel_xy); + // Flip because of Vulkan + write_xy.y = sceneData.renderTargetSize.y - write_xy.y; for (i = 0; i < READ_COUNT; i++) { @@ -166,13 +170,12 @@ void main() { int bias = bilinear > 0 ? 1 : -1; vec2 offset_xy = vec2(x_axis_major ? 0 : bias, x_axis_major ? bias : 0); + // Flip because vulkan vec2 read_xy_one = read_xy * sceneData.texelSize; read_xy_one.y = 1 - read_xy_one.y; vec2 read_xy_two = (read_xy + offset_xy) * sceneData.texelSize; read_xy_two.y = 1 - read_xy_two.y; - //depths.x = textureLod(depthImage, read_xy * sceneData.texelSize, 0).r; depths.x = textureLod(depthImage, read_xy_one, 0).r; - //depths.y = textureLod(depthImage, (read_xy + offset_xy) * sceneData.texelSize, 0).r; depths.y = textureLod(depthImage, read_xy_two, 0).r; // Depth thresholds (bilinear/shadow thickness) are based on a fractional ratio of the difference between sampled depth and the far clip depth @@ -214,6 +217,7 @@ void main() { pixel_xy += xy_delta * direction; } + // Commenting out early out code because I'm not able to figure out the glsl equivalent to the subgroup/wave lane shit // Using early out, and no debug mode is enabled? // if (pushConstants.bUseEarlyOut == 1 && pushConstants.debugMode == 0) // { @@ -222,10 +226,10 @@ void main() { // skip_pixel = EarlyOutPixel(DEPTH_BOUNDS, write_xy, sampling_depth[0]); // // // are all threads in this wave out of bounds? - // bool early_out = WaveActiveAnyTrue(!skip_pixel) == false; + // bool earl_out = subgroupAny(!skip_pixel) == false; // // // WaveGetLaneCount returns the hardware wave size - // if (WaveGetLaneCount() == WAVE_SIZE) + // if (gl_SubgroupSize == WAVE_SIZE) // { // // Optimal case: // // If each wavefront is just a single wave, then we can trivially early-out. @@ -358,19 +362,22 @@ void main() { { switch (pushConstants.debugMode){ case 1: - result = is_edge ? 1 : 0; + float edge = is_edge ? 1 : 0; + imageStore(debugImage, ivec2(write_xy), vec4(vec3(edge), 1.0f)); break; case 2: - result = (gl_LocalInvocationID.x / float(WAVE_SIZE)); + float invocIndex = (gl_LocalInvocationID.x / float(WAVE_SIZE)); + imageStore(debugImage, ivec2(write_xy), vec4(vec3(invocIndex), 1.0f)); break; case 3: - result = fract(ivec3(gl_WorkGroupID).x / float(WAVE_SIZE)); + float workGroup = fract(ivec3(gl_WorkGroupID).x / float(WAVE_SIZE)); + imageStore(debugImage, ivec2(write_xy), vec4(vec3(workGroup), 1.0f)); + break; + default: + imageStore(debugImage, ivec2(write_xy), vec4(vec3(result), 1.0f)); break; - case 4: - imageStore(debugImage, ivec2(write_xy), vec4(vec3(pixel_distance * sceneData.texelSize.x), 1.0f)); - return; } - imageStore(debugImage, ivec2(write_xy), vec4(vec3(result), 1.0f)); + imageStore(contactShadow, ivec2(write_xy), vec4(vec3(result), 1.0f)); } } diff --git a/src/core/engine.cpp b/src/core/engine.cpp index 80840898..86d0a4ae 100644 --- a/src/core/engine.cpp +++ b/src/core/engine.cpp @@ -232,6 +232,7 @@ void Engine::initRenderer() depthImage.imageView, velocityRenderTarget.imageView, ambientOcclusionPipeline->getAmbientOcclusionRenderTarget().imageView, + contactShadowsPipeline->getContactShadowRenderTarget().imageView, drawImage.imageView, resourceManager->getDefaultSamplerLinear() }; diff --git a/src/renderer/imgui_wrapper.cpp b/src/renderer/imgui_wrapper.cpp index 2b5f3abb..674dd09a 100644 --- a/src/renderer/imgui_wrapper.cpp +++ b/src/renderer/imgui_wrapper.cpp @@ -224,7 +224,7 @@ void ImguiWrapper::imguiInterface(Engine* engine) ImGui::Checkbox("Disable Physics", &engine->bPausePhysics); ImGui::Text("Deferred Debug"); - const char* deferredDebugOptions[]{"None", "Depth", "Velocity", "Albedo", "Normal", "PBR", "Shadows", "Cascade Level", "nDotL", "AO"}; + const char* deferredDebugOptions[]{"None", "Depth", "Velocity", "Albedo", "Normal", "PBR", "Shadows", "Cascade Level", "nDotL", "AO", "Contact Shadows"}; ImGui::Combo("Deferred Debug", &engine->deferredDebug, deferredDebugOptions, IM_ARRAYSIZE(deferredDebugOptions)); ImGui::Separator(); @@ -1089,7 +1089,7 @@ void ImguiWrapper::imguiInterface(Engine* engine) ImGui::InputFloat("Surface Thickness", &engine->sssPush.surfaceThickness); ImGui::InputFloat("Shadow Contrast", &engine->sssPush.shadowContrast); - ImGui::SliderInt("Contact Shadow Debug", &engine->sssPush.debugMode, 0, 4); + ImGui::SliderInt("Contact Shadow Debug", &engine->sssPush.debugMode, 0, 3); ImGui::SliderInt("Ignore Edge Pixels", &engine->sssPush.bIgnoreEdgePixels, 0, 1); ImGui::SliderInt("Use Precision Offset", &engine->sssPush.bUsePrecisionOffset, 0, 1); diff --git a/src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline.cpp b/src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline.cpp index 1a92774d..3813756a 100644 --- a/src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline.cpp +++ b/src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline.cpp @@ -54,7 +54,7 @@ will_engine::deferred_resolve::DeferredResolvePipeline::~DeferredResolvePipeline void will_engine::deferred_resolve::DeferredResolvePipeline::setupDescriptorBuffer(const DeferredResolveDescriptor& drawInfo) { std::vector renderTargetDescriptors; - renderTargetDescriptors.reserve(6); + renderTargetDescriptors.reserve(8); VkDescriptorImageInfo normalTarget = {}; normalTarget.sampler = drawInfo.sampler; @@ -86,6 +86,11 @@ void will_engine::deferred_resolve::DeferredResolvePipeline::setupDescriptorBuff aoTarget.imageView = drawInfo.aoTarget; aoTarget.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + VkDescriptorImageInfo contactShadow = {}; + contactShadow.sampler = drawInfo.sampler; + contactShadow.imageView = drawInfo.contactShadowsTarget; + contactShadow.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + VkDescriptorImageInfo drawImageTarget = {}; drawImageTarget.imageView = drawInfo.outputTarget; drawImageTarget.imageLayout = VK_IMAGE_LAYOUT_GENERAL; @@ -96,6 +101,7 @@ void will_engine::deferred_resolve::DeferredResolvePipeline::setupDescriptorBuff renderTargetDescriptors.push_back({VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, depthImageTarget, false}); renderTargetDescriptors.push_back({VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, velocityTarget, false}); renderTargetDescriptors.push_back({VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, aoTarget, false}); + renderTargetDescriptors.push_back({VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, contactShadow, false}); renderTargetDescriptors.push_back({VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, drawImageTarget, false}); resourceManager.setupDescriptorBufferSampler(resolveDescriptorBuffer, renderTargetDescriptors, 0); diff --git a/src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline_types.h b/src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline_types.h index e0e5fb10..9d00b1de 100644 --- a/src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline_types.h +++ b/src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline_types.h @@ -17,6 +17,7 @@ struct DeferredResolveDescriptor VkImageView depthTarget; VkImageView velocityTarget; VkImageView aoTarget; + VkImageView contactShadowsTarget; VkImageView outputTarget; VkSampler sampler; diff --git a/src/renderer/resource_manager.cpp b/src/renderer/resource_manager.cpp index 59a4b1a4..ce6d907a 100644 --- a/src/renderer/resource_manager.cpp +++ b/src/renderer/resource_manager.cpp @@ -122,7 +122,8 @@ will_engine::ResourceManager::ResourceManager(const VulkanContext& context, Imme layoutBuilder.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); // Depth layoutBuilder.addBinding(4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); // Velocity layoutBuilder.addBinding(5, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); // AO - layoutBuilder.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); // Output + layoutBuilder.addBinding(6, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); // Screen Space Contact Shadows + layoutBuilder.addBinding(7, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); // Output renderTargetsLayout = layoutBuilder.build(context.device, VK_SHADER_STAGE_COMPUTE_BIT, nullptr, VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT); } From d7396d4f00a57b6ea06caef736acf74e73188027 Mon Sep 17 00:00:00 2001 From: Williscool13 Date: Mon, 21 Apr 2025 22:42:30 +0700 Subject: [PATCH 14/15] Contact shadows included in lighting calculations --- assets/settings.willengine | 14 +++++++------- shaders/deferredResolve.comp | 14 +++++++++++--- src/core/engine.cpp | 2 ++ src/core/engine.h | 2 ++ src/renderer/imgui_wrapper.cpp | 3 +++ .../deferred_resolve/deferred_resolve_pipeline.cpp | 3 ++- .../deferred_resolve_pipeline_types.h | 3 +++ 7 files changed, 30 insertions(+), 11 deletions(-) diff --git a/assets/settings.willengine b/assets/settings.willengine index 544f484b..47e1cc2c 100644 --- a/assets/settings.willengine +++ b/assets/settings.willengine @@ -19,15 +19,15 @@ }, "cameraProperties": { "position": [ - 97.62080383300781, - 85.33240509033203, - -62.117923736572266 + -6.821944236755371, + 39.92100143432617, + -4.328110694885254 ], "rotation": [ - -0.05187241733074188, - -0.3708416819572449, - -0.020737167447805405, - 0.9270144104957581 + -0.07350965589284897, + 0.9242773056030273, + 0.2296377420425415, + 0.29592984914779663 ], "fov": 1.3089969158172607, "aspectRatio": 1.7777777910232544, diff --git a/shaders/deferredResolve.comp b/shaders/deferredResolve.comp index b4cbff63..77f54c92 100644 --- a/shaders/deferredResolve.comp +++ b/shaders/deferredResolve.comp @@ -47,6 +47,7 @@ layout (push_constant) uniform PushConstants { int height; int debug; int disableShadows; + int disableContactShadows; int pcfLevel; float nearPlane; float farPlane; @@ -124,12 +125,19 @@ void main() { float normalOffsetScale = max(offset, dot(N, L) * offset); vec3 offsetPosition = viewPosition + N * normalOffsetScale; vec4 worldPosition = sceneData.invView * vec4(offsetPosition, 1.0f); - float _tempShadowFactor = getShadowFactorBlend(pushConstants.pcfLevel, worldPosition.xyz, abs(viewPosition.z), shadowCascadeData.cascadeSplits, shadowCascadeData.lightViewProj, shadowMapSampler, shadowCascadeData.nearShadowPlane, shadowCascadeData.farShadowPlane); - float shadowFactor = clamp(smoothstep(-0.15f, 0.5f, dot(N, L)) * _tempShadowFactor, 0, 1); + //float _tempShadowFactor = getShadowFactorBlend(pushConstants.pcfLevel, worldPosition.xyz, abs(viewPosition.z), shadowCascadeData.cascadeSplits, shadowCascadeData.lightViewProj, shadowMapSampler, shadowCascadeData.nearShadowPlane, shadowCascadeData.farShadowPlane); + //float shadowFactor = clamp(smoothstep(-0.15f, 0.5f, dot(N, L)) * _tempShadowFactor, 0, 1); - if (pushConstants.disableShadows == 1) { + float shadowFactor = getShadowFactorBlend(pushConstants.pcfLevel, worldPosition.xyz, abs(viewPosition.z), shadowCascadeData.cascadeSplits, shadowCascadeData.lightViewProj, shadowMapSampler, shadowCascadeData.nearShadowPlane, shadowCascadeData.farShadowPlane); + if (pushConstants.disableShadows == 1){ shadowFactor = 1.0f; } + float contactShadow = texture(contactShadowBuffer, uv).r; + if (pushConstants.disableContactShadows == 1){ + contactShadow = 1.0f; + } + + shadowFactor = min(shadowFactor, contactShadow); // Direct lighting with shadows vec3 directLight = (diffuse + specular) * nDotL * shadowFactor * shadowCascadeData.directionalLightData.intensity * shadowCascadeData.directionalLightData.color; diff --git a/src/core/engine.cpp b/src/core/engine.cpp index 86d0a4ae..0a9455b9 100644 --- a/src/core/engine.cpp +++ b/src/core/engine.cpp @@ -666,6 +666,8 @@ void Engine::draw(float deltaTime) cascadedShadowMap->getCascadedShadowMapSamplerBuffer().getDescriptorBufferBindingInfo(), camera->getNearPlane(), camera->getFarPlane(), + bEnableShadows, + bEnableContactShadows }; deferredResolvePipeline->draw(cmd, deferredResolveDrawInfo); diff --git a/src/core/engine.h b/src/core/engine.h index 0dd498a8..7307fec2 100644 --- a/src/core/engine.h +++ b/src/core/engine.h @@ -188,6 +188,8 @@ class Engine bool bDisableJitter{false}; bool bHideTransparents{true}; bool bEnableGTAO{true}; + bool bEnableShadows{true}; + bool bEnableContactShadows{true}; void hotReloadShaders() const; diff --git a/src/renderer/imgui_wrapper.cpp b/src/renderer/imgui_wrapper.cpp index 674dd09a..1ab11205 100644 --- a/src/renderer/imgui_wrapper.cpp +++ b/src/renderer/imgui_wrapper.cpp @@ -207,6 +207,9 @@ void ImguiWrapper::imguiInterface(Engine* engine) engine->gtaoDebug = 0; } } + ImGui::Checkbox("Enable Shadows", &engine->bEnableShadows); + ImGui::Checkbox("Enable Contact Shadows", &engine->bEnableContactShadows); + ImGui::Separator(); ImGui::Text("Main Directional Light"); float direction[3] = {engine->mainLight.direction.x, engine->mainLight.direction.y, engine->mainLight.direction.z}; diff --git a/src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline.cpp b/src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline.cpp index 3813756a..88a9e257 100644 --- a/src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline.cpp +++ b/src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline.cpp @@ -125,7 +125,8 @@ void will_engine::deferred_resolve::DeferredResolvePipeline::draw(VkCommandBuffe pushConstants.width = RENDER_EXTENT_WIDTH; pushConstants.height = RENDER_EXTENT_HEIGHT; pushConstants.deferredDebug = drawInfo.deferredDebug; - pushConstants.disableShadows = 0; + pushConstants.disableShadows = drawInfo.bEnableShadows ? 0 : 1; + pushConstants.disableContactShadows = drawInfo.bEnableContactShadows ? 0 : 1; pushConstants.pcfLevel = drawInfo.csmPcf; pushConstants.nearPlane = drawInfo.nearPlane; pushConstants.farPlane = drawInfo.farPlane; diff --git a/src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline_types.h b/src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline_types.h index 9d00b1de..eb8cbdf6 100644 --- a/src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline_types.h +++ b/src/renderer/pipelines/geometry/deferred_resolve/deferred_resolve_pipeline_types.h @@ -29,6 +29,7 @@ struct DeferredResolvePushConstants int32_t height{900}; int32_t deferredDebug{0}; int32_t disableShadows{0}; + int32_t disableContactShadows{0}; int32_t pcfLevel{5}; float nearPlane{1000.0f}; float farPlane{0.1f}; @@ -47,6 +48,8 @@ struct DeferredResolveDrawInfo VkDescriptorBufferBindingInfoEXT cascadeSamplerBinding{}; float nearPlane{1000.0f}; float farPlane{0.1f}; + bool bEnableShadows{true}; + bool bEnableContactShadows{true}; }; } From e5b4fae06e89350c327ce191b2c1b77d74880a81 Mon Sep 17 00:00:00 2001 From: Williscool13 Date: Tue, 22 Apr 2025 19:34:18 +0700 Subject: [PATCH 15/15] Finalize contact shadows. --- assets/settings.willengine | 22 +++++++++---------- shaders/deferredResolve.comp | 1 + .../contact_shadows_pipeline_types.h | 2 +- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/assets/settings.willengine b/assets/settings.willengine index 47e1cc2c..d287a88a 100644 --- a/assets/settings.willengine +++ b/assets/settings.willengine @@ -6,28 +6,28 @@ }, "mainLight": { "direction": [ - -0.20589105784893036, - -0.7541796565055847, - -0.6235559582710266 + -0.005322144832462072, + -0.9349234104156494, + -0.35480964183807373 ], "color": [ 0.20000000298023224, 0.4000000059604645, 1.0 ], - "intensity": 2.0 + "intensity": 50.0 }, "cameraProperties": { "position": [ - -6.821944236755371, - 39.92100143432617, - -4.328110694885254 + 112.34994506835938, + 83.79894256591797, + -50.39910125732422 ], "rotation": [ - -0.07350965589284897, - 0.9242773056030273, - 0.2296377420425415, - 0.29592984914779663 + -0.4555923640727997, + -0.2922893166542053, + -0.16135302186012268, + 0.8252077102661133 ], "fov": 1.3089969158172607, "aspectRatio": 1.7777777910232544, diff --git a/shaders/deferredResolve.comp b/shaders/deferredResolve.comp index 77f54c92..014c0c53 100644 --- a/shaders/deferredResolve.comp +++ b/shaders/deferredResolve.comp @@ -153,6 +153,7 @@ void main() { ao = texture(aoBuffer, uv).r; } vec3 ambient = (kD * reflectionDiffuse + reflectionSpecular) * ao; + ambient *= mix(0.4, 1.0, min(shadowFactor, nDotL)); vec3 finalColor = directLight + ambient; imageStore(outputImage, screenPos, vec4(finalColor, albedo.w)); diff --git a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h index d9fee6ab..0311463a 100644 --- a/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h +++ b/src/renderer/pipelines/shadows/contact_shadow/contact_shadows_pipeline_types.h @@ -42,7 +42,7 @@ struct DispatchList struct ContactShadowsPushConstants { float surfaceThickness{0.005}; - float bilinearThreshold{0.02}; + float bilinearThreshold{0.05}; float shadowContrast{2}; int32_t bIgnoreEdgePixels{1};