查看: 1227|回复: 2

Tessellation着色器例子显示不正确

[复制链接]

该用户从未签到

发表于 2014-12-6 09:35:21 | 显示全部楼层 |阅读模式
本帖最后由 le贝 于 2014-12-6 09:38 编辑

1、没有修改的运行osg自带的细分着色器例子,显示的好像不正确,效果如下图:
2014-12-06_092510.jpg
看过一篇文章,正确的显示应该是这样的吧:
2014-12-06_092711.jpg
显卡:ATI Radeon HD 5450,想请问是不是显卡的问题。
2、把例子改写了,想试一下显示四边形细分会不会正确,但是会出现0xC0000005错误,我觉得是细分不正确的问题。
程序主要代码如下:
    1)主函数
int main()
{
        osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
        viewer->setUpViewInWindow(100,100,800,600);

        osg::ref_ptr<osg::Geode> geoNode = new osg::Geode;
        osg::ref_ptr<osg::Geometry> quadNode = new osg::Geometry;
        osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
        vertices->push_back(osg::Vec3f(0.0,0.0,0.0));
        vertices->push_back(osg::Vec3f(10.0,0.0,5.0));
        vertices->push_back(osg::Vec3f(10.0,10.0,3.0));
        vertices->push_back(osg::Vec3f(0.0,10.0,1.0));
        geoNode->addDrawable(quadNode);
        quadNode->setVertexArray(vertices.get());
        quadNode->addPrimitiveSet(new osg:rawArrays(osg::DrawArrays:ATCHES,0,4));

        osg::StateSet* stateset = quadNode->getOrCreateStateSet();
        osg::Program* program = new osg::Program;

        program->addShader(new osg::Shader(osg::Shader::VERTEX, vertShader));
        program->addShader(new osg::Shader(osg::Shader::TESSCONTROL, teconShader));
        program->addShader(new osg::Shader(osg::Shader::TESSEVALUATION, teevaShader));
/*        program->addShader(new osg::Shader(osg::Shader::GEOMETRY, geomShader));*/
    program->addShader(new osg::Shader(osg::Shader::FRAGMENT, fragShader));
        stateset->setAttributeAndModes(program, osg::StateAttribute::ON);

        // switch on the uniforms that track the modelview and projection matrices
        osgViewer::Viewer::Windows windows;
        viewer->getWindows(windows);
        for(osgViewer::Viewer::Windows::iterator itr = windows.begin();
                itr != windows.end();
                ++itr)
        {
                osg::State *s=(*itr)->getState();
                s->setUseModelViewAndProjectionUniforms(true);
                s->setUseVertexAttributeAliasing(true);
        }

        viewer->setSceneData(geoNode.get());
        viewer->addEventHandler(new osgViewer::StatsHandler);
        viewer->run();
        return 0;
}

    2)细分控制着色器
static const char* teconShader = {
        "#version 400\n"
        "layout(vertices=4) out;\n"
        "in vec3 vPosition[];\n"
        "out vec3 tcPosition[];\n"
        "void main()\n"
        "{\n"
        "    tcPosition[gl_InvocationID].gl_Position = vPosition[gl_InvocationID].gl_Position;\n"
        "        gl_TessLevelOuter[0] = 4;\n"
        "        gl_TessLevelOuter[1] = 4;\n"
        "        gl_TessLevelOuter[2] = 4;\n"
        "        gl_TessLevelOuter[3] = 4;\n"
        "        gl_TessLevelInner[0] = 4;\n"
        "        gl_TessLevelInner[1] = 4;\n"
        "}\n"
};
   3)细分计算着色器
static const char* teevaShader = {
        "#version 400\n"
        "layout(quads,equal_spacing,ccw) in;\n"
        "in vec3 tcPosition[];\n"
        "uniform mat4 osg_ProjectionMatrix;\n"
        "uniform mat4 osg_ModelViewMatrix;\n"
        "void main()\n"
        "{\n"
        "        float u = gl_TessCoord.x;\n"
        "        float v = gl_TessCoord.y;\n"
        "        vec4 p0 = tcPosition[0].gl_Position;\n"
        "        vec4 p1 = tcPosition[1].gl_Position;\n"
        "        vec4 p2 = tcPosition[2].gl_Position;\n"
        "        vec4 p3 = tcPosition[3].gl_Position;\n"
        "        tePosition = p0*(1-u)*(1-v)+p1*u*(1-v)+p3*v*(1-u)+p2*u*v;\n"
        "        gl_Position = osg_ProjectionMatrix * osg_ModelViewMatrix * vec4(tePosition, 1);\n"
        "}\n"
};
想请各位看一下有什么问题。

该用户从未签到

 楼主| 发表于 2014-12-9 22:00:28 | 显示全部楼层
1、将着色器中通过osg传入的几个矩阵改为opengl自有的矩阵后,结果正确了:
改动之后.png
可能这几个矩阵有点问题
2、自己写的出不来的原因可能就是细分着色器写的不正确,我改正了能够改正的:
1)主函数:
int main()
{
        osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
        //viewer->setUpViewInWindow(100,100,800,600);

        osg::ref_ptr<osg::Geode> geoNode = new osg::Geode;
        osg::ref_ptr<osg::Geometry> quadNode =new osg::Geometry;
        osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
        vertices->push_back(osg::Vec3f(0.0,0.0,0.0));
        vertices->push_back(osg::Vec3f(10.0,0.0,0.0));
        vertices->push_back(osg::Vec3f(10.0,10.0,0.0));
        vertices->push_back(osg::Vec3f(0.0,10.0,0.0));
        quadNode->setVertexArray(vertices.get());
        const unsigned int Faces[] = {
                0, 1, 2, 3               
        };
        osg:rawElementsUInt* de = new osg::DrawElementsUInt(osg:rimitiveSet::PATCHES,4,Faces);
        quadNode->addPrimitiveSet(de);

        osg::StateSet* stateset = quadNode->getOrCreateStateSet();
        osg::Program* program = new osg::Program;


        program->addShader(new osg::Shader(osg::Shader::VERTEX, vertShader));
        program->addShader(new osg::Shader(osg::Shader::TESSCONTROL, teconShader));
        program->addShader(new osg::Shader(osg::Shader::TESSEVALUATION, teevaShader));
        program->addShader(new osg::Shader(osg::Shader::FRAGMENT, fragShader));
        stateset->setAttributeAndModes(program, osg::StateAttribute::ON);
        quadNode->setInitialBound(osg::BoundingBox(-1.0f,-1.0f,-1.0f,1.0f,1.0f,1.0f) );
        geoNode->addDrawable(quadNode);

        viewer->setSceneData(geoNode.get());
        viewer->addEventHandler(new osgViewer::StatsHandler);
        viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()));
        return viewer->run();
}
2)顶点着色器
static const char* vertShader = {
        "#version 400\n"
        "layout(location = 0) in vec3 in_Vertex;\n"
        "void main(){\n"
        "   gl_Position = vec4(in_Vertex,1);\n"
        "}\n"
};
3)细分控制着色器
static const char* teconShader = {
        "#version 400\n"
        "layout(vertices = 4) out;\n"
        //"in vec4 vPosition;\n"
        //"out vec4 tcPosition;\n"
        "#define ID gl_InvocationID\n"
        "void main()\n"
        "{\n"
        "   gl_out[ID].gl_Position = gl_in[ID].gl_Position;\n"
        "    if (ID == 0) {\n"
        "        gl_TessLevelOuter[0] = float(4);\n"
        "        gl_TessLevelOuter[1] = float(4);\n"
        "        gl_TessLevelOuter[2] = float(4);\n"
        "        gl_TessLevelOuter[3] = float(4);\n"
        "        gl_TessLevelInner[0] = float(3);\n"
        "        gl_TessLevelInner[1] = float(3);\n"
        "    }\n"
        "}\n"
};
4)细分计算着色器
static const char* teevaShader = {
        "#version 400\n"
        "layout(quads,equal_spacing,ccw) in;\n"
        "void main()\n"
        "{\n"
        "        float u = gl_TessCoord.x;\n"
        "        float v = gl_TessCoord.y;\n"
        "        vec4 p0 = gl_in[0].gl_Position;\n"
        "        vec4 p1 = gl_in[1].gl_Position;\n"
        "        vec4 p2 = gl_in[2].gl_Position;\n"
        "        vec4 p3 = gl_in[3].gl_Position;\n"
        "        gl_Position = p0*(1-u)*(1-v)+p1*u*(1-v)+p3*v*(1-u)+p2*u*v;\n"
        "        gl_Position = gl_ModelViewProjectionMatrix * gl_Position;\n"
        "}\n"
};
片元着色器就不写了,没有影响。
但是出来的是这个:
错误.png
有没有高手指点一下,真的很困惑

该用户从未签到

 楼主| 发表于 2014-12-14 10:05:24 | 显示全部楼层
1、可能是大神们没有时间或未关注到这个问题,等了很长时间都没有人来解答,这段时间真的很难受,被这个问题困扰的。但是自己依然没有放弃,这是我很感激自己的一点。
2、其实解答很简单,有个参数自己没有设置好,Quad的细分和Triangle的细分除了着色器中写的不同之外,还有就是要设置Patch_Vertices的数量,这一点我一直没找到,OSG把它封装了,在osg:atchParameter中。
3、给出最终的着色器代码
1)顶点着色器——什么都没做,只是传递了坐标
        "#version 400\n"
        "in vec4 osg_Vertex;\n"
        "out vec3 vPosition;\n"
        "void main(){\n"
        "    vPosition = osg_Vertex.xyz;\n"
        "}\n"
2)细分控制着色器——主要是细分因子的控制,这里采用了外部传入,参考了OSG例子的细分因子回调,在主函数中控制
        "#version 400\n"
        "layout(vertices = 4) out;\n"
        "in vec3 vPosition[];\n"
        "out vec3 tcPosition[];\n"
        "uniform float TessLevelInner;\n"
        "uniform float TessLevelOuter;\n"
        "#define ID gl_InvocationID\n"
        "void main(){\n"
        "    tcPosition[ID] = vPosition[ID];\n"
        "        gl_TessLevelInner[0] = TessLevelInner;\n"
        "        gl_TessLevelInner[1] = TessLevelInner;\n"
        "        gl_TessLevelOuter[0] = TessLevelOuter;\n"
        "        gl_TessLevelOuter[1] = TessLevelOuter;\n"
        "        gl_TessLevelOuter[2] = TessLevelOuter;\n"
        "        gl_TessLevelOuter[3] = TessLevelOuter;\n"
        "}\n"
3)细分计算着色器——坐标都是在这里计算,采用了最简单的线性插值
"#version 400\n"
        "layout(quads, equal_spacing, cw) in;\n"
        "in vec3 tcPosition[];\n"
        "out vec3 tePosition;\n"
        "void main(){\n"
        "        float u = gl_TessCoord.x;\n"
        "        float v = gl_TessCoord.y;\n"
        "        vec3 p0 = tcPosition[0];\n"
        "        vec3 p1 = tcPosition[1];\n"
        "        vec3 p2 = tcPosition[2];\n"
        "        vec3 p3 = tcPosition[3];\n"
        "        vec3 tePosition = p0*(1-u)*(1-v)+p1*u*(1-v)+p3*v*(1-u)+p2*u*v;\n"
        "    gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * vec4(tePosition, 1);\n"
        "}\n"
4)片元着色器——最简单的一片白,没有关照,就是为了简单
        "#version 400\n"
        "void main(){\n"
        "    gl_FragColor = vec4(1.0,1.0,1.0, 1.0);\n"
        "}\n"
5)Quad的细分需要设置,在Opengl中是GL_PATCH_VERTICES吧好像
state->setAttribute(new osg::PatchParameter(4));//四边形是四个点
state->setAttribute(new osg::PatchParameter(3));//如果三角形是三个点

细分前

细分前

(细分前)

细分后

细分后

(细分后)
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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