【发布时间】:2014-10-23 17:50:29
【问题描述】:
我想在一个已通过非仿射变换(更具体地说是透视变换)变换的矩形上放置纹理。
我有一个基于openscenegraph 并加载我自己的顶点和片段着色器的非常复杂的实现。 问题始于着色器是很久以前编写的,并且使用的是 GLSL 120。
OpenGL 端是用 C++ 编写的,最简单的形式是加载纹理并将其应用于四边形。直到最近,一切都运行良好,因为四边形最多进行了仿射变换(旋转 + 平移),因此其上的纹理渲染是正确的。
但是现在我们想要支持任何形状的四边形,包括这样的东西: http://ibin.co/1dbsGPpzbkOX
如上图所示,中间的纹理不正确(箭头所示) 经过数小时的研究,我发现这是由于 OpenGL 将四边形拆分为三角形并独立渲染每个三角形。如果我的四边形如图所示,这当然是不正确的,因为第四点会影响纹理拉伸。 然后我什至发现这个问题有一个名字:它是“纹理坐标的透视错误插值”,如下所述: [1]
在寻找解决方案时,我遇到了这篇文章,其中提到了在以后的 GLSL 版本中使用“smooth”属性:[2] 但这意味着将我的着色器更新到更新的版本。
我发现的另一种方法是使用 GL_Hints,如下所述:[3] 但是这里的缺点是它只是一个提示,没有办法确保它被使用。
现在我已经展示了我的研究,这是我的问题:
更新我的(复杂的)着色器和所有与之配套的 OpenGL 以遵守新的 OpenGL 管道范例太耗时,所以我尝试使用 GLSL“版本 330 兼容性”并将“变化”更改为“平滑”和“平滑”,以及在 C++ 端添加 GL_NICE 提示,但这些更改并没有解决我的问题。这是正常的吗,因为兼容模式不支持这种正确的透视变换?还是我需要做更多的事情? 或者有没有更好的方法让我无需重构所有内容即可获得此功能?
这是我的顶点着色器:
#version 330 compatibility
smooth out vec4 texel;
void main(void) {
gl_Position = ftransform();
texel = gl_TextureMatrix[0] * gl_MultiTexCoord0;
}
片段着色器太复杂了,但它以
开头#version 330 compatibility
smooth in vec4 texel;
【问题讨论】:
-
以上文字的链接:[1] en.wikibooks.org/wiki/GLSL_Programming/…
-
smooth关键字不是这里的问题。它实际上是默认行为,在 GLSL 1.20 中也是如此。 OpenGL 的内置透视投影对您没有帮助。您似乎直接将矩形扭曲为梯形,而实际上并未将其深度扩展-因此对于内置逻辑,您的图元与观察平面平行,并且透视校正最终将无济于事。这里需要的是投影纹理映射,看看this question。
标签: opengl glsl compatibility