金属着色器更改摄像机 Z 值无效。

huangapple go评论59阅读模式
英文:

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 &lt;metal_stdlib&gt;
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) -&gt; MTLDepthStencilState {
let depthStencilDescriptor = MTLDepthStencilDescriptor()
depthStencilDescriptor.depthCompareFunction = .less
depthStencilDescriptor.isDepthWriteEnabled = true
return device.makeDepthStencilState(descriptor: depthStencilDescriptor)!
}
depthStencilState = Renderer.buildDepthStencilState(device: device)
commandEncoder.setDepthStencilState(depthStencilState)

huangapple
  • 本文由 发表于 2023年6月12日 03:50:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76452279.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定