void JShadowMappingAlgorithm2::render(GLfloat x, GLfloat y, GLfloat z) {
JLightManager * lightManager = scene->getLightManager();
int numberOfLights = lightManager->getNumberOfLightsUsed();
JModelManager * modelManager = scene->getModelManager();
//INITIALISATION STEP HAS TO BE DONE EACH TIME BECAUSE THE CAMERA
//IS NOT STATIONARY!!!!!!!!!! YOU NITWIT!
//Load identity modelview
//Calculate & save matrices
glPushMatrix();
glLoadIdentity();
gluPerspective(45.0, 1.0, 0.1, 1000.0);
glGetFloatv(GL_MODELVIEW_MATRIX, cameraProjectionMatrix);
glLoadIdentity();
JVector3D pos = scene->getCameraManager()->getCurrentCamera()->getCameraPosition();
JVector3D dir = scene->getCameraManager()->getCurrentCamera()->getCameraDirection();
gluLookAt(pos.x, pos.y, pos.z,
dir.x, dir.y, dir.z,
0.0f, 1.0f, 0.0f);
glGetFloatv(GL_MODELVIEW_MATRIX, cameraViewMatrix);
glLoadIdentity();
gluPerspective(45.0, 1.0, 0.1, 1000.0);
glGetFloatv(GL_MODELVIEW_MATRIX, lightProjectionMatrix);
glLoadIdentity();
JVector3D lightPos = scene->getLightManager()->getLight(0)->getPosition();
gluLookAt(lightPos.x, lightPos.y, lightPos.z,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
glGetFloatv(GL_MODELVIEW_MATRIX, lightViewMatrix);
glPopMatrix();
/////////////////////////////////////////////////////////////////////////
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
for(int i = 0; i < numberOfLights; i++) {
JVector3D lightPos = lightManager->getLight(i)->getPosition();
//First pass - from light's point of view
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(lightProjectionMatrix);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(lightViewMatrix);
//Use viewport the same size as the shadow map
glViewport(0, 0, SHADOW_MAP_WIDTH, SHADOW_MAP_HEIGHT);
//Draw back faces into the shadow map
glCullFace(GL_FRONT);
//Disable color writes, and use flat shading for speed
glShadeModel(GL_FLAT);
glColorMask(0, 0, 0, 0);
scene->renderInternalProperties();
modelManager->render();
//Read the depth buffer into the shadow map texture
glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,SHADOW_MAP_WIDTH, SHADOW_MAP_HEIGHT);
//restore states
glCullFace(GL_BACK);
glShadeModel(GL_SMOOTH);
glColorMask(1, 1, 1, 1);
//bool showShadowMap = true;
// if (showShadowMap)
// return;
//2nd pass - Draw from camera's point of view
glClear(GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(cameraProjectionMatrix);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(cameraViewMatrix);
//glViewPort(0, 0, winWidth, winHeight);
glViewport( viewport[0], viewport[1], viewport[2], viewport[3] );
//Use dim light to represent shadowed areas
GLfloat lightPosition [] = {lightPos.x, lightPos.y, lightPos.z, 1.0};
glLightfv(GL_LIGHT0+i, GL_POSITION, lightPosition );
GLfloat white [] = {0.2,0.2,0.2,1.0};
GLfloat black [] = {0.0,0.0,0.0,1.0};
glLightfv(GL_LIGHT0+i, GL_AMBIENT, white);
glLightfv(GL_LIGHT0+i, GL_DIFFUSE, white);
glLightfv(GL_LIGHT0+i, GL_SPECULAR, black);
glEnable(GL_LIGHT0+i);
glEnable(GL_LIGHTING);
scene->renderInternalProperties();
modelManager->render();
GLfloat cwhite [] = { 1.0,1.0,1.0,1.0};
GLfloat cblack [] = {0.0,0.0,0.0,1.0};
//3rd pass
//Draw with bright light
glLightfv(GL_LIGHT0+i, GL_DIFFUSE, cwhite);
glLightfv(GL_LIGHT0+i, GL_SPECULAR, cwhite);
//Calculate texture matrix for projection
//This matrix takes us from eye space to the light's clip space
//It is postmultiplied by the inverse of the current view matrix when specifying texgen
static MATRIX4X4 biasMatrix(0.5f, 0.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f); //bias from [-1, 1] to [0, 1]
Matrix textureMatrix=biasMatrix*lightProjectionMatrix*lightViewMatrix;
//Set up texture coordinate generation.
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_S, GL_EYE_PLANE, textureMatrix.GetRow(0));
glEnable(GL_TEXTURE_GEN_S);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_T, GL_EYE_PLANE, textureMatrix.GetRow(1));
glEnable(GL_TEXTURE_GEN_T);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_R, GL_EYE_PLANE, textureMatrix.GetRow(2));
glEnable(GL_TEXTURE_GEN_R);
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_Q, GL_EYE_PLANE, textureMatrix.GetRow(3));
glEnable(GL_TEXTURE_GEN_Q);
//Bind & enable shadow map texture
glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
glEnable(GL_TEXTURE_2D);
//Enable shadow comparison
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);
//Shadow comparison should be true (ie not in shadow) if r<=texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
//Shadow comparison should generate an INTENSITY result
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
//Set alpha test to discard false comparisons
glAlphaFunc(GL_GEQUAL, 0.99f);
glEnable(GL_ALPHA_TEST);
//glDisable(GL_TEXTURE_2D);
///glMatrixMode(GL_MODELVIEW);
//glLoadIdentity();
//scene->getCurrentCamera()->Update();
scene->renderInternalProperties();
modelManager->render(true);
//Disable textures and texgen
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glDisable(GL_TEXTURE_GEN_Q);
//Restore other states
glDisable(GL_LIGHTING);
glDisable(GL_ALPHA_TEST);
}
}
Shadow Mapping Woes
I am currently trying to incorporate simple Shadow Mapping into my "engine" and am stumpling into problems which I'm not sure how to fix. Not sure whether my OpenGL code is wrong or my interpretation. I have read various different papers on this, describing various different terms: Cascading, Perspective, Adaptive, Forward, Variance, Deep, Parallel-Split, Trapezoidal and finally Back-projection. I know they all are based on the generic Shadow Mapping algorithm, but how do they differ?
1st Problem) I have a setup such as the following
render() {
for each light {
Setup Projection and View Matrices with respect to the light
renderScene into depth buffer
clear buffer
Setup with respect to the Camera
draw scene
}
}
Open GL Code
I have 3 passes in the above algorithm to add extra light to the scene. Is there anything wrong with the code or just biasing or matrix trouble as I have no outputted shadow.
Neutrinohunter
They can differ in projection organization:
Dual parabolic (two shadowmaps for each halfsphere around a point lightwith parabolic projection, not artifact free)
Cascading (many shadowmaps for directional lights, to avoid under and oversampling. Disadvantage: Many render passes)
Trapezoidal, Perspective... (desperate trys to construct a adaptive projection matrix. All these algorithms suck if the near plane is covered in light direction by the farplane. This case can't be avoided if the user can rotate the cam.)
Variance shadowmapping, this allows to filter shadowmaps with blur, anisotropic and mipmapping filter. Has it's own artifacts, but is most times better than standard filtering. It can be combined with all projections.
Dual parabolic (two shadowmaps for each halfsphere around a point lightwith parabolic projection, not artifact free)
Cascading (many shadowmaps for directional lights, to avoid under and oversampling. Disadvantage: Many render passes)
Trapezoidal, Perspective... (desperate trys to construct a adaptive projection matrix. All these algorithms suck if the near plane is covered in light direction by the farplane. This case can't be avoided if the user can rotate the cam.)
Variance shadowmapping, this allows to filter shadowmaps with blur, anisotropic and mipmapping filter. Has it's own artifacts, but is most times better than standard filtering. It can be combined with all projections.
Thanks for the info, is there anything I'm doing which is drastically wrong in my code?
Neutrinohunter
Neutrinohunter
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement