[英]How to get fragment coordinate in fragment shader in Metal?
這個最小的金屬着色器對基於頂點的顏色屬性在屏幕上呈現簡單的插值漸變(當提供頂點四邊形/三角形時):
#include <metal_stdlib>
using namespace metal;
typedef struct {
float4 position [[position]];
float4 color;
} vertex_t;
vertex vertex_t vertex_function(const device vertex_t *vertices [[buffer(0)]], uint vid [[vertex_id]]) {
return vertices[vid];
}
fragment half4 fragment_function(vertex_t interpolated [[stage_in]]) {
return half4(interpolated.color);
}
...具有以下頂點:
{
// x, y, z, w, r, g, b, a
1.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0,
-1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0,
-1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0,
1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0,
1.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0,
-1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0
}
到現在為止還挺好。 它呈現眾所周知的漸變三角形/四邊形。
幾乎每個GPU HelloWorld教程中都能找到的那個。
然而,我需要一個片段着色器,而不是采用插值的頂點顏色,根據屏幕上的片段位置計算顏色。 它接收一個填充屏幕的四邊形頂點,然后僅使用片段着色器來計算實際顏色。
根據我的理解,頂點的位置是float4
,前三個元素是3d矢量,第四個元素設置為1.0
。
所以 - 我想 - 應該很容易修改上面的內容,讓它簡單地將頂點的位置重新解釋為片段着色器中的顏色,對吧?
#include <metal_stdlib>
using namespace metal;
typedef struct {
float4 position [[position]];
} vertex_t;
vertex vertex_t vertex_function(const device vertex_t *vertices [[buffer(0)]], uint vid [[vertex_id]]) {
return vertices[vid];
}
fragment half4 fragment_function(vertex_t interpolated [[stage_in]]) {
float4 color = interpolated.position;
color += 1.0; // move from range -1..1 to 0..2
color *= 0.5; // scale from range 0..2 to 0..1
return half4(color);
}
...具有以下頂點:
{
// x, y, z, w,
1.0, -1.0, 0.0, 1.0,
-1.0, -1.0, 0.0, 1.0,
-1.0, 1.0, 0.0, 1.0,
1.0, 1.0, 0.0, 1.0,
1.0, -1.0, 0.0, 1.0,
-1.0, 1.0, 0.0, 1.0,
}
然而,我很驚訝地找到了一個均勻着色的(黃色)屏幕,而不是在x軸上從red=0.0
到red=1.0
在x軸上從green=0.0
到green=1.0
的漸變:
interpolated.position
似乎為每個片段產生相同的值。
我在這做錯了什么?
Ps :(雖然這個虛擬片段邏輯可以很容易地使用頂點插值完成,但我的實際片段邏輯不能。)
interpolated.position似乎為每個片段產生相同的值。
不,價值非常大。 片段着色器中具有[[position]]限定符的變量位於像素坐標中。 除以渲染目標尺寸,你會看到你想要的東西,除了必須反轉綠色值,因為Metal的慣例是將左上角定義為此的原點,而不是左下角。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.