一个 opengl 纹理透明 hack

问题描述

我希望为 DxWnd 工具(一个由 SourceForge 托管的开源程序)制作一个 opengl 通用纹理透明黑客。 hack 应该适用于每个使用 opengl 渲染 RGBA 纹理的程序。 DxWnd cah 挂钩并重定向来自库的所有调用包括 opengl32.dll。 我已阅读并尝试实施有关使纹理透明的所有建议,包括启用 GL_BLEND、禁用 GL_CULL_FACE 和设置 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)。此外,还有一个例程可以强制所有纹理像素的 alpha 位。 我预计,一旦完成,结果应该是一个半透明的场景,但事实并非如此。 例如,以下是来自 gl hexen II 的 3d 场景:

enter image description here

这是最终结果,一些纹理不透明,大多数像素颜色丢失:

enter image description here

只是为了证明 DxWnd 能够操作彩色像素(因此这不应该是问题的原因),这是具有过滤器的相同场景,可以为每个纹理重新着色:

enter image description here

问题的原因是什么?我该如何解决?请注意,由于 DxWnd 正在挂钩一个通用程序,因此它可能很容易不得不面对具有相反目的的 opengl 调用

解决方法

你想要的东西通常不可能仅仅通过连接到其他应用程序来实现。

您可以强制开启混合。但是正确的透明渲染与渲染不透明场景是一项根本不同的任务。因为 alpha 混合透明度是基于对背景进行每个三角形的混合操作,所以它只有在您以从后到前的顺序渲染所有内容时才真正有效。

但就程序而言,它认为它在做不透明渲染。所以它将按照它认为适合使用的顺序进行渲染。对于更现代的应用程序,这可能是从前到后,以利用早期的深度测试。

这正是让透明度发挥作用所需的相反顺序。而且没有通用的方法来控制渲染的顺序,仅仅通过挂接一些 OpenGL 函数。

此外,应用程序往往会尽量避免渲染明显不可见的场景部分。因此,如果应用程序认为某个特定房间不可见,因为该房间的门不可见,那么该房间及其内容将不会被渲染。因此,即使您可以获得正确的渲染顺序,您也需要让程序更改渲染内容,以便正确地看穿东西。

还应该注意,进行 alpha 混合需要渲染的片段具有有用的 alpha 值。但是对于不透明表面的大多数片段计算将具有 1.0 的 alpha 值。因此:没有混合。而且,除非您要处理固定功能的 OpenGL 渲染,或者您愿意手动修补着色器以添加您自己的 alpha 统一值,否则无法从应用程序外部更改此设置。