【问题标题】:Volume Rendering in OpenGL using 2D textures使用 2D 纹理在 OpenGL 中进行体积渲染
【发布时间】:2017-06-05 13:32:14
【问题描述】:

为什么我们必须根据相机的视角来对齐不同方向的纹理?不应该一样吗?(如果我启用了深度测试)


编辑 1:

我用自己的程序测试了一下。

这是我的渲染函数代码。

        if (position.z >= 0) pz = true;
        else pz = false;

        if (lz != pz) {
            slice.clear();
            printf("Changed !!! :: %s", (pz?"Positive Z":"Negative Z") );
            if (pz) {
                for (float i = 0; i < count; ++i) {
                    slice.push_back( glm::vec2( -SIZE/2 + SIZE * i / (count-1), i ) );
                }
                lz = pz;
            } else {
                for (float i = count-1; i >= 0; --i) {
                    slice.push_back( glm::vec2( -SIZE/2 + SIZE * i / (count-1), i ) );
                }
                lz = pz;
            }
            glBindBuffer(GL_ARRAY_BUFFER, ibo);
            glBufferData(GL_ARRAY_BUFFER, slice.size()* 2 *sizeof(float), &slice[0], GL_STATIC_DRAW);
        }

        glUseProgram(programID);
        glBindVertexArray(vao);
        glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &mvp[0][0]);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture);
        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1);
        glEnableVertexAttribArray(2);
        glDrawArraysInstanced(GL_TRIANGLES, 0, 6, slice.size());
        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);
        glDisableVertexAttribArray(2);
        glBindVertexArray(0);

向量“切片”包含 2 个浮点数(z 位置和切片的 id)。每个实例都是唯一的。如果没有这个“if (lz != pz) ...”子句,我只能在 +ve Z 方向看到模型。


编辑 2:

这是一种观点。

但是当我的相机移动到 z=0 附近时,部分纹理就看不到了。 我试图关闭深度测试,然后我看到了背面的纹理。为什么前面的纹理消失了?

  1. 启用深度测试
  2. 禁用背面剔除
  3. 启用 alpha 测试

编辑 3:

我将“if (lz != pz) ...”子句更改为以下代码,现在一切正常。但我还是不明白为什么。

        slice.clear();
        for (float i = 0; i < count; ++i) { // position is a vector representing the location of the camera
            if (-SIZE/2 + SIZE * i / (count-1) >= position.z) break;
            slice.push_back( glm::vec2( -SIZE/2 + SIZE * i / (count-1), i ) );
        }

        for (float i = count-1; i >= 0; --i) {
            if (-SIZE/2 + SIZE * i / (count-1) < position.z) break;
            slice.push_back( glm::vec2( -SIZE/2 + SIZE * i / (count-1), i ) );
        }

虽然它看起来并不吸引人,但它按预期工作。对于每一帧,我根据相机的位置对切片进行排序。


编辑 4:

我的 alpha 测试代码

glEnable (GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.1);

这两行在 init() 函数中。


【问题讨论】:

  • 是的,它应该与启用深度测试相同,但我猜他们正在做某种没有深度测试的从后到前的混合。
  • 我自己试了一下。似乎即使进行深度测试也是必要的。
  • 你试过使用深度剥离吗? Martin Pernollet 给我们举了一个基于 JOGL 的例子,他在 Jzy3D 中使用了这个算法。
  • 没有。有没有相关的链接或教程?

标签: opengl graphics rendering jogl volume-rendering


【解决方案1】:

基本上我在这里看到两个问题:

为什么要选择离相机方向最近的轴?

因为否则切片可能不会填满卷的整个屏幕区域。想象一下,您渲染切片平行于 XY 平面,但相机沿 X 轴看,即“从侧面”。然后你会看到切片之间的间隙。像这样:

为什么要从前渲染?

这并不总是必要的。原则上,如果您启用 alpha-test 和 depth-test,那么您可以按任何顺序进行渲染。然而,体积渲染通常假设支持部分透明的数据,在这种情况下,为了使通常的 alpha 混合方程起作用,几何图形必须从前渲染。

【讨论】:

  • 谢谢。第一个答案非常有用。对于第二部分,我仍然得到奇怪的结果。我将在编辑帖子后发布。我启用了深度测试和 alpha 测试。
  • 见编辑 2。我添加了我的编译程序
  • @FunnyFunkyBuggy:看起来你没有做第一件事(即你没有沿着主轴渲染)。除此之外,我感觉你启用了面部剔除,这意味着所有背对相机的切片都不会被渲染。
  • 确实,我没有沿着长轴渲染(我稍后会实现)。最困扰我的问题是我看不到其他纹理,即使它们不垂直于我。从理论上讲,应该只有几片我看不到。顺便说一句,我禁用了面部剔除。
  • @FunnyFunkyBuggy:您能展示一下您是如何启用 alpha 测试的吗?您的设置有问题。
猜你喜欢
  • 2019-04-02
  • 1970-01-01
  • 1970-01-01
  • 2012-03-14
  • 1970-01-01
  • 1970-01-01
  • 2013-12-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多