Hi,

currently I am working on a OSG Project as part of my study. I wrote a Toon 
Shader and a Fog Shader (as Post-Process), which work fine on my (and others) 
AMD Graphic Cards. However, on almost every NVIDIA Card (the only one it worked 
very slow was a Quadro one, unfortunately I do not know which one) the picture 
is totally messed up (look at the provided screenshots below)!. I was sure that 
I was only using non-manufacter specific shader code, so I am totally lost what 
could be the cause of the error.
I did though tracked it down to _maybe_, just maybe the TextureMapping of the 
toonTex. If I remove this part of the shader, it looks a bit different, still a 
mess, but the crowbar is fine (the rest is still color bingo).
Maybe the light code is wrong to? If I remove everything and only passing the 
texture then it looks just fine. Of course, no Lightning and so, but no color 
bingo and texture are fine.
Maybe one of you sees my mistake? Do I use platform depended code? Is my 
Texture Mapping faulty? Or what else could be wrong? The GLSL Version?
The TexSize for the Toon Texture ist 128x128 (sampler2D toonTex).
I am using the osgFX Effect class for the CelShading, the Technique works as 
that:
First pass my shader code, second pass is copy/pasted from osgFX::Cartoon for 
the Oulines.
The output of this I render to Texture, along with a render-to-texture depth 
buffer and this two texture are used in my FogShader for FogCalculation, which 
is outputed on a screensize-quad.
The models are created and UV-Mapped with Blender, then exported with 
osgexporter-Plugin, which is why I do not explicitly set the Texture Mode for 
sampler2D texture0. As far as I unterstand, GLSL then just use the 0-Texture, 
with seems to work on booth, AMD and NVIDIA.
Some Screenies:
Working Intel i5 Third Generation, AMD Radeon HD 7950.
also working on: ATI Mobility HD3400 Series (do no which one)
Non-Working AMD Phenom II X4 850, NVIDIA GTX 560TI
Also non-working on: NVIDIA GTX 660 TI (video: 
https://www.youtube.com/watch?v=1FvQ6tnGmXs)

Shader Code:
celShading.vert

Code:

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



celShading.frag

Code:

#version 120 
#define NUM_LIGHTS 4
uniform sampler2D texture0;
uniform sampler2D toonTex;
uniform float osg_FrameTime;
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;
        //check if directional or point
        if(curLightPos.w == 0)
                lightDir = normalize(curLightPos.xyz);
        else
                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;
        vec4 toonColor;
        if(front){
                vec3 n = normalize(normalModelView);
                float intensity = dot(n,lightDir); //NdotL, Lambert
                vec3 reflected = normalize(reflect( -lightDir, n));
                float specular = pow(max(dot(reflected, eye), 0.0), 
gl_FrontMaterial.shininess);
                //Toon-Shading
                //2D Toon 
http://www.cs.rpi.edu/~cutler/classes/advancedgraphics/S12/final_projects/hutchins_kim.pdf
                float d = specular;
                toonColor = texture2D(toonTex,vec2(intensity,d));
                
                color += gl_FrontMaterial.ambient * 
gl_LightSource[lightIndex].ambient[lightIndex];
                         //+gl_FrontMaterial.ambient * gl_LightModel.ambient
                        // +  gl_FrontLightModelProduct.sceneColor;
                if(intensity > 0.0){
                                color += gl_FrontMaterial.diffuse * 
gl_LightSource[lightIndex].diffuse * intensity * attenuation ;
                                
                                //-Phong Modell
                                
                                color += gl_FrontMaterial.specular * 
gl_LightSource[lightIndex].specular * specular *attenuation ;
                }
        } else {//back
                vec3 n = normalize(-normalModelView);
                float intensity = dot(n,lightDir); //NdotL, Lambert
        
                //Toon-Shading
                vec3 reflected = normalize(reflect( -lightDir, n));
                                //-Phong Modell
                                float specular = pow(max(dot(reflected, eye), 
0.0), gl_BackMaterial.shininess);
                float d = specular;
                toonColor = texture2D(toonTex,vec2(intensity,d));

                color += gl_BackMaterial.ambient * 
gl_LightSource[lightIndex].ambient[lightIndex];
                         //+gl_FrontMaterial.ambient * gl_LightModel.ambient
                        // +  gl_FrontLightModelProduct.sceneColor;
                if(intensity > 0.0){
                                color += gl_BackMaterial.diffuse * 
gl_LightSource[lightIndex].diffuse * intensity * attenuation ;
                                
                                color += gl_BackMaterial.specular * 
gl_LightSource[lightIndex].specular * specular *attenuation ;
                }
        }
        return color  * toonColor;// * attenuation;

}

void main(void) {
        vec4 frontColor = vec4(0.0);
        for(int i = 0; i< NUM_LIGHTS; i++){
                frontColor += calculateLightFromLightSource(i,true);
                }
        vec4 backColor = vec4(0.0);
        for(int i = 0; i< NUM_LIGHTS; i++){
                backColor += calculateLightFromLightSource(i,false);
                }
        vec4 texColor = texture2D(texture0,gl_TexCoord[0].xy);

                
        //http://www.ozone3d.net/tutorials/glsl_fog/p04.php
        float z = length(vertexModelView);//(gl_FragCoord.z / gl_FragCoord.w);
        vec4 color = frontColor;
        if(!gl_FrontFacing)
                color = backColor;

                gl_FragColor =color * texColor;
  }



fogShading.vert

Code:

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



fogShading.frag

Code:

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 = (3000*4-z) / (3000*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) ;    
}




Some Source Code, which might help:

Code:

//osgFX::Technique my own passes
 void define_passes() {
            // implement pass #1 (solid surfaces)
                {
                    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;

                    osg::ref_ptr<osg::PolygonOffset> polyoffset = new 
osg::PolygonOffset;
                    polyoffset->setFactor(1.0f);
                    polyoffset->setUnits(1.0f);
                    ss->setAttributeAndModes(polyoffset, 
osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);


                    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);


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

                    osg::ref_ptr<osg::TexEnv> texenv = new osg::TexEnv; //TODO 
Was bedeutet das?
                    texenv->setMode(osg::TexEnv::MODULATE);
                    ss->setTextureAttributeAndModes(1, texenv, 
osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                    addPass(ss);
                }

            // implement pass #2 (outlines) copy/paste from osgFX::Cartoon
            if(_secondPass){
                osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;
                osg::ref_ptr<osg::PolygonMode> polymode = new osg::PolygonMode;
                polymode->setMode(osg::PolygonMode::FRONT_AND_BACK, 
osg::PolygonMode::LINE);
                ss->setAttributeAndModes(polymode.get(), 
osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                osg::ref_ptr<osg::CullFace> cf = new osg::CullFace;
                cf->setMode(osg::CullFace::FRONT);
                ss->setAttributeAndModes(cf.get(), 
osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                ss->setAttributeAndModes(_lineWidth.get(), 
osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                _material->setColorMode(osg::Material::OFF);
                _material->setDiffuse(osg::Material::FRONT_AND_BACK, 
osg::Vec4(0, 0, 0, 1));
                _material->setAmbient(osg::Material::FRONT_AND_BACK, 
osg::Vec4(0, 0, 0, 1));
                _material->setSpecular(osg::Material::FRONT_AND_BACK, 
osg::Vec4(0, 0, 0, 1));

                // set by outline colour so no need to set here.
                _material->setEmission(osg::Material::FRONT_AND_BACK, 
osg::Vec4(0, 0, 0, 1));

                ss->setAttributeAndModes(_material.get(), 
osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

                ss->setMode(GL_LIGHTING, osg::StateAttribute::OVERRIDE | 
osg::StateAttribute::ON);
                ss->setTextureMode(0, GL_TEXTURE_1D, 
osg::StateAttribute::OVERRIDE | osg::StateAttribute::OFF);
                ss->setTextureMode(0, GL_TEXTURE_2D, 
osg::StateAttribute::OVERRIDE | osg::StateAttribute::OFF);
                ss->setTextureMode(1, GL_TEXTURE_1D, 
osg::StateAttribute::OVERRIDE | osg::StateAttribute::OFF);
                ss->setTextureMode(1, GL_TEXTURE_2D, 
osg::StateAttribute::OVERRIDE | osg::StateAttribute::OFF);

                addPass(ss.get());
            }
        }

//my creation of the post-process
struct RenderingPipeline {
        osg::ref_ptr<osg::Camera> pass_0_color;
        osg::ref_ptr<osg::Camera> pass_0_depth;
        osg::ref_ptr<osg::Camera> pass_PostProcess;
        osg::ref_ptr<osg::Program>* programs;
        unsigned int programCount;

        ~RenderingPipeline() {
            delete[] programs;
        }
    };
void createRenderingPipeline(unsigned int width, unsigned int height, 
osg::Node& rootForToon, osgViewer::Viewer &viewer, std::string toonTex, 
RenderingPipeline& pipe) {
//CelShading is an osgFX::Effect subclass with the passes shown above
        osg::ref_ptr<brtr::CelShading> toonRoot = new brtr::CelShading(toonTex);
        toonRoot->addChild(&rootForToon);
//createRTTCamera is from cookbok
        osg::ref_ptr<osg::Texture2D> toonAndOutline = new osg::Texture2D;
        toonAndOutline->setTextureSize(width, height);
        toonAndOutline->setInternalFormat(GL_RGBA);
        osg::ref_ptr<osg::Camera> rttCamToon = 
brtr::createRTTCamera(osg::Camera::COLOR_BUFFER, toonAndOutline);
        rttCamToon->addChild(toonRoot);

        osg::ref_ptr<osg::Texture2D> deepth = new osg::Texture2D;
        deepth->setTextureSize(width, height);
        deepth->setInternalFormat(GL_DEPTH_COMPONENT24);
        deepth->setSourceFormat(GL_DEPTH_COMPONENT);
        deepth->setSourceType(GL_FLOAT);

        osg::ref_ptr<osg::Camera> rttCamDepth = 
brtr::createRTTCamera(osg::Camera::DEPTH_BUFFER, deepth);
        rttCamDepth->addChild(toonRoot);

        osg::ref_ptr<Camera> postProcessCam = brtr::createHUDCamera(0, 1, 0, 1);
        postProcessCam->addChild(brtr::createScreenQuad(width, height));

//width and height are screen width and height optained through:
//ref_ptr<GraphicsContext::WindowingSystemInterface> wsi = 
GraphicsContext::getWindowingSystemInterface();
//    unsigned int width, height;
//   wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, 
height);

        osg::ref_ptr<osg::Shader> fogFrag = 
osgDB::readShaderFile("../Shader/fogShader.frag");
        osg::ref_ptr<osg::Shader> fogVert = 
osgDB::readShaderFile("../Shader/fogShader.vert");
        osg::ref_ptr<osg::Program> fogProgram = new osg::Program;
        fogProgram->addShader(fogFrag);
        fogProgram->addShader(fogVert);

      //second program for switching, not part of the problem (switching to 
sepia works and the color bingo is now sepia)
        osg::ref_ptr<osg::Shader> sepiaFogFrag = 
osgDB::readShaderFile("../Shader/sepiaFogShader.frag");
        osg::ref_ptr<osg::Shader> sepiaFogVert = 
osgDB::readShaderFile("../Shader/fogShader.vert");
        osg::ref_ptr<osg::Program> sepiaFogProgram = new osg::Program;
        sepiaFogProgram->addShader(sepiaFogFrag);
        sepiaFogProgram->addShader(sepiaFogVert);

        //creating Program Array, element 0 should be the active one
      //for switching, not part of the problem
        osg::ref_ptr<osg::Program>* programs = new 
osg::ref_ptr<osg::Program>[2];
        programs[0] = fogProgram;
        programs[1] = sepiaFogProgram;

        
postProcessCam->getOrCreateStateSet()->setAttributeAndModes(programs[0], 
osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);
        postProcessCam->getOrCreateStateSet()->setTextureAttributeAndModes(0, 
toonAndOutline, osg::StateAttribute::ON);
        postProcessCam->getOrCreateStateSet()->addUniform(new 
osg::Uniform("texture0", 0));
        postProcessCam->getOrCreateStateSet()->setTextureAttributeAndModes(1, 
deepth, osg::StateAttribute::ON);
        postProcessCam->getOrCreateStateSet()->addUniform(new 
osg::Uniform("deepth", 1));
        postProcessCam->getOrCreateStateSet()->addUniform(new 
osg::Uniform("fogColor", Vec3f(0.3, 0.1, 0.1)));

        //setting Clipping Pane
        float zNear = 0.01, zFar = 100000;
        osg::ref_ptr<osg::Uniform> zNearUniform = new osg::Uniform("zNear", 
zNear);
        osg::ref_ptr<osg::Uniform> zFarUniform = new osg::Uniform("zFar", zFar);
        postProcessCam->getOrCreateStateSet()->addUniform(zNearUniform);
        postProcessCam->getOrCreateStateSet()->addUniform(zFarUniform);
        
viewer.getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
        viewer.getCamera()->setProjectionMatrixAsPerspective(70, 1.778, zNear, 
zFar);
        //not needed anymore
        //viewer.getCamera()->setPreDrawCallback(new 
brtr::UpdateNearFearUniformCallback(zNearUniform, zFarUniform));

        //Setting Pipeline 
        pipe.pass_0_color = rttCamToon;
        pipe.pass_0_depth = rttCamDepth;
        pipe.pass_PostProcess = postProcessCam;
        pipe.programs = programs; //for switching, not part of the problem
        pipe.programCount = 2;  //for switching, not part of the problem
}

//final scene-graph looks like this
[...]
ref_ptr<Group> rootForToon = new Group;
rootForToon->addChild(trainStation);
rootForToon->addChild(leftBench);
rootForToon->addChild(rightBench);
rootForToon->addChild(train);
rootForToon->setDataVariance(Object::STATIC);
//Create light from cookbook
ref_ptr<LightSource> light0 = brtr::createLight(Vec3(-76.88403, -8.27441, 
20.63965), 0);
ref_ptr<LightSource> light1 = brtr::createLight(Vec3(-26.8972, 1.97552, 
20.02043), 1);
ref_ptr<LightSource> light2 = brtr::createLight(Vec3(24.33239, 2.49185, 
21.58063), 2);
ref_ptr<LightSource> light3 = brtr::createLight(Vec3(74.73347, -8.13866, 
21.33362), 3);
rootForToon->addChild(light0);
rootForToon->addChild(light1);
rootForToon->addChild(light2);
rootForToon->addChild(light3);

brtr::RenderingPipeline pipe;
brtr::createRenderingPipeline(width, height, *rootForToon, viewer, 
"2d_toons_violet.png", pipe);
[...]
ref_ptr<Group> sceneData = new Group;
//add elements to sceneData

sceneData->addChild(pipe.pass_0_color);
sceneData->addChild(pipe.pass_0_depth);
sceneData->addChild(pipe.pass_PostProcess);  
sceneData->addChild(trainStationHitbox);
sceneData->addChild(weaponHUD);
sceneData->addChild(textHUD);
viewer.setSceneData(sceneData);
[...]





Any help appreciated, thanks to anyone how read all this. 

Thank you!

Cheers,
Fitz

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=59737#59737




Attachments: 
http://forum.openscenegraph.org//files/braintrain_nvidia_error3_207.jpg
http://forum.openscenegraph.org//files/braintrain_nvidia_shader_error2_119.png
http://forum.openscenegraph.org//files/braintrain_nvidia_shader_error1_453.png
http://forum.openscenegraph.org//files/braintrain_amd_howitshould2_214.png
http://forum.openscenegraph.org//files/braintrain_amd_howitshould1_208.png


_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to