From Anders Backman, added bias and texture size methods.

From Robert Osfield, tweaks to the above for method parameters and indenting.
This commit is contained in:
Robert Osfield 2007-09-20 10:12:58 +00:00
parent 5fb9673382
commit 55a9ea19d7
2 changed files with 76 additions and 40 deletions

View File

@ -40,6 +40,27 @@ class OSGSHADOW_EXPORT SoftShadowMap : public ShadowTechnique
/** Set the values for the ambient bias the shader will use.*/
void setAmbientBias(const osg::Vec2& ambientBias );
/** Set the resolution of the rendertarget texture used for shadow generation */
void setTextureSize(int width, int height) { setTextureSize(osg::Vec2s(width, height)); }
/** Set the resolution of the rendertarget texture used for shadow generation */
void setTextureSize(const osg::Vec2s&);
/** Get the resolution of the rendertarget texture used for shadow generation */
const osg::Vec2s& getTextureSize() const { return _textureSize; }
/** Add a small bias to the z-value when calculating the MVPT matrix, this can reduce
* shadow acne problem.
* Suitable values are 0-0.005
* Default is 0. */
void setBias(float bias) { _bias = bias; }
/** Return the bias value set used when calculating the MVPT matrix */
float getBias() const { return _bias; }
/** Set the values for width of the soft penumbra the shader will use.
* Zero is for hard shadow (no penumbra). 0.01 is already very soft penumbra.
* Default is 0.005.*/
@ -87,6 +108,9 @@ class OSGSHADOW_EXPORT SoftShadowMap : public ShadowTechnique
osg::Vec2 _ambientBias;
float _softnesswidth;
float _jitteringscale;
float _bias;
osg::Vec2s _textureSize;
};
}

View File

@ -157,7 +157,9 @@ SoftShadowMap::SoftShadowMap():
_textureUnit(1),
_ambientBias(0.5f,0.5f),
_softnesswidth(0.005f),
_jitteringscale(32.f)
_jitteringscale(32.f),
_bias(0.0f),
_textureSize(1024, 1024)
{
}
@ -166,7 +168,9 @@ SoftShadowMap::SoftShadowMap(const SoftShadowMap& copy, const osg::CopyOp& copyo
_textureUnit(copy._textureUnit),
_ambientBias(copy._ambientBias),
_softnesswidth(copy._softnesswidth),
_jitteringscale(copy._jitteringscale)
_jitteringscale(copy._jitteringscale),
_bias(copy._bias),
_textureSize(copy._textureSize)
{
}
@ -190,16 +194,24 @@ void SoftShadowMap::setJitteringScale(const float jitteringscale )
_jitteringscale = jitteringscale;
}
void SoftShadowMap::setTextureSize(const osg::Vec2s& texsize)
{
_textureSize = texsize;
if (_texture.valid())
{
_texture->setTextureSize(_textureSize[0], _textureSize[1]);
_camera->setViewport(0,0,_textureSize[0], _textureSize[1]);
}
}
void SoftShadowMap::init()
{
if (!_shadowedScene) return;
unsigned int tex_width = 1024;
unsigned int tex_height = 1024;
_texture = new osg::Texture2D;
_texture->setTextureSize(tex_width, tex_height);
_texture->setTextureSize(_textureSize[0], _textureSize[1]);
_texture->setInternalFormat(GL_DEPTH_COMPONENT);
_texture->setSourceType(GL_UNSIGNED_INT);
@ -228,7 +240,7 @@ void SoftShadowMap::init()
_camera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR);
// set viewport
_camera->setViewport(0,0,tex_width,tex_height);
_camera->setViewport(0,0,_textureSize[0],_textureSize[1]);
// set the camera to render before the main camera.
_camera->setRenderOrder(osg::Camera::PRE_RENDER);
@ -410,7 +422,7 @@ void SoftShadowMap::cull(osgUtil::CullVisitor& cv)
osg::Matrix MVPT = _camera->getViewMatrix() *
_camera->getProjectionMatrix() *
osg::Matrix::translate(1.0,1.0,1.0) *
osg::Matrix::scale(0.5f,0.5f,0.5f);
osg::Matrix::scale(0.5,0.5,0.5+_bias);
_texgen->setMode(osg::TexGen::EYE_LINEAR);
_texgen->setPlanesFromMatrix(MVPT);
@ -460,45 +472,45 @@ void SoftShadowMap::initJittering(osg::StateSet *ss)
for ( unsigned int s = 0; s < size; ++s )
{
for ( unsigned int t = 0; t < size; ++t )
{
float v[4], d[4];
for ( unsigned int r = 0; r < R; ++r )
for ( unsigned int t = 0; t < size; ++t )
{
const int x = r % ( gridW / 2 );
const int y = ( gridH - 1 ) - ( r / (gridW / 2) );
float v[4], d[4];
// Generate points on a regular gridW x gridH rectangular
// grid. We multiply x by 2 because, we treat 2
// consecutive x each loop iteration. Add 0.5f to be in
// the center of the pixel. x, y belongs to [ 0.0, 1.0 ].
v[0] = float( x * 2 + 0.5f ) / gridW;
v[1] = float( y + 0.5f ) / gridH;
v[2] = float( x * 2 + 1 + 0.5f ) / gridW;
v[3] = v[1];
for ( unsigned int r = 0; r < R; ++r )
{
const int x = r % ( gridW / 2 );
const int y = ( gridH - 1 ) - ( r / (gridW / 2) );
// Jitter positions. ( 0.5f / w ) == ( 1.0f / 2*w )
v[0] += ((float)rand() * 2.f / RAND_MAX - 1.f) * ( 0.5f / gridW );
v[1] += ((float)rand() * 2.f / RAND_MAX - 1.f) * ( 0.5f / gridH );
v[2] += ((float)rand() * 2.f / RAND_MAX - 1.f) * ( 0.5f / gridW );
v[3] += ((float)rand() * 2.f / RAND_MAX - 1.f) * ( 0.5f / gridH );
// Generate points on a regular gridW x gridH rectangular
// grid. We multiply x by 2 because, we treat 2
// consecutive x each loop iteration. Add 0.5f to be in
// the center of the pixel. x, y belongs to [ 0.0, 1.0 ].
v[0] = float( x * 2 + 0.5f ) / gridW;
v[1] = float( y + 0.5f ) / gridH;
v[2] = float( x * 2 + 1 + 0.5f ) / gridW;
v[3] = v[1];
// Warp to disk; values in [-1,1]
d[0] = sqrtf( v[1] ) * cosf( 2.f * 3.1415926f * v[0] );
d[1] = sqrtf( v[1] ) * sinf( 2.f * 3.1415926f * v[0] );
d[2] = sqrtf( v[3] ) * cosf( 2.f * 3.1415926f * v[2] );
d[3] = sqrtf( v[3] ) * sinf( 2.f * 3.1415926f * v[2] );
// Jitter positions. ( 0.5f / w ) == ( 1.0f / 2*w )
v[0] += ((float)rand() * 2.f / RAND_MAX - 1.f) * ( 0.5f / gridW );
v[1] += ((float)rand() * 2.f / RAND_MAX - 1.f) * ( 0.5f / gridH );
v[2] += ((float)rand() * 2.f / RAND_MAX - 1.f) * ( 0.5f / gridW );
v[3] += ((float)rand() * 2.f / RAND_MAX - 1.f) * ( 0.5f / gridH );
// store d into unsigned values [0,255]
const unsigned int tmp = ( (r * size * size) + (t * size) + s ) * 4;
data3D[ tmp + 0 ] = (unsigned char)( ( 1.f + d[0] ) * 127 );
data3D[ tmp + 1 ] = (unsigned char)( ( 1.f + d[1] ) * 127 );
data3D[ tmp + 2 ] = (unsigned char)( ( 1.f + d[2] ) * 127 );
data3D[ tmp + 3 ] = (unsigned char)( ( 1.f + d[3] ) * 127 );
// Warp to disk; values in [-1,1]
d[0] = sqrtf( v[1] ) * cosf( 2.f * 3.1415926f * v[0] );
d[1] = sqrtf( v[1] ) * sinf( 2.f * 3.1415926f * v[0] );
d[2] = sqrtf( v[3] ) * cosf( 2.f * 3.1415926f * v[2] );
d[3] = sqrtf( v[3] ) * sinf( 2.f * 3.1415926f * v[2] );
// store d into unsigned values [0,255]
const unsigned int tmp = ( (r * size * size) + (t * size) + s ) * 4;
data3D[ tmp + 0 ] = (unsigned char)( ( 1.f + d[0] ) * 127 );
data3D[ tmp + 1 ] = (unsigned char)( ( 1.f + d[1] ) * 127 );
data3D[ tmp + 2 ] = (unsigned char)( ( 1.f + d[2] ) * 127 );
data3D[ tmp + 3 ] = (unsigned char)( ( 1.f + d[3] ) * 127 );
}
}
}
}
// the GPU Gem implementation uses a NV specific internal texture format (GL_SIGNED_RGBA_NV)