Отображение теней с несколькими тенями

Я реализовал отображение теней с использованием расширений ARB после этого урока
http://www.paulsprojects.net/tutorials/smt/smt.html
Я изменил код, чтобы добавить еще один источник света. Я создал и инициализировал еще 2 матрицы (lightViewMatrix2 и lightProjectionMatrix2) и другую текстуру shadowMap.
На третьем шаге урока после связывания первой текстуры карты теней я связал вторую.
В результате я вижу только пересечения между двумя тенями, создаваемыми двумя разными источниками света.
Я инициализировал все матрицы в функции init, как показано в руководстве, это моя функция отображения.

void Display(void){
//First pass - from light's point of view
//Calculate & save matrices LIGHT 1
glPushMatrix();
glLoadIdentity();
gluLookAt(  lightPosition[0], lightPosition[1], lightPosition[2],
0.0f, 0.0f , 0.0f,
0.0f, 1.0f, 0.0f);
glGetFloatv(GL_MODELVIEW_MATRIX, lightViewMatrix);
glPopMatrix();

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadMatrixf(lightProjectionMatrix);

glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(lightViewMatrix);

//Use viewport the same size as the shadow map
glViewport(0, 0, shadowMapSize, shadowMapSize);

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

//Draw the scene
DrawScene();

//Read the depth buffer into the shadow map texture
glBindTexture(GL_TEXTURE_2D, shadowMapTexture[0]);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, shadowMapSize, shadowMapSize);//First pass - from light's point of view
//Calculate & save matrices LIGHT 2
glPushMatrix();
glLoadIdentity();
gluLookAt(  lightPosition2[0], lightPosition2[1], lightPosition2[2],
0.0f, 0.0f , 0.0f,
0.0f, 1.0f, 0.0f);
glGetFloatv(GL_MODELVIEW_MATRIX, lightViewMatrix2);
glPopMatrix();

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadMatrixf(lightProjectionMatrix2);

glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(lightViewMatrix2);

//Use viewport the same size as the shadow map
glViewport(0, 0, shadowMapSize, shadowMapSize);

//Draw the scene
DrawScene();

//Read the depth buffer into the shadow map texture
glBindTexture(GL_TEXTURE_2D, shadowMapTexture[1]);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, shadowMapSize, shadowMapSize);

//restore states
glCullFace(GL_BACK);
glShadeModel(GL_SMOOTH);
glColorMask(1, 1, 1, 1);//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, windowWidth, windowHeight);

float white2[3]={0.2f,0.2f,0.2f};

//light to represent shadowed areas
glLightfv(GL_LIGHT1, GL_POSITION, VECTOR4D(lightPosition));
glLightfv(GL_LIGHT1, GL_AMBIENT, white2);
glLightfv(GL_LIGHT1, GL_DIFFUSE, white2);
glLightfv(GL_LIGHT1, GL_SPECULAR, black1);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHTING);

DrawScene();//3rd pass
//Draw with bright light LIGHT1
glLightfv(GL_LIGHT1, GL_DIFFUSE, white1);
glLightfv(GL_LIGHT1, GL_SPECULAR, white1);

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

MATRIX4X4 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[0]);
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);

DrawScene();

//3rd pass
//Draw with bright light LIGHT2

MATRIX4X4 textureMatrix2=biasMatrix*lightProjectionMatrix2*lightViewMatrix2;

//Set up texture coordinate generation.
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_S, GL_EYE_PLANE, textureMatrix2.GetRow(0));
glEnable(GL_TEXTURE_GEN_S);

glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_T, GL_EYE_PLANE, textureMatrix2.GetRow(1));
glEnable(GL_TEXTURE_GEN_T);

glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_R, GL_EYE_PLANE, textureMatrix2.GetRow(2));
glEnable(GL_TEXTURE_GEN_R);

glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_Q, GL_EYE_PLANE, textureMatrix2.GetRow(3));
glEnable(GL_TEXTURE_GEN_Q);

//Bind & enable shadow map texture
glBindTexture(GL_TEXTURE_2D, shadowMapTexture[1]);
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);

DrawScene();

//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);//Set matrices for ortho
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(-1.0f, 1.0f, -1.0f, 1.0f);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

//reset matrices
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();

glFinish();
glutSwapBuffers();}

3

Решение

Что вы делаете здесь, так это то, что вы сначала генерируете карту теней для первого источника света, затем вы генерируете карту теней для второго источника света, одновременно проводя сравнение с первой картой теней. В результате вы получите тень, которая является некой комбинацией двух.
Вам нужно будет сгенерировать вторую тень так же, как вы генерируете свою первую (генерация тени для каждого источника света должна быть независимой от каждого другого источника света), а затем, наконец, поскольку вам нужно будет использовать несколько текстур, чтобы как-то сделать такую ​​же проверку сравнения для каждая z-текстура самостоятельно.

Подумайте об использовании подхода, основанного на шейдерах, поскольку все эти вызовы с фиксированными функциями устарели и не имеют преимуществ перед шейдерами. Лучшая статья, которую я читал о теневом картографировании со многими источниками света, — «Массивное количество освещающих теней источников со слоистой визуализацией» Даниэля Ракоса. Это очень эффективный способ сделать это.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]