首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >具有多个阴影的阴影贴图

具有多个阴影的阴影贴图
EN

Stack Overflow用户
提问于 2013-05-06 01:36:36
回答 1查看 779关注 0票数 3

我已经使用ARB扩展实现了阴影贴图,在本教程http://www.paulsprojects.net/tutorials/smt/smt.html之后,我修改了代码以添加另一个光源。我已经创建并初始化了另外两个矩阵(lightViewMatrix2和lightProjectionMatrix2)和另一个shadowMap纹理。在本教程的第3步中,在绑定第一个阴影贴图纹理之后,我绑定了第二个阴影贴图纹理。我得到的结果是,我只看到了两个不同光源产生的两个阴影之间的交点。我已经初始化了init函数中的所有矩阵,如本教程所示,这是我的显示函数。

代码语言:javascript
运行
复制
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();}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-05-07 21:16:03

您在这里所做的是,首先为第一个灯光生成阴影贴图,然后为第二个灯光生成阴影贴图,同时与第一个阴影贴图进行比较。结果,你最终得到了一个阴影,它是两者的某种组合。您将需要生成第二个阴影的方式与生成第一个阴影的方式相同(每个灯光的阴影生成应该独立于所有其他灯光),最后,因为您将需要使用一些多纹理来以某种方式为每个z纹理独立执行相同的比较检查。

考虑使用基于着色器的方法,因为所有这些固定函数调用都已过时,并且与着色器相比没有优势。我读过的关于多个灯光的阴影贴图的最好的文章是Daniel Rákos的“大量具有分层渲染的阴影投射灯光”。它提供了一种非常有效的方法来实现这一点。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16387210

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档