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