Hi,
First, thanks for your reply. So, my basic test to "light the way" is the next:
1. I'm used the two shaders (vert and frag) for StandardShadowMap:
frag:
Code:
uniform sampler2DShadow shadowTexture;
float DynamicShadow( )
{
return shadow2DProj( shadowTexture, gl_TexCoord[1] ).r;
}
//following expressions are auto modified - do not change them:
//gl_TexCoord[0] 0 - can be subsituted with other index
float DynamicShadow( );
varying vec4 colorAmbientEmissive;
uniform sampler2D baseTexture;
void main(void)
{
vec4 color = texture2D( baseTexture, gl_TexCoord[0].xy );
color *= mix( colorAmbientEmissive, gl_Color, DynamicShadow() );
float fog = clamp((gl_Fog.end - gl_FogFragCoord)*gl_Fog.scale, 0.,1.);
color.rgb = mix( gl_Fog.color.rgb, color.rgb, fog );
gl_FragColor = color;
}
vert:
Code:
void DynamicShadow( in vec4 ecPosition )
{
// generate coords for shadow mapping
gl_TexCoord[1].s = dot( ecPosition, gl_EyePlaneS[1] );
gl_TexCoord[1].t = dot( ecPosition, gl_EyePlaneT[1] );
gl_TexCoord[1].p = dot( ecPosition, gl_EyePlaneR[1] );
gl_TexCoord[1].q = dot( ecPosition, gl_EyePlaneQ[1] );
}
// following expressions are auto modified - do not change them:
// gl_TexCoord[0] 0 - can be subsituted with other index
// gl_TextureMatrix[0] 0 - can be subsituted with other index
// gl_MultiTexCoord0 0 - can be subsituted with other index
const int NumEnabledLights = 1;
void DynamicShadow( in vec4 ecPosition );
varying vec4 colorAmbientEmissive;
void SpotLight(in int i,
in vec3 eye,
in vec3 ecPosition3,
in vec3 normal,
inout vec4 ambient,
inout vec4 diffuse,
inout vec4 specular)
{
float nDotVP; // normal . light direction
float nDotHV; // normal . light half vector
float pf; // power factor
float spotDot; // cosine of angle between spotlight
float spotAttenuation; // spotlight attenuation factor
float attenuation; // computed attenuation factor
float d; // distance from surface to light source
vec3 VP; // direction from surface to light position
vec3 halfVector; // direction of maximum highlights
// Compute vector from surface to light position
VP = vec3(gl_LightSource[i].position) - ecPosition3;
// Compute distance between surface and light position
d = length(VP);
// Normalize the vector from surface to light position
VP = normalize(VP);
// Compute attenuation
attenuation = 1.0 / (gl_LightSource[i].constantAttenuation +
gl_LightSource[i].linearAttenuation * d +
gl_LightSource[i].quadraticAttenuation *d*d);
// See if point on surface is inside cone of illumination
spotDot = dot(-VP, normalize(gl_LightSource[i].spotDirection));
if (spotDot < gl_LightSource[i].spotCosCutoff)
spotAttenuation = 0.0; // light adds no contribution
else
spotAttenuation = pow(spotDot, gl_LightSource[i].spotExponent);
// Combine the spotlight and distance attenuation.
attenuation *= spotAttenuation;
halfVector = normalize(VP + eye);
nDotVP = max(0.0, dot(normal, VP));
nDotHV = max(0.0, dot(normal, halfVector));
if (nDotVP == 0.0)
pf = 0.0;
else
pf = pow(nDotHV, gl_FrontMaterial.shininess);
ambient += gl_LightSource[i].ambient * attenuation;
diffuse += gl_LightSource[i].diffuse * nDotVP * attenuation;
specular += gl_LightSource[i].specular * pf * attenuation;
}
void PointLight(in int i,
in vec3 eye,
in vec3 ecPosition3,
in vec3 normal,
inout vec4 ambient,
inout vec4 diffuse,
inout vec4 specular)
{
float nDotVP; // normal . light direction
float nDotHV; // normal . light half vector
float pf; // power factor
float attenuation; // computed attenuation factor
float d; // distance from surface to light source
vec3 VP; // direction from surface to light position
vec3 halfVector; // direction of maximum highlights
// Compute vector from surface to light position
VP = vec3(gl_LightSource[i].position) - ecPosition3;
// Compute distance between surface and light position
d = length(VP);
// Normalize the vector from surface to light position
VP = normalize(VP);
// Compute attenuation
attenuation = 1.0 / (gl_LightSource[i].constantAttenuation +
gl_LightSource[i].linearAttenuation * d +
gl_LightSource[i].quadraticAttenuation * d*d);
halfVector = normalize(VP + eye);
nDotVP = max(0.0, dot(normal, VP));
nDotHV = max(0.0, dot(normal, halfVector));
if (nDotVP == 0.0)
pf = 0.0;
else
pf = pow(nDotHV, gl_FrontMaterial.shininess);
ambient += gl_LightSource[i].ambient * attenuation;
diffuse += gl_LightSource[i].diffuse * nDotVP * attenuation;
specular += gl_LightSource[i].specular * pf * attenuation;
}
void DirectionalLight(in int i,
in vec3 normal,
inout vec4 ambient,
inout vec4 diffuse,
inout vec4 specular)
{
float nDotVP; // normal . light direction
float nDotHV; // normal . light half vector
float pf; // power factor
nDotVP = max(0.0, dot(normal,
normalize(vec3(gl_LightSource[i].position))));
nDotHV = max(0.0, dot(normal,
vec3(gl_LightSource[i].halfVector)));
if (nDotVP == 0.0)
pf = 0.0;
else
pf = pow(nDotHV, gl_FrontMaterial.shininess);
ambient += gl_LightSource[i].ambient;
diffuse += gl_LightSource[i].diffuse * nDotVP;
specular += gl_LightSource[i].specular * pf;
}
void main( )
{
// Transform vertex to clip space
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
vec3 normal = normalize( gl_NormalMatrix * gl_Normal );
vec4 ecPos = gl_ModelViewMatrix * gl_Vertex;
float ecLen = length( ecPos );
vec3 ecPosition3 = ecPos.xyz / ecPos.w;
vec3 eye = vec3( 0.0, 0.0, 1.0 );
//vec3 eye = -normalize(ecPosition3);
DynamicShadow( ecPos );
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
// Front Face lighting
// Clear the light intensity accumulators
vec4 amb = vec4(0.0);
vec4 diff = vec4(0.0);
vec4 spec = vec4(0.0);
// Loop through enabled lights, compute contribution from each
for (int i = 0; i < NumEnabledLights; i++)
{
if (gl_LightSource[i].position.w == 0.0)
DirectionalLight(i, normal, amb, diff, spec);
else if (gl_LightSource[i].spotCutoff == 180.0)
PointLight(i, eye, ecPosition3, normal, amb, diff, spec);
else
SpotLight(i, eye, ecPosition3, normal, amb, diff, spec);
}
colorAmbientEmissive = gl_FrontLightModelProduct.sceneColor +
amb * gl_FrontMaterial.ambient;
gl_FrontColor = colorAmbientEmissive +
diff * gl_FrontMaterial.diffuse;
gl_FrontSecondaryColor = vec4(spec*gl_FrontMaterial.specular);
gl_BackColor = gl_FrontColor;
gl_BackSecondaryColor = gl_FrontSecondaryColor;
gl_FogFragCoord = ecLen;
}
For now I'm not used any other GLSL code. So, I've created a simple application
like this:
Code:
int main (int argc, char* argv[])
{
osg::ArgumentParser psr(&argc, argv);
osgViewer::Viewer viewer(psr);
std::string file = "path/to/model.osg";
std::string terr = "path/to/terrain.osg";
osg::ref_ptr<osgShadow::MinimalShadowMap> l_MinimalShadowMap;
l_MinimalShadowMap = new osgShadow::LightSpacePerspectiveShadowMapCB();
l_MinimalShadowMap->setMinLightMargin(10.0);
l_MinimalShadowMap->setMaxFarPlane(1000.0);
l_MinimalShadowMap->setTextureSize(osg::Vec2s(2048, 2048));
l_MinimalShadowMap->setBaseTextureCoordIndex(0);
l_MinimalShadowMap->setBaseTextureUnit(0);
l_MinimalShadowMap->setShadowTextureCoordIndex(1);
l_MinimalShadowMap->setShadowTextureUnit(1);
osg::ref_ptr<osgShadow::ShadowedScene> root = new osgShadow::ShadowedScene;
root->setReceivesShadowTraversalMask(RECEIVES_SHADOW_TRAVERSAL_MASK);
root->setCastsShadowTraversalMask(CASTS_SHADOW_TRAVERSAL_MASK);
root->setShadowTechnique(l_MinimalShadowMap.get());
osg::Group* obj2 = dynamic_cast<osg::Group*>(osgDB::readNodeFile(terr));
osg::Group* obj1 = dynamic_cast<osg::Group*>(osgDB::readNodeFile(file));
if (obj1 == NULL || obj2 == NULL) {
osg::notify(osg::FATAL) << "can't read file " << file << std::endl;
return 1;
}
root->addChild(obj2);
root->addChild(obj1);
// add the state manipulator
viewer.addEventHandler(new
osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
// add the thread model handler
viewer.addEventHandler(new osgViewer::ThreadingHandler);
// add the window size toggle handler
viewer.addEventHandler(new osgViewer::WindowSizeHandler);
// add the stats handler
viewer.addEventHandler(new osgViewer::StatsHandler);
// add the help handler
viewer.addEventHandler(new
osgViewer::HelpHandler(psr.getApplicationUsage()));
// add the LOD Scale handler
viewer.addEventHandler(new osgViewer::LODScaleHandler);
// add the screen capture handler
viewer.addEventHandler(new osgViewer::ScreenCaptureHandler);
viewer.setSceneData(root);
osg::LightSource* light = createLight(osg::Vec4(10,-10,5,0),
osg::Vec4(1,1,1,1), osg::Vec4(1,1,1,1), osg::Vec4(1,1,1,1));
osg::StateSet* planeStateset =
static_cast<osg::Geode*>(obj1->getChild(0))->getOrCreateStateSet();
light->setStateSetModes(*planeStateset, osg::StateAttribute::ON);
osg::MatrixTransform * transform = new osg::MatrixTransform();
transform->addChild(light);
root->addChild(transform);
osg::Shader * VertexShader = new osg::Shader( osg::Shader::VERTEX );
osg::Shader * PixelShader = new osg::Shader( osg::Shader::FRAGMENT );
osg::Program* prg = new osg::Program;
//This visitor loads the shaders above and applies them to all nodes.
PrepareNodeForShading visitor;
visitor.setTheProgram(prg);
visitor.setShaders(VertexShader, PixelShader);
root.get()->accept(visitor);
return viewer.run();
The scene is black. I would expect the shadows. I have something terribly
wrong. Some suggestions?
Thank you!
Cheers,
Dario
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=49010#49010
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org