如果要渲染一个冒名顶替的几何体(比如a sphere),那么标准做法是使用两个三角形绘制它(比如通过传递一个顶点并使用几何体着色器生成一个三角形条带)。
这很好,因为它允许广告牌的范围设置得相当简单:您可以直接计算实际的世界空间位置。
几何着色器可以交替输出点图元,我看不出它们不应该输出点图元的原因。唯一的问题是找到某种方法来缩放gl_PointSize
,以便获得这种效果。
我能找到的唯一先例是this question(我不确定它的答案是否正确)和this question(没有答案)。
值得注意的是,用距离来正确地缩放点是相当简单的(通过gl_PointSize = constant/length(gl_Position)
,但这是不可控的;你不能说例如:我希望该点看起来像是两个世界单位的跨度。
所以:有人知道怎么做吗?
1条答案
按热度按时间yqlxgs2m1#
一个直接的想法是将粒子顶部和底部的一个点转换到屏幕空间,并找到距离。这可以很好地抵消,而且只使用
y
坐标非常简单。广告牌是屏幕对齐的,视图矩阵通常不会缩放,因此世界空间中的粒子大小与眼睛空间中的粒子大小相同,这就只剩下投影到达NDC,除以
w
,然后按视口大小缩放。一个典型的投影矩阵
P
可能看起来像这样...从
y_eye
(眼空间中的y坐标)开始,图像空间坐标y_image
以像素为单位获得...插入广告牌上方/下方的半径并减去取消...
或者,在文本中,
pixelSize = vpHeight * P[1][1] * radius / w_clip
对于透视投影,
P[1][1] = 1 / tan(fov_y / 2)
.w_clip
是gl_Position.w
,也是-z_eye
(来自透视矩阵中的-1
)。为了保证点覆盖所需的每个像素,这可能需要一个额外的小常量。边注:广告牌上的球体在屏幕中间看起来不错。如果你有一个大视野的透视投影,一个真实的球体在接近屏幕边缘时应该会扭曲。你可以隐式地对广告牌上的每个像素进行虚拟球体的光线投射,以获得正确的结果,但广告牌的边界需要相应地调整。快速谷歌结果:第一个
[* 编辑 *]
好吧,既然我费心测试了这个,我也会把我的着色器扔在这里...
顶点:
片段:
(Note右下角的可见间隙如上所述不正确)