Skip to content

Commit

Permalink
From Anders Backman, added bias and texture size methods.
Browse files Browse the repository at this point in the history
From Robert Osfield, tweaks to the above for method parameters and indenting.
  • Loading branch information
robertosfield committed Sep 20, 2007
1 parent 5fb9673 commit 55a9ea1
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 45 deletions.
24 changes: 24 additions & 0 deletions include/osgShadow/SoftShadowMap
Expand Up @@ -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.*/
Expand Down Expand Up @@ -87,6 +108,9 @@ class OSGSHADOW_EXPORT SoftShadowMap : public ShadowTechnique
osg::Vec2 _ambientBias;
float _softnesswidth;
float _jitteringscale;
float _bias;
osg::Vec2s _textureSize;

};

}
Expand Down
102 changes: 57 additions & 45 deletions src/osgShadow/SoftShadowMap.cpp
Expand Up @@ -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)
{
}

Expand All @@ -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)
{
}

Expand All @@ -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);

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) );

// 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];

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

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

float v[4], d[4];

for ( unsigned int r = 0; r < R; ++r )
{
const int x = r % ( gridW / 2 );
const int y = ( gridH - 1 ) - ( r / (gridW / 2) );

// 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];

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

// 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)
Expand Down

0 comments on commit 55a9ea1

Please sign in to comment.