I am trying to render a split screen (left + right) . On the left I am rendering a pyramid 3D and on the right I am trying to render the depth texture corresponding to the pyramid. I have created a depthTexture and did a blind pass then I am trying to render the texture on a quad. However the texture is not getting rendererd.
I tried to see if the quad is coming properly by rendering it in sollid color and it works. I also saw the uv corresponding to the quad is coming correctly.
func draw(in view: MTKView) {
guard let commandBuffer = Self.commandQueue.makeCommandBuffer() else { return }
guard let drawable = view.currentDrawable else { return }
// Get the render pass descriptor
guard let descriptor = view.currentRenderPassDescriptor else { return }
guard let depthCommandBuffer = Self.commandQueue.makeCommandBuffer(),
let depthRenderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: depthRenderPassDescriptor) else { return }
let viewportForDepth = MTLViewport(
originX: 0,
originY: 0,
width: 2048,
height: 2048,
znear: 0,
zfar: 1
)
depthRenderEncoder.pushDebugGroup("Depth Pass")
depthRenderEncoder.setViewport(viewportForDepth)
// Configure matrices for right cube (top view)
let viewMatRight = getViewMatrix(
eye: SIMD3<Float>(0, 3, 0),
center: SIMD3<Float>(0, 0, 0),
up: SIMD3<Float>(0, 0, -1)
)
let projMatRight = createProjectionMatrix(
fov: 60.0 * .pi / 180,
near: 0.0001,
far: 3.0,
aspect: 1.0
)
uniforms.vMatrix = viewMatRight
uniforms.pMatrix = projMatRight
depthRenderEncoder.setDepthStencilState(depthStencilState)
depthRenderEncoder.setRenderPipelineState(depthPipelineState)
depthRenderEncoder.setVertexBuffer(positionBuffer, offset: 0, index: 0)
depthRenderEncoder.setVertexBuffer(normalBuffer, offset: 0, index: 1)
depthRenderEncoder.setVertexBytes(&uniforms, length: MemoryLayout<Uniforms>.stride, index: 2)
depthRenderEncoder.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: 36)
depthRenderEncoder.popDebugGroup()
// Finish encoding
depthRenderEncoder.endEncoding()
// END OF TEXTURE GENERATION
// Create a command buffer
// guard let commandBuffer = Self.commandQueue.makeCommandBuffer() else { return }
// Set up common render pass properties
descriptor.colorAttachments[0].clearColor = MTLClearColor(red: 1, green: 1, blue: 1, alpha: 1) // White
descriptor.colorAttachments[0].loadAction = .clear // Clears once at the start
descriptor.colorAttachments[0].storeAction = .store // Store the result
// ---- Render Pyramid to Left Screen ----
if let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor) {
let rotationMatrix = matrix_rotation_y(angle)
renderEncoder.setDepthStencilState(depthStencilState)
renderEncoder.setRenderPipelineState(pipelineState)
renderEncoder.setVertexBuffer(positionBuffer, offset: 0, index: 0)
renderEncoder.setVertexBuffer(normalBuffer, offset: 0, index: 1)
// Left Viewport for Pyramid
let viewportLeft = MTLViewport(
originX: 0,
originY: 0,
width: Double(view.drawableSize.width / 2),
height: Double(view.drawableSize.height),
znear: 0,
zfar: 1
)
renderEncoder.setViewport(viewportLeft)
let viewMatLeft = getViewMatrix(
eye: SIMD3<Float>(0, 3, -5),
center: SIMD3<Float>(0, 0, 0),
up: SIMD3<Float>(0, 1, 0)
)
let aspectRatioLeft = Float(view.drawableSize.width / 2) / Float(view.drawableSize.height)
let projMatLeft = createProjectionMatrix(
fov: 60.0 * .pi / 180,
near: 0.0001,
far: 10.0,
aspect: aspectRatioLeft
)
uniforms.mMatrix = rotationMatrix
uniforms.mITMatrix = computeNormalMatrix(from: rotationMatrix)
uniforms.vMatrix = viewMatLeft
uniforms.pMatrix = projMatLeft
renderEncoder.setVertexBytes(&uniforms, length: MemoryLayout<Uniforms>.stride, index: 2)
renderEncoder.setFragmentBytes(&uniforms, length: MemoryLayout<Uniforms>.stride, index: 0)
renderEncoder.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: 36)
// End first render pass
renderEncoder.endEncoding()
}
// ---- Render Quad to Right Screen ----
descriptor.colorAttachments[0].loadAction = .load // Clears once at the start
descriptor.colorAttachments[0].storeAction = .store
// depthRenderPassDescriptor.depthAttachment.loadAction = .load
// depthRenderPassDescriptor.depthAttachment.storeAction = .store
if let quadRenderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor) {
let viewportRight = MTLViewport(
originX: Double(view.drawableSize.width / 2),
originY: 0,
width: Double(view.drawableSize.width / 2),
height: Double(view.drawableSize.height),
znear: 0,
zfar: 1
)
// quadRenderEncoder.setTriangleFillMode(.lines)
quadRenderEncoder.setViewport(viewportRight)
quadRenderEncoder.setRenderPipelineState(renderTexturePipelineState)
quadRenderEncoder.setVertexBuffer(quadVertexBuffer, offset: 0, index: 0)
quadRenderEncoder.setVertexBuffer(quadUvBuffer, offset: 0, index: 1)
quadRenderEncoder.setFragmentTexture(depthTexture, index: 2)
quadRenderEncoder.drawIndexedPrimitives(type: .triangle, indexCount: 6, indexType: .uint16, indexBuffer: quadIndexBuffer, indexBufferOffset: 0)
// End second render pass
quadRenderEncoder.endEncoding()
}
// Present and commit command buffer
commandBuffer.present(drawable)
commandBuffer.commit()
commandBuffer.waitUntilCompleted()
}
This is my draw call. And this is my fragment shader corresponding to the quad:
fragment float4 tex_fragment_main(QuadOut in [[stage_in]],
depth2d<float, access::sample> depthTexture [[texture(2)]]) {
// constexpr sampler textureSampler(coord::normalized, address::clamp_to_edge);
constexpr sampler smpler(
coord::normalized, filter::linear);
float2 texCoord = in.uv ;
float d = depthTexture.sample(smpler, texCoord);
return float4(d, d, d, 1.0);
// return float4(in.uv.x, in.uv.y, 0.0, 1.0);
}
Kindly let me know if you can find the issue.