代码之家  ›  专栏  ›  技术社区  ›  Tare

为什么OpenSceneGraph将所有Sampler2D映射到第一个纹理

  •  0
  • Tare  · 技术社区  · 7 年前

    它使用多个纹理进行输入,然后使用预渲染摄影机进行多渲染目标渲染,并使用第二个摄影机读取这些多渲染目标纹理以进行延迟着色。因此,两个相机都有自己的着色器(此处称为geometry\u pass和lighting\u pass)。 sampler2D 阅读时穿制服。

    //in geometry_pass.frag
    uniform sampler2D uAlbedoMap;
    uniform sampler2D uHeightMap;
    uniform sampler2D uNormalMap;
    uniform sampler2D uRoughnessMap;
    uniform sampler2D uSpecularMap;
    [...]
    layout (location = 0) out vec4 albedo;
    layout (location = 1) out vec4 height;
    layout (location = 2) out vec4 normal;
    layout (location = 3) out vec4 position;
    layout (location = 4) out vec4 roughness;
    layout (location = 5) out vec4 specular;
    [...]
    albedo = vec4(texture(uAlbedoMap, vTexCoords).rgb, 1.0);
    height = vec4(texture(uHeightMap, vTexCoords).rgb, 1.0);
    normal = vec4(texture(uNormalMap, vTexCoords).rgb, 1.0);
    position = vec4(vPosition_WorldSpace, 1.0);
    roughness = vec4(texture(uRoughnessMap, vTexCoords).rgb, 1.0);
    specular = vec4(texture(uSpecularMap, vTexCoords).rgb, 1.0);    
    

    这里的输出始终是 uAlbedoMap

    //in lighting_pass.frag
    uniform sampler2D uAlbedoMap;
    uniform sampler2D uHeightMap;
    uniform sampler2D uNormalMap;
    uniform sampler2D uPositionMap;
    uniform sampler2D uRoughnessMap;
    uniform sampler2D uSpecularMap;
    [...]
    vec3 albedo = texture(uAlbedoMap, vTexCoord).rgb;
    vec3 height = texture(uHeightMap, vTexCoord).rgb;
    vec3 normal_TangentSpace = texture(uNormalMap, vTexCoord).rgb;
    vec3 position_WorldSpace = texture(uPositionMap, vTexCoord).rgb;
    vec3 roughness = texture(uRoughnessMap, vTexCoord).rgb;
    vec3 specular = texture(uSpecularMap, vTexCoord).rgb;
    

    i、 e.正确导出的位置地图也具有照明过程中反照率的颜色。

    因此,似乎正常工作的是纹理输出,但显然不工作的是输入。

    现在,一个明显的问题是:如何在着色器中正确使用这些纹理?


    项目建设

    osgViewer::Viewer ,因此只有一个视图。 这个 displayCamera

    osg::ref_ptr<osg::Camera> camera = viewer.getCamera();
    
    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
    traits->windowDecoration = false;
    traits->x = 0;
    traits->y = 0;
    traits->width = 640;
    traits->height = 480;
    traits->doubleBuffer = true;
    
    camera->setGraphicsContext(new osgQt::GraphicsWindowQt(traits.get()));
    camera->getGraphicsContext()->getState()->setUseModelViewAndProjectionUniforms(true);
    camera->getGraphicsContext()->getState()->setUseVertexAttributeAliasing(true);
    camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.6f, 1.0f));
    camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
    camera->setViewMatrix(osg::Matrix::identity());
    

    显示摄像机 对于该查看器相机,创建第二个相机以渲染到纹理(因此称为 rttCamera )并将其作为子对象添加到 显示摄像机 ).

    显示摄像机 有两个孩子 矩阵变换->屏幕四元菜单。这个 rttCamera公司 有子场景->晶洞。 显示摄像机 s rendermask,场景 rttCamera公司

    使用场景节点,我从文件(所有位图)中读取5个纹理,然后渲染 rttCamera公司

    //model is the geode in the scene group node
    osg::ref_ptr<osg::StateSet> ss = model->getOrCreateStateSet();
    ss->addUniform(new osg::Uniform(name.toStdString().c_str(), counter));
    ss->setTextureAttributeAndModes(counter, pairNameTexture.second, osg::StateAttribute::ON | osg::StateAttribute::PROTECTED);
    

    .

    //camera is the rttCamera
    //bufferComponent is constructed by osg::Camera::COLOR_BUFFER0+counter
    //(where counter is just an integer that gets incremented)
    //texture is an osg::Texture2D that is newly created
    camera->attach(bufferComponent, texture);
    //the textures get stored to assign them later on
    gBufferTextures[name] = texture;
    

    这些mrt纹理作为纹理绑定到screenquad

    //ssQuad is the stateset of the screen quad geode
    QString uniformName = "u" + name + "Map";
    uniformName[1] = uniformName[1].toUpper();
    
    ssQuad->addUniform(new osg::Uniform(uniformName.toStdString().c_str(), counter));
    osg::ref_ptr<osg::Texture2D> tex = gBufferTextures[name];
    ssQuad->setTextureAttributeAndModes(counter, gBufferTextures[name], osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
    

    纹理附件的创建如下(其中使用宽度和高度或大小的二次幂值没有区别)

    osg::ref_ptr<osg::Texture2D> Utils::createTextureAttachment(int width, int height)
    {
        osg::Texture2D* texture = new osg::Texture2D();
        //texture->setTextureSize(width, height);
        texture->setTextureSize(512, 512);
        texture->setInternalFormat(GL_RGBA);
        texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR);
        texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);
    
        return texture;
    }
    

    如果有更重要的解决代码或信息缺失的方法,请告诉我。

    1 回复  |  直到 7 年前
        1
  •  0
  •   Tare    7 年前

    所以我终于发现了错误。我的柜台是一个 unsigned int 这显然是不允许的。由于osg对我隐藏了太多的错误,我没有发现这是一个问题。。。

    int ,我现在将不同的纹理放入着色器。