如何使用OpenGL着色器在平面上绘制没有透视的纹理?
Posted
技术标签:
【中文标题】如何使用OpenGL着色器在平面上绘制没有透视的纹理?【英文标题】:How to draw a texture without perspective on a plane, using OpenGL Shaders? 【发布时间】:2017-08-26 11:53:32 【问题描述】:我正在尝试在 3d 环境中绘制 2d 角色。我正在使用面向相机的飞机。这给了我正确的结果只有在没有与墙壁的深度相交时。关闭深度测试不是答案,因为飞机仍然需要在其他墙壁、门和物体后面。
然后我使平面垂直,这给了我想要的深度测试相交结果。然而,现在 2d 角色由于透视而变形,并且似乎给了他一个大头和/或较短的身体。不是我想要的结果。
理想情况下,我希望能够绘制一个垂直的平面以使用所需的深度测试相交,并使用着色器在没有透视的情况下绘制纹理(并缩放)。这保持了平面的深度测试相交(对于墙壁、门、物体等),并为我提供了 2d 角色的正确比例。
更新
也许另一种方法是使用模板?理想情况下不使用它们会很好。
启用模板测试并设置测试功能和操作以将 1 写入所有模板。 垂直绘制平面。 如果模板值等于 1,则设置模板函数通过。 绘制面向相机的 2d 角色。 禁用模板测试。更新
也许在不使用法线的情况下绘制为平面上的平面反射?像立方体反射或球面反射,但只是平面反射。有任何想法吗?
【问题讨论】:
您在 C 中绘制的内容没有意义。不存在同时仿射的梯形失真。您可以在那里找到一些子平行四边形,原则上可以为其定义映射。但这是一个有争议的问题。 A中根本没有裁剪,只有深度测试,可以禁用。 如果您不想进行透视校正,只需将其绘制为 2D 精灵即可。但是,您必须通过查询角色与相机的距离(“深度”值)来计算正确的 缩放 @meowgoesrhedog,是的,这将是理想的。计算比例很容易,但我确实想要飞机的深度测试。 @derhass,剪裁不仅仅与视锥剪裁有关。根据定义,它的意思是“从某物上剪下的一小块”。我已经更新了我的问题以避免将来出现混淆。是的,我已经在给定的设置上尝试将它作为平行四边形,但它会导致其自身的失真。也许如果它被细分,那么你的方法就不那么明显的扭曲了。不过,这不是我的问题。 裁剪在 OpenGL 的上下文中是明确定义的。未通过深度测试的片段不会被剪裁。 【参考方案1】:您可以做的是使用 A) 中的解决方案,但将 Z 值(用于深度测试)更改为更好的位置。
所以在你的顶点着色器结束时你会得到这样的东西:
gl_Position = projModelViewMatrix * vec4(position, 1.0);
这会将您的 3d 位置转换为屏幕空间位置。更改 gl_Position.z 将更改用于深度测试的值。在这种情况下,您希望该值稍微靠近相机。
最终使这个值正确可能会很复杂,但假设您的模型矩阵是精灵底部中间的点,然后将您的世界空间 Z、X 归零并仅保留每个顶点的 Y 轴,将为您提供一个适合进行 z 测试的位置。
gl_Position = projModelViewMatrix * vec4(position, 1.0);
gl_Position.z = projModelViewMatrix * vec4(0.0, position, 0.0, 1.0);
*注意事项:未经测试,有一段时间没有接触过 glsl,只是在我的脑海中输入了这个。
祝你好运!
【讨论】:
如果我对您的理解正确,基本上您是说将 gl_Position.z 向前拉到相机以重新创建我想要用于深度测试的平面?我尝试使用以下代码:gl_Position = projModelViewMatrix * vec4(position.xyz, 1.0); gl_Position.z = (projModelViewMatrix * vec4(0.0, position.y, position.y * 0.39283710065919303, 1.0)).z;
计算幻数:a = camera angle h = height of plane 1 / (cos(a) * h * 2)
当平面在屏幕上垂直居中时,这非常有效...
...但是,如果平面不在屏幕上垂直居中,即可能位于墙后的屏幕底部,则平面与墙相交,就好像它向前倾斜朝向相机一样.这是有道理的,即使面对相机的平面在中心比边缘更近。现在可能有点太一厢情愿了,反正还有吗?以上是关于如何使用OpenGL着色器在平面上绘制没有透视的纹理?的主要内容,如果未能解决你的问题,请参考以下文章
着色器在 Opengl Shader Builder 上工作,但不在我的 OpenGL 应用程序中
我的OpenGL学习进阶之旅介绍一下OpenGL ES的图元装配:坐标系统透视分割视口变化