英文:
Metal shader changing camera z does nothing
问题
以下是您提供的Metal Shader代码的翻译部分:
#include <metal_stdlib>
using namespace metal;
// 将角度转换为弧度的函数
float degreesToRadians(float degrees) {
return degrees * (M_PI_F / 180.0);
}
// 生成投影矩阵的函数
float4x4 generateProjectionMatrix(float fov, float aspectRatio, float near, float far) {
float yScale = 1.0 / tan(fov * 0.5);
float xScale = yScale / aspectRatio;
float zRange = near - far;
float4x4 projectionMatrix;
projectionMatrix.columns[0] = float4(xScale, 0.0, 0.0, 0.0);
projectionMatrix.columns[1] = float4(0.0, yScale, 0.0, 0.0);
projectionMatrix.columns[2] = float4(0.0, 0.0, (near + far) / zRange, -1.0);
projectionMatrix.columns[3] = float4(0.0, 0.0, 2.0 * near * far / zRange, 0.0);
return projectionMatrix;
}
// 生成视图矩阵的函数
float4x4 generateViewMatrix(float3 cameraPosition) {
float3 eye = cameraPosition;
float3 target = float3(0.0, 0.0, 0.0); // 假设目标在原点
float3 up = float3(0.0, 1.0, 0.0); // 上方向是正Y轴
float3 zAxis = normalize(eye - target);
float3 xAxis = normalize(cross(up, zAxis));
float3 yAxis = cross(zAxis, xAxis);
float4x4 viewMatrix;
viewMatrix.columns[0] = float4(xAxis.x, yAxis.x, zAxis.x, 0.0);
viewMatrix.columns[1] = float4(xAxis.y, yAxis.y, zAxis.y, 0.0);
viewMatrix.columns[2] = float4(xAxis.z, yAxis.z, zAxis.z, 0.0);
viewMatrix.columns[3] = float4(-dot(xAxis, eye), -dot(yAxis, eye), -dot(zAxis, eye), 1.0);
return viewMatrix;
}
[[ stitchable ]] float2
accordion(float2 position, float amount, float fov_in) {
float4 newPos = float4(position.x, position.y, 0.0, 1.0);
float3 cameraPosition = float3(0.0, 0.0, amount);
float4x4 viewMatrix = generateViewMatrix(cameraPosition);
float nearPlane = 0.1;
float farPlane = 100.0;
float aspectRatio = 1.0;
float fov = degreesToRadians(fov_in);
float4x4 projectionMatrix = generateProjectionMatrix(fov,
aspectRatio,
nearPlane,
farPlane);
float4 final = projectionMatrix * viewMatrix * newPos;
return final.xy;
}
请注意,这只是代码的翻译部分,不包括问题或额外内容。
英文:
I have the following Metal Shader code, if I move the camera X/Y the view updates correctly, however If I move the z position of the camera, it's as if nothing happens, the view renders normally without zooming in/out...I feel like I'm missing something?
Am I creating the transforms and multiplying them correctly?
#include <metal_stdlib>
using namespace metal;
float degreesToRadians(float degrees) {
return degrees * (M_PI_F / 180.0);
}
// Function to generate a projection matrix
float4x4 generateProjectionMatrix(float fov, float aspectRatio, float near, float far) {
float yScale = 1.0 / tan(fov * 0.5);
float xScale = yScale / aspectRatio;
float zRange = near - far;
float4x4 projectionMatrix;
projectionMatrix.columns[0] = float4(xScale, 0.0, 0.0, 0.0);
projectionMatrix.columns[1] = float4(0.0, yScale, 0.0, 0.0);
projectionMatrix.columns[2] = float4(0.0, 0.0, (near + far) / zRange, -1.0);
projectionMatrix.columns[3] = float4(0.0, 0.0, 2.0 * near * far / zRange, 0.0);
return projectionMatrix;
}
float4x4 generateViewMatrix(float3 cameraPosition) {
float3 eye = cameraPosition;
float3 target = float3(0.0, 0.0, 0.0); // Assuming the target is at the origin
float3 up = float3(0.0, 1.0, 0.0); // Up direction is positive Y-axis
float3 zAxis = normalize(eye - target);
float3 xAxis = normalize(cross(up, zAxis));
float3 yAxis = cross(zAxis, xAxis);
float4x4 viewMatrix;
viewMatrix.columns[0] = float4(xAxis.x, yAxis.x, zAxis.x, 0.0);
viewMatrix.columns[1] = float4(xAxis.y, yAxis.y, zAxis.y, 0.0);
viewMatrix.columns[2] = float4(xAxis.z, yAxis.z, zAxis.z, 0.0);
viewMatrix.columns[3] = float4(-dot(xAxis, eye), -dot(yAxis, eye), -dot(zAxis, eye), 1.0);
return viewMatrix;
}
[[ stitchable ]] float2
accordion(float2 position, float amount, float fov_in) {
float4 newPos = float4(position.x, position.y, 0.0, 1.0);
float3 cameraPosition = float3(0.0, 0.0, amount);
float4x4 viewMatrix = generateViewMatrix(cameraPosition);
float nearPlane = 0.1;
float farPlane = 100.0;
float aspectRatio = 1.0;
float fov = degreesToRadians(fov_in);
float4x4 projectionMatrix = generateProjectionMatrix(fov,
aspectRatio,
nearPlane,
farPlane);
float4 final = projectionMatrix * viewMatrix * newPos;
return final.xy;
}
答案1
得分: 0
需要启用深度并提供深度缓冲。
来自https://metalbyexample.com/modern-metal-2/的代码:
mtkView.colorPixelFormat = .bgra8Unorm_srgb
mtkView.depthStencilPixelFormat = .depth32Float
pipelineDescriptor.colorAttachments[0].pixelFormat = view.colorPixelFormat
pipelineDescriptor.depthAttachmentPixelFormat = view.depthStencilPixelFormat
let depthStencilState: MTLDepthStencilState
static func buildDepthStencilState(device: MTLDevice) -> MTLDepthStencilState {
let depthStencilDescriptor = MTLDepthStencilDescriptor()
depthStencilDescriptor.depthCompareFunction = .less
depthStencilDescriptor.isDepthWriteEnabled = true
return device.makeDepthStencilState(descriptor: depthStencilDescriptor)!
}
depthStencilState = Renderer.buildDepthStencilState(device: device)
commandEncoder.setDepthStencilState(depthStencilState)
英文:
You need to enable depth and provide a depth buffer.
Code from https://metalbyexample.com/modern-metal-2/
mtkView.colorPixelFormat = .bgra8Unorm_srgb
mtkView.depthStencilPixelFormat = .depth32Float
pipelineDescriptor.colorAttachments[0].pixelFormat = view.colorPixelFormat
pipelineDescriptor.depthAttachmentPixelFormat = view.depthStencilPixelFormat
let depthStencilState: MTLDepthStencilState
static func buildDepthStencilState(device: MTLDevice) -> MTLDepthStencilState {
let depthStencilDescriptor = MTLDepthStencilDescriptor()
depthStencilDescriptor.depthCompareFunction = .less
depthStencilDescriptor.isDepthWriteEnabled = true
return device.makeDepthStencilState(descriptor: depthStencilDescriptor)!
}
depthStencilState = Renderer.buildDepthStencilState(device: device)
commandEncoder.setDepthStencilState(depthStencilState)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论