Skip to content

Commit 005ead8

Browse files
committed
Fixed ambient occlusion texture sampling, worked on some shading artifacts.
1 parent bd99577 commit 005ead8

File tree

4 files changed

+30
-48
lines changed

4 files changed

+30
-48
lines changed

Molecules/Rendering/MetalRenderView.swift

-2
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,9 @@ class MetalRenderView: MTKView {
6666

6767
override func draw(_ rect:CGRect) {
6868
guard let drawable = self.currentDrawable else {
69-
print("No drawable")
7069
return
7170
}
7271
guard let moleculeRenderer = moleculeRenderer else {
73-
print("No molecule renderer")
7472
return
7573
}
7674
if let commandBuffer = sharedMetalRenderingDevice.commandQueue.makeCommandBuffer(),

Molecules/Rendering/MoleculeRenderer.swift

+16-30
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ final class MoleculeRenderer {
195195
sphereAmbientOcclusionTexture.label = "Ambient occlustion texture"
196196

197197
// TODO: Extend ambient occlusion to ball-and-stick rendering modes.
198-
if visualizationStyle == .ballAndStick {
198+
if (visualizationStyle == .ballAndStick) || (molecule.atoms.count < 100) {
199199
// Set the ambient lighting texture to all-white for uniform illumination.
200200
if let commandBuffer = sharedMetalRenderingDevice.commandQueue.makeCommandBuffer() {
201201
commandBuffer.clear(texture: sphereAmbientOcclusionTexture, with: MTLClearColorMake(1.0, 1.0, 1.0, 1.0))
@@ -206,25 +206,25 @@ final class MoleculeRenderer {
206206
}
207207

208208
guard let commandBuffer = sharedMetalRenderingDevice.commandQueue.makeCommandBuffer() else { return }
209-
commandBuffer.clear(texture: sphereAmbientOcclusionTexture, with: MTLClearColorMake(0.0, 0.0, 0.0, 0.0))
209+
commandBuffer.clear(texture: sphereAmbientOcclusionTexture, with: MTLClearColorMake(0.0, 0.0, 0.0, 1.0))
210210
let sphereDepthTextureWidth = 1024
211211

212-
let intensityFactor: Float = 0.5 / Float(ambientOcclusionSamplingAngles.count)
213-
// let intensityFactor: Float = 1.0
212+
let depthTextureDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .bgra8Unorm,
213+
width: sphereDepthTextureWidth,
214+
height: sphereDepthTextureWidth,
215+
mipmapped: false)
216+
depthTextureDescriptor.usage = [.renderTarget, .shaderRead, .shaderWrite]
217+
guard let depthTexture = sharedMetalRenderingDevice.device.makeTexture(descriptor: depthTextureDescriptor) else {
218+
fatalError("Could not create depth texture of size: (\(sphereDepthTextureWidth), \(sphereDepthTextureWidth))")
219+
}
220+
depthTexture.label = "Depth texture"
221+
222+
223+
let intensityFactor: Float = 2.0 / Float(ambientOcclusionSamplingAngles.count)
214224
for (theta, phi) in ambientOcclusionSamplingAngles {
215225
var rotationMatrix = Matrix4x4.identity.rotated(angle: theta, x: 1.0, y: 0.0, z: 0.0)
216226
rotationMatrix = rotationMatrix.rotated(angle: phi, x: 0.0, y: 1.0, z: 0.0)
217227

218-
let depthTextureDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .bgra8Unorm,
219-
width: sphereDepthTextureWidth,
220-
height: sphereDepthTextureWidth,
221-
mipmapped: false)
222-
depthTextureDescriptor.usage = [.renderTarget, .shaderRead, .shaderWrite]
223-
guard let depthTexture = sharedMetalRenderingDevice.device.makeTexture(descriptor: depthTextureDescriptor) else {
224-
fatalError("Could not create depth texture of size: (\(sphereDepthTextureWidth), \(sphereDepthTextureWidth))")
225-
}
226-
depthTexture.label = "Depth texture"
227-
228228
renderDepthTexture(targetModelViewProjMatrix: rotationMatrix, buffer: commandBuffer, depthTexture: depthTexture)
229229
renderAmbientOcclusion(targetModelViewProjMatrix: rotationMatrix, buffer: commandBuffer, depthTexture: depthTexture, intensityFactor: intensityFactor)
230230

@@ -239,7 +239,7 @@ final class MoleculeRenderer {
239239
}
240240

241241
func renderDepthTexture(targetModelViewProjMatrix: Matrix4x4, buffer: MTLCommandBuffer, depthTexture: MTLTexture) {
242-
let orthographicMatrix = orthographicMatrix(left: -1.0, right: 1.0, bottom: Float(-1.0 * 1024 / 1024), top: Float(1024 / 1024), near: -1.0, far: 1.0)
242+
let orthographicMatrix = orthographicMatrix(left: -1.0, right: 1.0, bottom: -1.0, top: 1.0, near: -1.0, far: 1.0)
243243

244244
let depthStencilDescriptor1 = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .depth32Float,
245245
width: 1024,
@@ -314,7 +314,7 @@ final class MoleculeRenderer {
314314
}
315315

316316
func renderAmbientOcclusion(targetModelViewProjMatrix: Matrix4x4, buffer: MTLCommandBuffer, depthTexture: MTLTexture, intensityFactor: Float) {
317-
let orthographicMatrix = orthographicMatrix(left: -1.0, right: 1.0, bottom: Float(-1.0 * 1024 / 1024), top: Float(1024 / 1024), near: -1.0, far: 1.0)
317+
let orthographicMatrix = orthographicMatrix(left: -1.0, right: 1.0, bottom: -1.0, top: 1.0, near: -1.0, far: 1.0)
318318

319319
let renderPass = MTLRenderPassDescriptor()
320320
renderPass.colorAttachments[0].texture = sphereAmbientOcclusionTexture
@@ -375,20 +375,6 @@ final class MoleculeRenderer {
375375
}
376376

377377
func renderMoleculeFrame(width: CGFloat, height: CGFloat, buffer: MTLCommandBuffer, renderPass: MTLRenderPassDescriptor) {
378-
let sphereDepthTextureWidth = 1024
379-
let depthTextureDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .bgra8Unorm,
380-
width: sphereDepthTextureWidth,
381-
height: sphereDepthTextureWidth,
382-
mipmapped: false)
383-
depthTextureDescriptor.usage = [.renderTarget, .shaderRead, .shaderWrite]
384-
guard let depthTexture = sharedMetalRenderingDevice.device.makeTexture(descriptor: depthTextureDescriptor) else {
385-
fatalError("Could not create depth texture of size: (\(sphereDepthTextureWidth), \(sphereDepthTextureWidth))")
386-
}
387-
depthTexture.label = "Depth texture"
388-
// renderDepthTexture(buffer: buffer, depthTexture: depthTexture)
389-
// renderAmbientOcclusion(buffer: buffer, depthTexture: depthTexture, intensityFactor: 1.0)
390-
391-
392378
let orthographicMatrix = orthographicMatrix(left: -1.0, right: 1.0, bottom: Float(-1.0 * height / width), top: Float(height / width), near: -1.0, far: 1.0)
393379

394380
renderPass.colorAttachments[0].clearColor = MTLClearColorMake(0.0, 0.0, 0.0, 1.0)

Molecules/Rendering/Shaders/SphereAmbientOcclusion.metal

+8-9
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,12 @@ fragment half4 sphereAmbientOcclusionFragment(SphereAmbientOcclusionVertexIO fra
101101
currentPositionCoordinate.y = 1.0 - currentPositionCoordinate.y;
102102
float previousDepthValue = depthFromEncodedColor(float4(depthTexture.sample(depthSampler, currentPositionCoordinate.xy)));
103103

104-
return half4(1.0, 1.0, 1.0, 1.0);
105-
// if ( (floor(currentPositionCoordinate.z * 765.0 - 5.0)) <= (ceil(previousDepthValue * 765.0)) )
106-
// {
107-
// return half4(half3(uniform.intensityFactor), 1.0h);
108-
// }
109-
// else
110-
// {
111-
// return half4(0.0h, 0.0h, 0.0h, 1.0h);
112-
// }
104+
if ( (floor(currentPositionCoordinate.z * 765.0 - 5.0)) <= (ceil(previousDepthValue * 765.0)) )
105+
{
106+
return half4(half3(uniform.intensityFactor), 1.0h);
107+
}
108+
else
109+
{
110+
return half4(0.0h, 0.0h, 0.0h, 1.0h);
111+
}
113112
}

Molecules/Rendering/Shaders/SphereRaytracing.metal

+6-7
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,11 @@ float2 ambientOcclusionLookupCoordinate(float2 impostorSpaceCoordinate,
9191
else
9292
{
9393
float2 theSign = aoNormal.xy / absoluteSphereSurfacePosition.xy;
94-
//vec2 aSign = sign(aoNormal.xy);
95-
lookupTextureCoordinate = theSign - absoluteSphereSurfacePosition.yx * (theSign / d);
94+
lookupTextureCoordinate = theSign - absoluteSphereSurfacePosition.yx * (theSign / d);
9695
}
9796

98-
return (lookupTextureCoordinate / 2.0) + 0.5;
97+
// Using a slight inset here to avoid seam artifacts, should examine this further to fix.
98+
return lookupTextureCoordinate / 2.1;
9999
}
100100

101101
fragment FragmentColorDepth sphereRaytracingFragment(SphereRaytracingVertexIO fragmentInput [[stage_in]],
@@ -114,11 +114,10 @@ fragment FragmentColorDepth sphereRaytracingFragment(SphereRaytracingVertexIO fr
114114
uniform.inverseModelViewProjMatrix,
115115
distanceFromCenter);
116116

117-
lookupTextureCoordinate = (lookupTextureCoordinate * 2.0) - 1.0;
118-
119117
float2 textureCoordinateForAOLookup = fragmentInput.ambientOcclusionTextureBase + uniform.ambientOcclusionTexturePatchWidth * lookupTextureCoordinate;
120118
textureCoordinateForAOLookup.y = 1.0 - textureCoordinateForAOLookup.y;
121-
constexpr sampler ambientOcclusionSampler;
119+
constexpr sampler ambientOcclusionSampler(mag_filter::linear,
120+
min_filter::linear);
122121
half ambientOcclusionIntensity = ambientOcclusionTexture.sample(ambientOcclusionSampler, textureCoordinateForAOLookup).x;
123122

124123
// Ambient lighting
@@ -130,7 +129,7 @@ fragment FragmentColorDepth sphereRaytracingFragment(SphereRaytracingVertexIO fr
130129

131130
// Specular lighting
132131
half specularLightingIntensityFactor = pow(ambientLightingIntensityFactor, 60.0h) * 0.6h;
133-
finalSphereColor = finalSphereColor + ((specularLightingIntensityFactor * ambientOcclusionIntensity) * (half3(1.0h) - finalSphereColor));
132+
finalSphereColor = finalSphereColor + ((specularLightingIntensityFactor * ambientOcclusionIntensity) * (half3(1.0h) - finalSphereColor));
134133

135134
FragmentColorDepth colorDepth;
136135
colorDepth.color = half4(finalSphereColor * alphaComponent, 1.0);

0 commit comments

Comments
 (0)