diff --git a/Engine/Core/Configuration/PNDefaults.swift b/Engine/Core/Configuration/PNDefaults.swift index 036ca78f..c63ab41c 100644 --- a/Engine/Core/Configuration/PNDefaults.swift +++ b/Engine/Core/Configuration/PNDefaults.swift @@ -88,6 +88,8 @@ public struct PNDefaults { /// Exponent used to control the strength and contrast of the occlusion effect. public var power: Float16 = 16 /// Blur sigma - public var blurSigma: Float = 5.0 + public var blurSigma: Float = 2.0 + /// Rendering scale - scale of the image in relation to frame resolution + public var renderingScale: Float = 0.33 } } diff --git a/Engine/Core/Rendering/Jobs/SSAO/PNSSAOJob.swift b/Engine/Core/Rendering/Jobs/SSAO/PNSSAOJob.swift index 377628e7..f0adb523 100644 --- a/Engine/Core/Rendering/Jobs/SSAO/PNSSAOJob.swift +++ b/Engine/Core/Rendering/Jobs/SSAO/PNSSAOJob.swift @@ -34,11 +34,11 @@ struct PNSSAOJob: PNComputeJob { self.noiseBuffer = noiseBuffer self.kernelBuffer.upload(data: samples) self.noiseBuffer.upload(data: noise) - guard let inputTexture = prTexture.texture else { + guard let outputTexture = outputTexture.texture else { return nil } - dispatchSize = MTLSize(width: inputTexture.width, - height: inputTexture.height) + dispatchSize = MTLSize(width: outputTexture.width, + height: outputTexture.height) } func compute(encoder: MTLComputeCommandEncoder, supply: PNFrameSupply) { let time = Int32(Date.timeIntervalSinceReferenceDate) diff --git a/Engine/Core/Rendering/Stages/PNPipeline.swift b/Engine/Core/Rendering/Stages/PNPipeline.swift index a123be11..5ee9739b 100644 --- a/Engine/Core/Rendering/Stages/PNPipeline.swift +++ b/Engine/Core/Rendering/Stages/PNPipeline.swift @@ -36,6 +36,7 @@ class PNPipeline: PNStage { shadowTextureSize: PNDefaults.shared.rendering.shadowSize), let ssaoStage = PNSSAOStage(device: device, renderingSize: renderingSize, + scaleSize: PNDefaults.shared.shaders.ssao.renderingScale, prTexture: gBufferStage.io.output.color[2], nmTexture: gBufferStage.io.output.color[1], blurSigma: PNDefaults.shared.shaders.ssao.blurSigma), diff --git a/Engine/Core/Rendering/Stages/PNSSAOStage.swift b/Engine/Core/Rendering/Stages/PNSSAOStage.swift index ed6570b0..0ae8b31f 100644 --- a/Engine/Core/Rendering/Stages/PNSSAOStage.swift +++ b/Engine/Core/Rendering/Stages/PNSSAOStage.swift @@ -13,15 +13,19 @@ struct PNSSAOStage: PNStage { private var ssaoKernel: PNSSAOJob init?(device: MTLDevice, renderingSize: CGSize, + scaleSize: Float, prTexture: PNTextureProvider, nmTexture: PNTextureProvider, blurSigma: Float) { - guard let ssaoTexture = device.makeTextureSSAOC(size: renderingSize), + + let ssaoTexturesSize = CGSize(width: renderingSize.width * CGFloat(scaleSize), + height: renderingSize.height * CGFloat(scaleSize)) + guard let ssaoTexture = device.makeTextureSSAOC(size: ssaoTexturesSize), let ssaoKernel = PNSSAOJob.make(device: device, prTexture: prTexture, nmTexture: nmTexture, outputTexture: PNStaticTexture(ssaoTexture)), - let gaussTexture = device.makeTexture(descriptor: .ssaoC(size: renderingSize)) else { + let gaussTexture = device.makeTexture(descriptor: .ssaoC(size: ssaoTexturesSize)) else { return nil } self.ssaoTexture = ssaoTexture diff --git a/Engine/Shaders/SSAO.metal b/Engine/Shaders/SSAO.metal index d999ef35..6249fe3d 100644 --- a/Engine/Shaders/SSAO.metal +++ b/Engine/Shaders/SSAO.metal @@ -34,13 +34,16 @@ kernel void kernelSSAO(texture2d nm [[texture(kAttributeSsao int seed = positionContinuousBuffer + time; Random random = Random(seed); uint2 positionXY = inposition.xy; - float3 worldPosition = pr.read(positionXY).xyz; - float3 normal = normalize(float3(nm.read(positionXY).xyz)); + float2 texcoord = float2(static_cast(inposition.x) / out.get_width(), + static_cast(inposition.y) / out.get_height()); + float2 resolutionMultiplier(pr.get_width(), pr.get_height()); + uint2 prnmSamplePosition = uint2(texcoord * resolutionMultiplier); + float3 worldPosition = pr.read(prnmSamplePosition).xyz; + float3 normal = normalize(float3(nm.read(prnmSamplePosition).xyz)); float3 randomVector = noise[int(random.random() * noiseCount)]; float3 tangent = normalize(randomVector - normal * dot(randomVector, normal)); float3 bitangent = normalize(cross(normal, tangent)); float3x3 TBN = float3x3(tangent, bitangent, normal); - float2 resolutionMultiplier(pr.get_width(), pr.get_height()); half occlusion = 0.0; for(int i = 0; i < sampleCount; ++i) { float3 neighbourWorldPosition = worldPosition + (TBN * samples[i]);