OSG:GLSL Shader正在研发AMD而不是NVIDIA

时间:2014-06-16 22:03:03

标签: opengl glsl nvidia openscenegraph amd-processor

目前我正在为我的研究开发一个OSG项目,并编写了一个CelShading着色器(以及一个simpleFog Shader)。我首先使用CelShader和深度缓冲区渲染到Texture,然后使用fogShader。在我的AMD Radeon HD 7950和我的英特尔HD4400上都运行良好(虽然最后速度很慢),都运行Windows。然而,在Quadro 600运行的Linux上,Shader编译没有错误,但仍然是错误的,光线变暗,并且由于缺少一些光点,似乎并非使用场景中的每个灯光。整个香椿效果也消失了。 我确认Shader正在开发另一款AMD,即ATI Mobility HD3400。

但是对于其他NVIDIA,如GTX 670或660 TI或560 TI(此时间窗口),Shader无法正常工作。首先,由于流量不均匀,它完全搞砸了,但是在我修好它之后仍然无法正常工作。

我现在有这个问题好几天了,这让我头疼。我不知道我错过了什么,为什么它在简单的英特尔HD 4400上运行而在高端NVIDIA卡上却没有? 奇怪的是,fogShader在每个系统上都能完美运行,并且给了我想要的美妙雾。 有没有人有想法? Uniforms是为toonTex设置的,但是texture0没有设置,因为模型是用blender进行uv映射的,但是纹理似乎工作得很好(看看屏幕中的Pony)。我假设0被用作texture0的布局,据我所知,这是完全有效的。 Here是一个视频,显示GTX 660 TI上的着色器。有些东西似乎有用,如果只有一个灯,但它不应该是什么样子,在Radeon HD 7950上它就像this(忽略黑色边框,截图问题)。

光线与众不同。

编辑:刚做了另一个测试:在Intel HD 4400和Windows上,它正在运行。但是运行Linux的同一系统只显示了大量的White,但有一些轮廓,但根本没有纹理。 有人有什么建议吗? 着色器的来源如下:

celShader.vert

#version 120
varying vec3 normalModelView;
varying vec4 vertexModelView;
uniform bool zAnimation;
uniform float osg_FrameTime;
void main()
{   
    normalModelView = gl_NormalMatrix * gl_Normal;
    vertexModelView = gl_ModelViewMatrix * gl_Vertex;
    gl_TexCoord[0] = gl_MultiTexCoord0;

    vec4 vertexPos = gl_Vertex;
    if(zAnimation){//
        vertexPos.z = sin(5.0*vertexPos.z + osg_FrameTime)*0.25;//+ vertexPos.z;    
    }
    gl_Position = gl_ModelViewProjectionMatrix * vertexPos;     

}

celShader.frag

#version 120 
#define NUM_LIGHTS 5
uniform sampler2D texture0;
uniform sampler2D toonTex;
uniform float osg_FrameTime;
uniform bool tex;
varying vec3 normalModelView;
varying vec4 vertexModelView;

vec4 calculateLightFromLightSource(int lightIndex, bool front){
    vec3 lightDir;
    vec3 eye = normalize(-vertexModelView.xyz);
    vec4 curLightPos = gl_LightSource[lightIndex].position;
    //curLightPos.z = sin(10*osg_FrameTime)*4+curLightPos.z;
    lightDir = normalize(curLightPos.xyz - vertexModelView.xyz);

    float dist = distance( gl_LightSource[lightIndex].position, vertexModelView );
    float attenuation =  1.0 / (gl_LightSource[lightIndex].constantAttenuation
                 + gl_LightSource[lightIndex].linearAttenuation * dist 
                 + gl_LightSource[lightIndex].quadraticAttenuation * dist * dist);

    float z = length(vertexModelView);
    vec4 color;
    vec3 n = normalize(normalModelView);
    vec3 nBack = normalize(-normalModelView);
    float intensity = dot(n,lightDir); //NdotL, Lambert
    float intensityBack = dot(nBack,lightDir); //NdotL, Lambert
    //-Phong Modell
    vec3 reflected = normalize(reflect( -lightDir, n));
    float specular = pow(max(dot(reflected, eye), 0.0), gl_FrontMaterial.shininess);
    vec3 reflectedBack = normalize(reflect( -lightDir, nBack));
    float specularBack = pow(max(dot(reflectedBack, eye), 0.0), gl_BackMaterial.shininess);
    //Toon-Shading
    //2D Toon http://www.cs.rpi.edu/~cutler/classes/advancedgraphics/S12/final_projects/hutchins_kim.pdf        
    vec4 toonColor = texture2D(toonTex,vec2(intensity,specular));
    vec4 toonColorBack = texture2D(toonTex,vec2(intensityBack,specularBack));
    if(front){  
        color += gl_FrontMaterial.ambient * gl_LightSource[lightIndex].ambient[lightIndex];
        if(intensity > 0.0){
            color += gl_FrontMaterial.diffuse * gl_LightSource[lightIndex].diffuse * intensity * attenuation ;
            color += gl_FrontMaterial.specular * gl_LightSource[lightIndex].specular * specular *attenuation ;
        }
        return color  * toonColor;
    } else {//back  
        color += gl_BackMaterial.ambient * gl_LightSource[lightIndex].ambient[lightIndex];
        if(intensity > 0.0){
            color += gl_BackMaterial.diffuse * gl_LightSource[lightIndex].diffuse * intensityBack * attenuation ;
            color += gl_BackMaterial.specular * gl_LightSource[lightIndex].specular * specularBack *attenuation ;
        }
        return color  * toonColorBack;
    }   
}

void main(void) {
    vec4 color = vec4(0.0);
    bool front = true;
    //non-uniform-flow error correction
    //see more here: http://www.opengl.org/wiki/GLSL_Sampler#Non-uniform_flow_control
    //and here: http://gamedev.stackexchange.com/questions/32543/glsl-if-else-statement-unexpected-behaviour
    vec4 texColor = texture2D(texture0,gl_TexCoord[0].xy);
    if(!gl_FrontFacing)
        front = false;
    for(int i = 0; i< NUM_LIGHTS; i++){
        color += calculateLightFromLightSource(i,front);
        }
    if(tex) 
        gl_FragColor =color * texColor;
    else
        gl_FragColor = color;
  }

fogShader.vert

#version 120
varying vec4 vertexModelView;
void main()
{   
  gl_Position = ftransform();       
  vertexModelView = gl_ModelViewMatrix * gl_Vertex;
  gl_TexCoord[0] = gl_MultiTexCoord0;
}

fogShader.frag

varying vec4 vertexModelView;
uniform sampler2D texture0;
uniform sampler2D deepth;
uniform vec3 fogColor;
uniform float zNear;
uniform float zFar;

float linearDepth(float z){
    return (2.0 * (zNear+zFar)) / ((zFar + zNear) - z * (zFar - zNear));// -1.0;    
}

void main(void){
    //Literature
    //http://www.ozone3d.net/tutorials/glsl_fog/p04.php and depth_of_field example OSG Cookbook
    vec2 deepthPoint = gl_TexCoord[0].xy;
    float z = texture2D(deepth, deepthPoint).x;
    //fogFactor = (end - z) / (end - start)
    z = linearDepth(z); 
        float fogFactor = (4000*4-z) / (4000*4 - 30*4);
    fogFactor = clamp(fogFactor, 0.0, 1.0);

    vec4 texColor = texture2D(texture0,gl_TexCoord[0].xy);

    gl_FragColor = mix(vec4(fogColor,1.0), texColor,fogFactor);

}

ProgramLinking

 osg::ref_ptr<osg::Shader> toonFrag = osgDB::readShaderFile("../Shader/celShader.frag");
 osg::ref_ptr<osg::Shader> toonVert = osgDB::readShaderFile("../Shader/" +  _vertSource);
 osg::ref_ptr<osg::Program> celShadingProgram = new osg::Program;
 celShadingProgram->addShader(toonFrag);
 celShadingProgram->addShader(toonVert);

 osg::ref_ptr<osg::Texture2D> toonTex = new osg::Texture2D;
 toonTex->setImage(osgDB::readImageFile("../BlenderFiles/Texturen/toons/" + _toonTex));
 toonTex->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
 toonTex->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);

 osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;




 ss->setTextureAttributeAndModes(1, toonTex, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);
 ss->addUniform(new osg::Uniform("toonTex", 1));
 ss->setAttributeAndModes(celShadingProgram, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                    //TODO NEEED?
 ss->setTextureMode(1, GL_TEXTURE_1D, osg::StateAttribute::OVERRIDE | osg::StateAttribute::OFF);


 ss->addUniform(new osg::Uniform("tex", true));
 ss->addUniform(new osg::Uniform("zAnimation", false));

1 个答案:

答案 0 :(得分:1)

好的,我终于找到了错误。 从我的Shader的零版本开始有一个错误的Line,我整整一周都忽略了(我很惊讶我的AMD驱动程序没有给我一个错误,这是完全错的! 编辑:没有错,请看下面的评论!)。 这两行被打破了:

 color += gl_FrontMaterial.ambient * gl_LightSource[lightIndex].ambient[lightIndex];
 color += gl_BackMaterial.ambient * gl_LightSource[lightIndex].ambient[lightIndex];

环境当然不是数组......