这个简单的金属着色器对提供了顶点四边形/三角形的颜色属性进行插值,将简单的渐变渲染到屏幕上:
到目前为止还不错。它呈现了众所周知的渐变三角形/四边形。
你可以在几乎每个GPU HelloWorld教程中找到它。
我需要一个片段着色器,它不是根据插值的顶点颜色计算颜色,而是基于片段在屏幕上的位置计算颜色。它接收一个填充整个屏幕的四边形的顶点,然后仅使用片段着色器来计算实际颜色。
据我所知,顶点的位置是一个float4,前三个元素是3D向量,第四个元素设置为1.0。
因此,我认为将其修改为在片段着色器中将顶点的位置简单地重新解释为颜色应该很容易,对吗?
我很惊讶地发现屏幕呈统一的黄色,而不是在x轴上从
#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
,在y轴上从green=0.0
到green=1.0
的渐变色:
(期望的渲染输出expected render output与实际的渲染输出actual render output)
interpolated.position
似乎为每个片段产生了相同的值。
我在这里做错了什么?
附注:(虽然这个虚拟片段逻辑可以很容易地使用顶点插值来完成,但我的实际片段逻辑不能)