【问题标题】:Volume Rendering alpha blending体积渲染 Alpha 混合
【发布时间】:2014-08-12 15:59:47
【问题描述】:

我找到了这个关于体积渲染的教程http://www.codeproject.com/Articles/352270/Getting-started-with-Volume-Rendering 并尝试实现我自己的渲染器。我已经到了可以通过 alpha 测试一次绘制所有切片的地步,这或多或少地给了我在教程中的结果。现在,我想向前迈出一步并应用 alpha 混合,但之后没有任何变化(即使有,看起来也没有教程中的那么好)。

这是我的渲染代码:

glClear(GL_COLOR_BUFFER_BIT  | GL_DEPTH_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);

for (int i = 0; i < z; ++i)
{
    glBindTexture(GL_TEXTURE_2D, texturesObjects[i]);

    glBegin(GL_QUADS);

    glTexCoord2f(0.0f, 0.0f);
    glVertex3f(-1.0, -1.0, 2 * i / z - 1);
    glTexCoord2f(1.0f, 0.0f);
    glVertex3f(1.0, -1.0, 2 * i / z - 1);
    glTexCoord2f(1.0f, 1.0f);
    glVertex3f(1.0, 1.0, 2 * i / z - 1);
    glTexCoord2f(0.0f, 1.0f);
    glVertex3f(-1.0, 1.0, 2 * i / z - 1);

    glEnd();
    glBindTexture(GL_TEXTURE_2D, 0);
}

glutSwapBuffers();

其中 z 是切片数。纹理生成代码如下所示:

GLuint* loadXZslices(const VR::DataAccessor& accessor, int& x, int& y, int& z)
{
    x = accessor.getX();
    y = accessor.getY();
    z = accessor.getZ();

    GLuint* texturesObjects = new GLuint[accessor.getZ()];

    for (size_t i = 0; i < accessor.getZ(); ++i)
    {
        char* luminanceBuffer = accessor.getXYslice(i);
        char* rgbaBuffer = new char[accessor.getX() * accessor.getY() * 4];

        for (size_t j = 0; j < accessor.getX() * accessor.getY(); ++j)
        {
            rgbaBuffer[j * 4] = luminanceBuffer[j];
            rgbaBuffer[j * 4 + 1] = luminanceBuffer[j];
            rgbaBuffer[j * 4 + 2] = luminanceBuffer[j];
            rgbaBuffer[j * 4 + 3] = 255;

            if (luminanceBuffer[j] < 20)
            {
                rgbaBuffer[j * 4 + 3] = 0;
            }
        }

        glActiveTexture(GL_TEXTURE0);
        glGenTextures(1, &texturesObjects[i]);
        glBindTexture(GL_TEXTURE_2D, texturesObjects[i]);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, accessor.getX(), accessor.getY(), 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)rgbaBuffer);

        delete[] luminanceBuffer;
        delete[] rgbaBuffer;
    }

    return texturesObjects;
}

DataAccessor 当然是可以访问原始纹理数据的类。

我是否忘记在我的窗口中设置某些内容或者我的代码有问题?

【问题讨论】:

    标签: c++ opengl alphablending volume-rendering


    【解决方案1】:

    您的代码中有几处看起来有问题:

    1. 您没有将纹理设置为具有部分透明度。在构建纹理的地方,您将 alpha 分量设置为 255,如果原始亮度小于 20,则设置为 0。要获得实际的混合值,您需要使用 alpha 分量的亮度值:

      rgbaBuffer[j * 4 + 3] = luminanceBuffer[j];
      

      要微调结果,您可能必须使用其他一些从原始强度到 alpha 的映射。但它可能仍然是某种斜坡,而不是阶跃函数。

    2. 虽然代码没有显示z 的声明,但这段代码看起来很可疑:

      glVertex3f(-1.0, -1.0, 2 * i / z - 1);
      

      从上下文来看,z 可能是一个整数。如果这是真的,这将是一个整数除法,当2 * i 小于z 时将产生 0,而其余循环值将产生 1。必须至少将其中一个值转换为浮点数才能使其成为浮点除法。

    【讨论】:

    • 你说对了!你不会相信我在这上面浪费了多少时间:P
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-25
    • 2018-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多