在我的Metal应用程序中,我需要在片段位置和基线之间进行一些距离比较,我从顶点着色器传入。片段位置在窗口或像素坐标中到达片段着色器。我想这是因为参数被标记为[[stage-in]],或者因为它被标记为[[position]]?我不清楚是什么原因导致了对位置参数的窗口坐标的转换。
如何传递我的基线坐标,以便它们也能获得与窗口/像素坐标相同的变换?现在我将我的基线坐标作为NDC,然后使用屏幕分辨率手动将它们转换为窗口坐标,但是当我的视口不完全是屏幕对齐时,这会造成严重破坏。
如果基线坐标刚刚以位置坐标的方式预先变换到达,而不是传递更多参数来修复手动转换,那么我可以比较它们而不用担心屏幕大小或视口。
我该怎么做?我查看了插值限定符,实际上我在基线参数上使用[[center_no_perspective]]。但它们仍然是NDC。如何让它们与位置坐标位于同一坐标系中?
这里有参考我的结构和论点:
struct VertexIn {
float4 position [[position]];
float4 baseline [[center_no_perspective]];
};
fragment void stroke_abuffer_fragment(VertexIn interpolated [[stage_in]],
constant ColorScale& colorScale[[ buffer(9) ]],
constant Globals& globals [[ buffer(11) ]],
) {
float scale = colorScale.scale;
float2 worldPos = float2(interpolated.position.xy); // these are in pixel coords -- points * 2 for retina
float2 worldCenterFlip = float2(interpolated.baseline.x,-interpolated.baseline.y); // flip y while still in NDC, these will range from -1 to 1
float2 worldCenter = worldCenterFlip*globals.displaySize + globals.displaySize; // these are NDC so multiply by displaySize * screenscale
worldCenter.x *= scale/2.0; // metal ndc is +/- 1
worldCenter.y *= scale/2.0;
float alpha;
float width = interpolated.baseline.w*scale; // scale is nativeScale ie 2 for retina?
float edge = widthCountEdge.edge * width;
float d = distance(worldPos, worldCenter);
谢谢!
鲍勃