查看: 4632|回复: 9

RTT post processing 的三线性过滤问题贴图 --- 问题求帮助

[复制链接]

该用户从未签到

发表于 2012-4-3 10:27:15 | 显示全部楼层 |阅读模式
目的:为减少锯齿,优化三维场景
办法:使用RTT,再将纹理渲染到覆盖场景的四边形上。
问题:当使用三线性(LINEAR_MIPMAP_LINEAR)时,随着纹理尺寸的变大,场景变暗变黑
相关代码:

//创建RTT纹理
        m_pBufferTexture = new osg::Texture2D;
        m_pBufferTexture->setName("RTT Texture");
        m_pBufferTexture->setTextureSize(m_vecTextureBufferSize.x(), m_vecTextureBufferSize.y());
        m_pBufferTexture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D:INEAR_MIPMAP_LINEAR);
        m_pBufferTexture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);
        m_pBufferTexture->setInternalFormat(GL_RGBA);

//创建RTT相机
        osg::ref_ptr<osg::Camera> pCamera = new osg::Camera;
        pCamera->setRenderOrder(osg::Camera:RE_RENDER);
        pCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
        pCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
        pCamera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        pCamera->setViewMatrix(osg::Matrixd::identity());
        pCamera->setProjectionMatrixAsPerspective(45.0, 1.0, 1.0, 10000.0);

        osg::ref_ptr<osg::Hint> pHint = new osg::Hint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
        pCamera->getOrCreateStateSet()->setAttributeAndModes(pHint.get());
        const osg::CullSettings::CullingMode eCullingMode = pCamera->getCullingMode();
        pCamera->setCullingMode(eCullingMode & ~osg::CullStack::SMALL_FEATURE_CULLING);
               
        pCamera->attach(osg::Camera::COLOR_BUFFER, m_pBufferTexture.get());
        pCamera->setViewport(0, 0, m_vecTextureBufferSize.x(), m_vecTextureBufferSize.y());

当m_vecTextureBufferSize大小为 1024时,场景还比较正常,但是随着改值的增大,场景就异常了(变暗变黑)

但是当MIN_FILTER不是三线性 osg::Texture2D::LINEAR_MIPMAP_LINEAR,而是osg::Texture2D::LINEAR时,m_vecTextureBufferSize变大或变小,场景都不会异常(变暗变黑)。
但是使用osg::Texture2D::LINEAR,场景的锯齿没有任何改善。

请教各位,这是什么原因引起的?  有没有解决的办法?

该用户从未签到

 楼主| 发表于 2012-4-4 18:07:58 | 显示全部楼层
怎么没有高手来回答一下?   

该用户从未签到

 楼主| 发表于 2012-4-4 18:08:29 | 显示全部楼层
请大家针对这个问题讨论一下,不管对错与否。

该用户从未签到

发表于 2012-4-5 12:28:17 | 显示全部楼层
据我猜想,你试一下2的n次方的贴图应该是正常的

该用户从未签到

 楼主| 发表于 2012-4-5 13:17:49 | 显示全部楼层
fenma3422 发表于 2012-4-5 12:28
据我猜想,你试一下2的n次方的贴图应该是正常的

我的贴图就是 2的n次方。  1024、2048、4096

该用户从未签到

发表于 2012-4-6 10:14:47 | 显示全部楼层
谨慎怀疑是您的显卡本身不能完全支持这种FBO纹理的mipmap;事实上的确有相当一部分显卡是不能直接对FBO纹理mipmap的

抗锯齿完全可以用一些后处理的方法来实现

该用户从未签到

 楼主| 发表于 2012-4-6 11:45:28 | 显示全部楼层
array 发表于 2012-4-6 10:14
谨慎怀疑是您的显卡本身不能完全支持这种FBO纹理的mipmap;事实上的确有相当一部分显卡是不能直接对FBO纹理 ...

谢谢。 你说的这种情况确实很有可能。

我的显卡支持 GL_ARB_Framebuffer_object 和 GL_EXT_FrameBuffer_object.  但很有可能支持mipmap。

我做过一些后处理操作,但是效果不是太好。
用的是 FXAA算法。相关代码如下:

        m_strVertShader =
                "uniform float subPixelShift = 1.0/4.0;\n"
                "uniform float winWidth;\n"
                "uniform float winHeight;\n"
                "varying vec4 fxaaUV;\n"

                "void main(void)\n"
                "{\n"
                "        gl_TexCoord[0] = gl_MultiTexCoord0;\n"
                "        gl_Position = ftransform();\n"
                "        vec2 rcpFrame = vec2(1.0/winWidth, 1.0/winHeight);\n"
                "        fxaaUV.xy = gl_MultiTexCoord0.xy;\n"
                "        fxaaUV.zw = gl_MultiTexCoord0.xy - (rcpFrame * (0.5 + subPixelShift));\n"
                "}\n";

        m_strFragShader =
                "uniform float winWidth;\n"
                "uniform float winHeight;\n"
                "uniform float spanMax = 8.0;\n"
                "uniform float reduceMul = 1.0/8.0;\n"
                "varying vec4 fxaaUV;\n"

                "uniform sampler2D BufferTexture;\n"

                "#define FxaaInt2 ivec2\n"
                "#define FxaaFloat2 vec2\n"
                "#define FxaaTexLod0(t, p) texture2DLod(t, p, 0.0)\n"
                "#define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)\n"
                "const float reduceMin = (1.0/128.0);\n"

                "vec3 fxaaPixelShader(sampler2D tex, vec2 rcpFrame)\n"
                "{\n"
                "        vec3 rgbNW = FxaaTexLod0(tex, fxaaUV.zw).xyz;\n"
                "        vec3 rgbNE = FxaaTexOff(tex, fxaaUV.zw, FxaaInt2(1,0), rcpFrame.xy).xyz;\n"
                //"        vec3 rgbNE = FxaaTexLod0(tex, fxaaUV.zw + (FxaaInt2(1,0) * rcpFrame.xy)).xyz;\n"
                "        vec3 rgbSW = FxaaTexOff(tex, fxaaUV.zw, FxaaInt2(0,1), rcpFrame.xy).xyz;\n"
                //"        vec3 rgbSW = FxaaTexLod0(tex, fxaaUV.zw + (FxaaInt2(0,1) * rcpFrame.xy)).xyz;\n"
                "        vec3 rgbSE = FxaaTexOff(tex, fxaaUV.zw, FxaaInt2(1,1), rcpFrame.xy).xyz;\n"
                //"        vec3 rgbSE = FxaaTexLod0(tex, fxaaUV.zw + (FxaaInt2(1,1) * rcpFrame.xy)).xyz;\n"
                "        vec3 rgbM  = FxaaTexLod0(tex, fxaaUV.xy).xyz;\n"

                "        vec3 luma = vec3(0.299, 0.587, 0.114);\n"
                "        float lumaNW = dot(rgbNW, luma);\n"
                "        float lumaNE = dot(rgbNE, luma);\n"
                "        float lumaSW = dot(rgbSW, luma);\n"
                "        float lumaSE = dot(rgbSE, luma);\n"
                "        float lumaM  = dot(rgbM,  luma);\n"
                "        float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));\n"
                "        float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));\n"

                "        vec2 dir = vec2(-((lumaNW + lumaNE) - (lumaSW + lumaSE)), (lumaNW + lumaSW) - (lumaNE + lumaSE));\n"
                "        float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * reduceMul), reduceMin);\n"
                "        float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);\n"
                "        dir = min(FxaaFloat2(spanMax, spanMax), max(FxaaFloat2(-spanMax,-spanMax), dir * rcpDirMin)) * rcpFrame.xy;\n"

                "        vec3 rgbA = (1.0/2.0) * (FxaaTexLod0(tex, fxaaUV.xy + dir * (1.0/3.0 - 0.5)).xyz + FxaaTexLod0(tex, fxaaUV.xy + dir * (2.0/3.0 - 0.5)).xyz);\n"
                "        vec3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (FxaaTexLod0(tex, fxaaUV.xy + dir * (0.0/3.0 - 0.5)).xyz + FxaaTexLod0(tex, fxaaUV.xy + dir * (3.0/3.0 - 0.5)).xyz);\n"
                "        float lumaB = dot(rgbB, luma);\n"
                "        if ((lumaB < lumaMin) || (lumaB > lumaMax)) return rgbA;\n"
                "        return rgbB;\n"
                "}\n"

                "vec4 computeColor(sampler2D tex, vec2 uv, float time)\n"
                "{\n"
                "    vec4 c = vec4(0.0);\n"
                "    vec2 rcpFrame = vec2(1.0/winWidth, 1.0/winHeight);\n"
                "    c.rgb = fxaaPixelShader(tex, rcpFrame);\n"
                "    c.a = 1.0;\n"
                "    return c;\n"
                "}\n"


                "void main(void)\n"
                "{\n"
                "        gl_FragColor = computeColor(BufferTexture, gl_TexCoord[0].st, 0.0);\n"
                "}\n";

该用户从未签到

 楼主| 发表于 2012-4-6 11:45:52 | 显示全部楼层
还请大家一起来研究。。。

该用户从未签到

 楼主| 发表于 2012-4-10 14:30:18 | 显示全部楼层
看来大家还没有碰到过类似的情况   

该用户从未签到

发表于 2012-4-12 09:54:55 | 显示全部楼层
既然您总说一起研究,那么请给出可编译的,能够说明问题的代码和数据,这样才有可能“一起研究您本人的问题”
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表