相关疑难解决方法(0)

Opengl渲染纹理与部分透明度(半透明度)然后渲染到屏幕

我找到了一些被问过的地方,但我还没有找到一个好的答案.

问题:我想要渲染到纹理,然后我想将渲染的纹理绘制到屏幕IDENTICALLY,如果我跳过渲染到纹理步骤并且只是直接渲染到屏幕,它将如何显示.我目前正在使用混合模式glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA).我也有glBlendFuncSeparate来玩.

我希望能够将部分透明的重叠项呈现给此纹理.我知道混合功能目前正在弄乱基于Alpha的RGB值.我已经看到一些模糊的建议使用"预乘alpha",但描述的含义很差.我在photoshop中制作png文件,我知道它们有一个半透明的位,你不能像TGA一样独立编辑alpha通道.如果需要,我可以切换到TGA,虽然PNG更方便.

现在,为了这个问题,我们假设我们没有使用图像,而是使用带有alpha的全彩色四边形.

一旦我将场景渲染到纹理,我需要将该纹理渲染到另一个场景,并且我需要将纹理再次呈现为部分透明度.事情就是崩溃的地方.在之前的混合步骤中,我明确地改变了基于Alpha的RGB值,如果Alpha为0或1,则再次执行它,但如果它在中间,则结果是那些部分半透明像素进一步变暗.

玩混合模式我运气很少.我能做的最好就是渲染纹理:

glBlendFuncSeparate(GL_ONE,GL_ONE_MINUS_SRC_ALPHA,GL_ONE,GL_ONE);

我发现使用glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)多次渲染将近似正确的颜色(除非事情重叠).但这并不完美(正如您在下图中看到的那样,绿色/红色/蓝色框重叠的部分会变暗或累积alpha.(编辑:如果我在渲染中进行多次绘制以筛选部分而且仅渲染一次纹理,alpha累积问题消失,它确实有效,但为什么?!我不想为屏幕呈现相同的纹理数百次,以使其正确累积)

以下是一些详细说明问题的图像(多个渲染过程使用基本混合(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA),并且它们在纹理渲染步骤中多次渲染.右边的3个框渲染为100%红色,绿色或蓝色(0-255)但蓝色的阿尔法值为50%,红色的阿尔法值为25%,绿色的阿尔法值为75%: 在此输入图像描述

那么,我想知道的细分:

  1. 我将混合模式设置为:X
  2. 我将场景渲染为纹理.(也许我必须使用一些混合模式或多次渲染?)
  3. 我将混合模式设置为:Y
  4. 我在现有场景上将纹理渲染到屏幕上.(也许我需要一个不同的着色器?也许我需要渲染纹理几次?)

期望的行为是,在该步骤结束时,最终的像素结果与我刚刚执行此操作相同:

  1. 我将混合模式设置为:(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)
  2. 我将我的场景渲染到屏幕上.

而且,为了完整性,这里有一些我的原始天真尝试的代码(只是定期混合):

    //RENDER TO TEXTURE.
    void Clipped::refreshTexture(bool a_forceRefresh) {
        if(a_forceRefresh || dirtyTexture){
            auto pointAABB = basicAABB();
            auto textureSize = castSize<int>(pointAABB.size());
            clippedTexture = DynamicTextureDefinition::make("", textureSize, {0.0f, 0.0f, 0.0f, 0.0f});
            dirtyTexture = false;
            texture(clippedTexture->makeHandle(Point<int>(), textureSize));
            framebuffer = renderer->makeFramebuffer(castPoint<int>(pointAABB.minPoint), textureSize, clippedTexture->textureId());
            {
                renderer->setBlendFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                SCOPE_EXIT{renderer->defaultBlendFunction(); };

                renderer->modelviewMatrix().push();
                SCOPE_EXIT{renderer->modelviewMatrix().pop(); };
                renderer->modelviewMatrix().top().makeIdentity();

                framebuffer->start();
                SCOPE_EXIT{framebuffer->stop(); };

                const size_t renderPasses = 1; //Not …
Run Code Online (Sandbox Code Playgroud)

c++ opengl blending render-to-texture glblendfunc

8
推荐指数
1
解决办法
2331
查看次数

标签 统计

blending ×1

c++ ×1

glblendfunc ×1

opengl ×1

render-to-texture ×1