Nec*_*twi 3 shader rendering metal
我试图从顶点着色器了解片段着色器输入位置。每个片段是否从顶点着色器接收其位置?
这是我的shaders.metal
struct VertexOut{
float4 position [[position]];
float4 color;
};
vertex VertexOut basic_vertex(
const device packed_float3* vertex_array [[ buffer(0) ]],
unsigned int vid [[ vertex_id ]]) {
VertexOut vertexOut;
vertexOut.position = float4(vertex_array[vid], 1.0);
vertexOut.color = (vertexOut.position+1)/2;
return vertexOut;
}
Run Code Online (Sandbox Code Playgroud)
在顶点着色器中计算的颜色
fragment float4 basic_fragment(VertexOut vertexOut [[stage_in]]) {
return vertexOut.color;
}
Run Code Online (Sandbox Code Playgroud)
在片段着色器中计算的颜色
fragment float4 basic_fragment(VertexOut vertexOut [[stage_in]]) {
return (vertexOut.position+1)/2;
}
Run Code Online (Sandbox Code Playgroud)
为什么它们的呈现方式不同?传递给每个片段的顶点位置值是多少?似乎三角形的所有片段都接收三角形的质心。如何计算每个片段在片段缓冲区中的位置?
- 编辑 -
片段着色器中与窗口大小的分割位置;三角形仍然是黄色的。
视图控制器.swift
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let window = view.window
if(window == nil) {return}
let scale = view.window?.screen.nativeScale
let layerSize = view.bounds.size
//[640, 1136]
frameSize = [UInt(layerSize.width * scale!), UInt(layerSize.height * scale!)]
uniformBuffer = device.makeBuffer(bytes: frameSize, length: 2*MemoryLayout<UInt>.size, options: [])
}
func render() {
...
renderEncoder.setFragmentBuffer(uniformBuffer, offset: 0, index: 0)
...
}
Run Code Online (Sandbox Code Playgroud)
着色器金属
struct FrameSize{
unsigned int x;
unsigned int y;
};
fragment float4 basic_fragment(VertexOut vertexOut [[stage_in]],
const device FrameSize* frameSize [[ buffer(0) ]]
) { // 1
return float4(vertexOut.position.x/frameSize->x, vertexOut.position.y/frameSize->y, vertexOut.position.z, 1.0); // 2
}
Run Code Online (Sandbox Code Playgroud)
顶点位置在离开顶点着色器后经过透视分割和视口变换。这会将它们从剪辑坐标(x,y 中的 -1..1,z 中的 0..1)转换为帧缓冲区坐标(x=0..width-1,y=0..height-1,z=0。 .1)。片段着色器接收帧缓冲区坐标空间中的内插位置。
由于片段位置坐标在帧缓冲区空间中,几乎所有的 xy 值都将大于 1.0,因此您的颜色将只是最大的红色,最大的绿色,然后是您获得的任何 z 值。您可能想要重新规范化它们,即将位置 x 值除以帧缓冲区宽度,位置 y 除以帧缓冲区高度。
| 归档时间: |
|
| 查看次数: |
929 次 |
| 最近记录: |