Basic shadow volume alogirthm implemented in example.
This commit is contained in:
parent
808047ee1b
commit
a9d18d01db
@ -3,6 +3,9 @@
|
||||
#include <osg/LightModel>
|
||||
#include <osg/Depth>
|
||||
#include <osg/BlendFunc>
|
||||
#include <osg/Camera>
|
||||
#include <osg/Stencil>
|
||||
#include <osg/CullFace>
|
||||
|
||||
#include <osgProducer/Viewer>
|
||||
|
||||
@ -141,11 +144,13 @@ int main(int argc, char** argv)
|
||||
while (arguments.read("--directionalLight")) postionalLight = false;
|
||||
|
||||
bool addOccluderToScene = false;
|
||||
while (arguments.read("addOccluderToScene")) addOccluderToScene = true;
|
||||
while (arguments.read("--addOccluderToScene")) addOccluderToScene = true;
|
||||
|
||||
bool updateLightPosition = true;
|
||||
while (arguments.read("--noUpdate")) updateLightPosition = false;
|
||||
|
||||
bool doShadow = true;
|
||||
while (arguments.read("--noShadow")) doShadow = false;
|
||||
|
||||
// any option left unread are converted into errors to write out later.
|
||||
arguments.reportRemainingOptionsAsUnrecognized();
|
||||
@ -210,11 +215,15 @@ int main(int argc, char** argv)
|
||||
occluder->comptueShadowVolumeGeometry(lightpos, *shadowVolume);
|
||||
geode->addDrawable(shadowVolume.get());
|
||||
group->addChild(geode.get());
|
||||
|
||||
osg::StateSet* ss = geode->getOrCreateStateSet();
|
||||
ss->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::Vec4 ambient(0.5,0.5,0.5,1.0);
|
||||
osg::Vec4 diffuse(1.0,1.0,1.0,1.0);
|
||||
osg::Vec4 ambient(0.2,0.2,0.2,1.0);
|
||||
osg::Vec4 diffuse(0.8,0.8,0.8,1.0);
|
||||
osg::Vec4 zero_colour(0.0,0.0,0.0,1.0);
|
||||
|
||||
// first group
|
||||
@ -234,51 +243,111 @@ int main(int argc, char** argv)
|
||||
light1->setAmbient(ambient);
|
||||
light1->setDiffuse(zero_colour);
|
||||
light1->setPosition(lightpos);
|
||||
ss1->setAttributeAndModes(light1, osg::StateAttribute::ON);
|
||||
ss1->setAttributeAndModes(light1, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
|
||||
ss1->setMode(GL_LIGHTING, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
|
||||
|
||||
}
|
||||
|
||||
// second group
|
||||
{
|
||||
// use a camera here just to implement a seperate post rendering stage.
|
||||
osg::Camera* camera = new osg::Camera;
|
||||
camera->setRenderOrder(osg::Camera::POST_RENDER);
|
||||
camera->setClearMask(GL_STENCIL_BUFFER_BIT);
|
||||
group->addChild(camera);
|
||||
|
||||
osg::Group* second_model_group = new osg::Group;
|
||||
second_model_group->addChild(model.get());
|
||||
group->addChild(second_model_group);
|
||||
osg::StateSet* ss_camera = camera->getOrCreateStateSet();
|
||||
|
||||
osg::StateSet* ss1 = second_model_group->getOrCreateStateSet();
|
||||
ss1->setRenderBinDetails(1, "RenderBin");
|
||||
|
||||
osg::LightModel* lm1 = new osg::LightModel;
|
||||
lm1->setAmbientIntensity(zero_colour);
|
||||
ss1->setAttribute(lm1);
|
||||
|
||||
|
||||
osg::LightSource* lightsource = new osg::LightSource;
|
||||
lightsource->setLight(light.get());
|
||||
light->setAmbient(zero_colour);
|
||||
light->setDiffuse(diffuse);
|
||||
light->setPosition(lightpos);
|
||||
second_model_group->addChild(lightsource);
|
||||
|
||||
ss1->setMode(GL_LIGHT0, osg::StateAttribute::ON);
|
||||
|
||||
osg::Depth* depth = new osg::Depth;
|
||||
depth->setWriteMask(false);
|
||||
depth->setFunction(osg::Depth::LEQUAL);
|
||||
ss1->setAttribute(depth);
|
||||
|
||||
osg::BlendFunc* blend = new osg::BlendFunc;
|
||||
blend->setFunction(osg::BlendFunc::ONE, osg::BlendFunc::ONE);
|
||||
ss1->setAttributeAndModes(blend, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
|
||||
|
||||
}
|
||||
ss_camera->setAttribute(depth);
|
||||
|
||||
{
|
||||
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
|
||||
occluder->comptueShadowVolumeGeometry(lightpos, *shadowVolume);
|
||||
geode->addDrawable(shadowVolume.get());
|
||||
group->addChild(geode.get());
|
||||
}
|
||||
{
|
||||
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
|
||||
occluder->comptueShadowVolumeGeometry(lightpos, *shadowVolume);
|
||||
geode->addDrawable(shadowVolume.get());
|
||||
|
||||
// switch off the writing to the color bit planes.
|
||||
osg::ColorMask* colourMask = new osg::ColorMask;
|
||||
colourMask->setMask(false,false,false,false);
|
||||
|
||||
osg::Stencil* stencil = new osg::Stencil;
|
||||
stencil->setFunction(osg::Stencil::ALWAYS,0,~0u);
|
||||
stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::INCR);
|
||||
|
||||
osg::StateSet* ss_sv1 = geode->getOrCreateStateSet();
|
||||
ss_sv1->setRenderBinDetails(0, "RenderBin");
|
||||
ss_sv1->setAttributeAndModes(stencil,osg::StateAttribute::ON);
|
||||
ss_sv1->setAttribute(colourMask);
|
||||
|
||||
ss_sv1->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
|
||||
|
||||
camera->addChild(geode.get());
|
||||
}
|
||||
|
||||
if (true)
|
||||
{
|
||||
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
|
||||
occluder->comptueShadowVolumeGeometry(lightpos, *shadowVolume);
|
||||
geode->addDrawable(shadowVolume.get());
|
||||
|
||||
// switch off the writing to the color bit planes.
|
||||
osg::ColorMask* colourMask = new osg::ColorMask;
|
||||
colourMask->setMask(false,false,false,false);
|
||||
|
||||
osg::Stencil* stencil = new osg::Stencil;
|
||||
stencil->setFunction(osg::Stencil::ALWAYS,0,~0u);
|
||||
stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::DECR);
|
||||
|
||||
osg::StateSet* ss_sv1 = geode->getOrCreateStateSet();
|
||||
ss_sv1->setRenderBinDetails(1, "RenderBin");
|
||||
ss_sv1->setAttributeAndModes(stencil,osg::StateAttribute::ON);
|
||||
ss_sv1->setAttribute(colourMask);
|
||||
|
||||
ss_sv1->setAttributeAndModes(new osg::CullFace(osg::CullFace::FRONT), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
|
||||
|
||||
camera->addChild(geode.get());
|
||||
}
|
||||
|
||||
{
|
||||
osg::Group* second_model_group = new osg::Group;
|
||||
second_model_group->addChild(model.get());
|
||||
|
||||
|
||||
osg::StateSet* ss1 = second_model_group->getOrCreateStateSet();
|
||||
ss1->setRenderBinDetails(5, "RenderBin");
|
||||
|
||||
osg::LightModel* lm1 = new osg::LightModel;
|
||||
lm1->setAmbientIntensity(zero_colour);
|
||||
ss1->setAttribute(lm1);
|
||||
|
||||
|
||||
osg::LightSource* lightsource = new osg::LightSource;
|
||||
lightsource->setLight(light.get());
|
||||
light->setAmbient(zero_colour);
|
||||
light->setDiffuse(diffuse);
|
||||
light->setPosition(lightpos);
|
||||
second_model_group->addChild(lightsource);
|
||||
|
||||
ss1->setMode(GL_LIGHT0, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
|
||||
|
||||
// set up the stencil ops so that only operator on this mirrors stencil value.
|
||||
osg::Stencil* stencil = new osg::Stencil;
|
||||
stencil->setFunction(osg::Stencil::EQUAL,0,~0u);
|
||||
stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::KEEP);
|
||||
ss1->setAttributeAndModes(stencil,osg::StateAttribute::ON);
|
||||
|
||||
|
||||
osg::BlendFunc* blend = new osg::BlendFunc;
|
||||
blend->setFunction(osg::BlendFunc::ONE, osg::BlendFunc::ONE);
|
||||
ss1->setAttributeAndModes(blend, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
|
||||
ss1->setMode(GL_LIGHTING, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
|
||||
|
||||
camera->addChild(second_model_group);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -962,7 +962,7 @@ void DrawShapeVisitor::apply(const HeightField& field)
|
||||
// draw skirt at begining if required.
|
||||
if (field.getSkirtHeight()!=0.0f)
|
||||
{
|
||||
vertTop.set(0.0f,dy*(float)row+dy,field.getHeight(0,row+1)-field.getSkirtHeight());
|
||||
vertTop.set(0.0f,dy*(float)(row+1),field.getHeight(0,row+1)-field.getSkirtHeight());
|
||||
normTop.set(field.getNormal(0,row+1));
|
||||
|
||||
vertBase.set(0.0f,dy*(float)row,field.getHeight(0,row)-field.getSkirtHeight());
|
||||
@ -979,7 +979,7 @@ void DrawShapeVisitor::apply(const HeightField& field)
|
||||
|
||||
for(unsigned int col=0;col<field.getNumColumns();++col,u+=du)
|
||||
{
|
||||
vertTop.set(dx*(float)col,dy*(float)row+dy,field.getHeight(col,row+1));
|
||||
vertTop.set(dx*(float)col,dy*(float)(row+1),field.getHeight(col,row+1));
|
||||
normTop.set(field.getNormal(col,row+1));
|
||||
|
||||
vertBase.set(dx*(float)col,dy*(float)row,field.getHeight(col,row));
|
||||
@ -1334,6 +1334,15 @@ void PrimitiveShapeVisitor::apply(const Sphere& sphere)
|
||||
|
||||
unsigned int numSegments = 40;
|
||||
unsigned int numRows = 20;
|
||||
float ratio = (_hints ? _hints->getDetailRatio() : 1.0f);
|
||||
if (ratio > 0.0f && ratio != 1.0f) {
|
||||
numRows = (unsigned int) (numRows * ratio);
|
||||
if (numRows < MIN_NUM_ROWS)
|
||||
numRows = MIN_NUM_ROWS;
|
||||
numSegments = (unsigned int) (numSegments * ratio);
|
||||
if (numSegments < MIN_NUM_SEGMENTS)
|
||||
numSegments = MIN_NUM_SEGMENTS;
|
||||
}
|
||||
|
||||
float lDelta = osg::PI/(float)numRows;
|
||||
float vDelta = 1.0f/(float)numRows;
|
||||
@ -1708,7 +1717,7 @@ void PrimitiveShapeVisitor::apply(const HeightField& field)
|
||||
|
||||
for(unsigned int col=0;col<field.getNumColumns();++col)
|
||||
{
|
||||
Vec3 vertTop(dx*(float)col,dy*(float)row+dy,field.getHeight(col,row+1));
|
||||
Vec3 vertTop(dx*(float)col,dy*(float)(row+1),field.getHeight(col,row+1));
|
||||
Vec3 vertBase(dx*(float)col,dy*(float)row,field.getHeight(col,row));
|
||||
|
||||
_functor.vertex(vertTop*matrix);
|
||||
|
@ -350,17 +350,21 @@ struct IndexVec3PtrPair
|
||||
inline bool operator == (const IndexVec3PtrPair& rhs) const
|
||||
{
|
||||
return *vec == *rhs.vec;
|
||||
|
||||
// return (*vec - *rhs.vec).length2() < 1e-2;
|
||||
|
||||
}
|
||||
|
||||
const osg::Vec3* vec;
|
||||
unsigned int index;
|
||||
};
|
||||
|
||||
|
||||
void OccluderGeometry::removeDuplicateVertices()
|
||||
{
|
||||
if (_vertices.empty()) return;
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"OccluderGeometry::removeDuplicates() before = "<<_vertices.size()<<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"OccluderGeometry::removeDuplicates() before = "<<_vertices.size()<<std::endl;
|
||||
|
||||
typedef std::vector<IndexVec3PtrPair> IndexVec3PtrPairs;
|
||||
IndexVec3PtrPairs indexVec3PtrPairs;
|
||||
@ -386,7 +390,7 @@ void OccluderGeometry::removeDuplicateVertices()
|
||||
|
||||
for(; curr != indexVec3PtrPairs.end(); ++curr)
|
||||
{
|
||||
if (*prev==*curr)
|
||||
if (*prev==*curr)
|
||||
{
|
||||
++numDuplicates;
|
||||
}
|
||||
@ -397,8 +401,8 @@ void OccluderGeometry::removeDuplicateVertices()
|
||||
}
|
||||
}
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"Num diplicates = "<<numDuplicates<<std::endl;
|
||||
// osg::notify(osg::NOTICE)<<"Num unique = "<<numUnique<<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"Num diplicates = "<<numDuplicates<<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"Num unique = "<<numUnique<<std::endl;
|
||||
|
||||
if (numDuplicates==0) return;
|
||||
|
||||
@ -689,7 +693,7 @@ void OccluderGeometry::computeLightDirectionSlihouetteEdges(const osg::Vec3& lig
|
||||
const osg::Vec3& v1 = _vertices[edge._p1];
|
||||
const osg::Vec3& v2 = _vertices[edge._p2];
|
||||
osg::Vec3 normal = (v2-v1) ^ lightdirection;
|
||||
if (normal * edge._normal < 0.0)
|
||||
if (normal * edge._normal > 0.0)
|
||||
{
|
||||
silhouetteIndices.push_back(edge._p1);
|
||||
silhouetteIndices.push_back(edge._p2);
|
||||
@ -717,7 +721,7 @@ void OccluderGeometry::computeLightPositionSlihouetteEdges(const osg::Vec3& ligh
|
||||
const osg::Vec3& v1 = _vertices[edge._p1];
|
||||
const osg::Vec3& v2 = _vertices[edge._p2];
|
||||
osg::Vec3 normal = (v2-v1) ^ (v1-lightpos);
|
||||
if (normal * edge._normal < 0.0)
|
||||
if (normal * edge._normal > 0.0)
|
||||
{
|
||||
silhouetteIndices.push_back(edge._p1);
|
||||
silhouetteIndices.push_back(edge._p2);
|
||||
@ -801,7 +805,7 @@ void OccluderGeometry::comptueShadowVolumeGeometry(const osg::Vec4& lightpos, Sh
|
||||
shadowVertices.push_back( v2_projected);
|
||||
shadowVertices.push_back( v2);
|
||||
|
||||
osg::Vec3 normal = (v2-v1) ^ lightdirection;
|
||||
osg::Vec3 normal = lightdirection ^ (v2-v1);
|
||||
normal.normalize();
|
||||
shadowNormals.push_back(normal);
|
||||
shadowNormals.push_back(normal);
|
||||
@ -862,7 +866,7 @@ void OccluderGeometry::comptueShadowVolumeGeometry(const osg::Vec4& lightpos, Sh
|
||||
shadowVertices.push_back( v2_projected);
|
||||
shadowVertices.push_back( v2);
|
||||
|
||||
osg::Vec3 normal = (v2-v1) ^ d1;
|
||||
osg::Vec3 normal = d1 ^ (v2-v1);
|
||||
normal.normalize();
|
||||
shadowNormals.push_back(normal);
|
||||
shadowNormals.push_back(normal);
|
||||
|
Loading…
Reference in New Issue
Block a user