C++ Opengl es 2.0中带cubemap的阴影映射
我是OpenGL ES的新手,我正在尝试向当前场景添加一些阴影。我决定在立方体地图的帮助下这样做。我使用的是OpenGL es 2.0,因此几何体着色器或gl_FragDepth变量对我不可用。我在谷歌上搜索了一些,因此我对这个主题有了一些见解,阅读这个()证明是非常有用的。基本上我依赖这个链接文档 但是我的代码有点问题,因为在渲染的场景中,每个像素都在阴影下。我认为这个问题可以在我的着色器中找到,但我将所有相关代码粘贴到这里,以便清楚地看到所有内容 设置帧缓冲区并创建立方体映射:C++ Opengl es 2.0中带cubemap的阴影映射,c++,opengl-es-2.0,shadow-mapping,C++,Opengl Es 2.0,Shadow Mapping,我是OpenGL ES的新手,我正在尝试向当前场景添加一些阴影。我决定在立方体地图的帮助下这样做。我使用的是OpenGL es 2.0,因此几何体着色器或gl_FragDepth变量对我不可用。我在谷歌上搜索了一些,因此我对这个主题有了一些见解,阅读这个()证明是非常有用的。基本上我依赖这个链接文档 但是我的代码有点问题,因为在渲染的场景中,每个像素都在阴影下。我认为这个问题可以在我的着色器中找到,但我将所有相关代码粘贴到这里,以便清楚地看到所有内容 设置帧缓冲区并创建立方体映射: GLuint
GLuint FBO;
GLuint cubeTexture;
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
// Depth texture
glGenTextures(1, &cubeTexture);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTexture);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); // no GL_TEXTURE_WRAP_R
// right, left, top, bottom, front, back
for (int face = 0; face < 6; ++face) {
// create space for the textures, content need not to be specified (last parameter is 0)
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_DEPTH_COMPONENT16, 1024, 768, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
}
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepthf(1.0f);
glm::vec3 camPos = ... // position of the camera, it is in world space
glm::vec4 lightPos = ... // position of the light source, it is in world space
// 1. render into texture
float zNear = 0.1f;
float zFar = 100.0f;
// or should I use ortho instead of perspective?
glm::mat4 projMatrix = glm::perspective(90.0f, (float)esContext->width / esContext->height, zNear, zFar);
// The 6 cameras have to be placed to the light source and they need the proper view matrices
glm::mat4 cubeMapMatrices[6]; // contains six basic and defined rotation matrices for the six directions
cubeMapMatrices[0] = glm::make_mat4(rotPositiveX);
cubeMapMatrices[1] = glm::make_mat4(rotNegativeX);
cubeMapMatrices[2] = glm::make_mat4(rotPositiveY);
cubeMapMatrices[3] = glm::make_mat4(rotNegativeY);
cubeMapMatrices[4] = glm::make_mat4(rotPositiveZ);
cubeMapMatrices[5] = glm::make_mat4(rotNegativeZ);
glm::vec4 translation = lightPos;
glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTexture);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
for (int face = 0; face < 6; ++face) {
glClear(GL_DEPTH_BUFFER_BIT); // do I need this here?
cubeMapMatrices[face][3] = translation; // the translation part is the same for all
cubeMapMatrices[face] = projMatrix * cubeMapMatrices[face]; // now it's an mvp matrix
glUniformMatrix4fv(cubeProjectionMatrixID, 1, GL_FALSE, glm::value_ptr(cubeMapMatrices[face]));
// Attach depth cubemap texture to FBO's depth attachment point
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, cubeTexture, 0);
int err = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (err != GL_FRAMEBUFFER_COMPLETE) {
std::cout << "Framebuffer error, status: " << err << std::endl;
}
RenderScene(); // do the drawing
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// 2. render into screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
RenderScene(); // do the drawing
// swap the buffers
in vec3 vPosition;
uniform mat4 mModel;
uniform mat4 mCubeProjection;
uniform vec4 vLight;
out vec4 vFrag Position; // world space
out vec4 vLightPosition; // mvp transformed
void main()
{
vec4 position = vec4(vPosition, 1.0);
vFragPosition = mModel* position;
vLightPosition = vLight;
gl_Position = mCubeProjection * vFragPosition;
}
in vec4 vFragPosition; // world space
in vec4 vLightPosition; // world space
out float depthValue;
void main()
{
depthValue = distance(vFragPosition.xyz, vLightPosition.xyz); // need normalization?
}
uniform mat4 mModel;
uniform mat4 mView;
uniform mat4 mProjection;
uniform vec4 vLight; // it is in world space
out vec3 lw; // light position in world space
out vec3 pw; // pixel position in world space
void main()
{
vec4 position = vec4(vPosition, 1.0);
lw = vLight.xyz;
pw = (mModel* position).xyz;
gl_Position = mProjection* mView * mModel* position;
}
in vec3 lw;
in vec3 pw;
uniform samplerCube cubeMap;
out vec4 outputColor;
void main()
{
vec3 lookup = pw - lw;
float smValue = texture(cubeMap, lookup).r; // retrieves texels from a texture (d, d, d, 1.0)
float distance = length(lookup); // dist from the fragment to the light
float eps = 0.1;
float shadowVal = 1.0;
if (smValue + eps < distance) {
shadowVal = 0.1; // in shadow
}
// here comes the lighting stuff
// ...
outputColor = outputColor * shadowVal;
}
用于深度计算的片段着色器:
GLuint FBO;
GLuint cubeTexture;
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
// Depth texture
glGenTextures(1, &cubeTexture);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTexture);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); // no GL_TEXTURE_WRAP_R
// right, left, top, bottom, front, back
for (int face = 0; face < 6; ++face) {
// create space for the textures, content need not to be specified (last parameter is 0)
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_DEPTH_COMPONENT16, 1024, 768, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
}
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepthf(1.0f);
glm::vec3 camPos = ... // position of the camera, it is in world space
glm::vec4 lightPos = ... // position of the light source, it is in world space
// 1. render into texture
float zNear = 0.1f;
float zFar = 100.0f;
// or should I use ortho instead of perspective?
glm::mat4 projMatrix = glm::perspective(90.0f, (float)esContext->width / esContext->height, zNear, zFar);
// The 6 cameras have to be placed to the light source and they need the proper view matrices
glm::mat4 cubeMapMatrices[6]; // contains six basic and defined rotation matrices for the six directions
cubeMapMatrices[0] = glm::make_mat4(rotPositiveX);
cubeMapMatrices[1] = glm::make_mat4(rotNegativeX);
cubeMapMatrices[2] = glm::make_mat4(rotPositiveY);
cubeMapMatrices[3] = glm::make_mat4(rotNegativeY);
cubeMapMatrices[4] = glm::make_mat4(rotPositiveZ);
cubeMapMatrices[5] = glm::make_mat4(rotNegativeZ);
glm::vec4 translation = lightPos;
glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTexture);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
for (int face = 0; face < 6; ++face) {
glClear(GL_DEPTH_BUFFER_BIT); // do I need this here?
cubeMapMatrices[face][3] = translation; // the translation part is the same for all
cubeMapMatrices[face] = projMatrix * cubeMapMatrices[face]; // now it's an mvp matrix
glUniformMatrix4fv(cubeProjectionMatrixID, 1, GL_FALSE, glm::value_ptr(cubeMapMatrices[face]));
// Attach depth cubemap texture to FBO's depth attachment point
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, cubeTexture, 0);
int err = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (err != GL_FRAMEBUFFER_COMPLETE) {
std::cout << "Framebuffer error, status: " << err << std::endl;
}
RenderScene(); // do the drawing
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// 2. render into screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
RenderScene(); // do the drawing
// swap the buffers
in vec3 vPosition;
uniform mat4 mModel;
uniform mat4 mCubeProjection;
uniform vec4 vLight;
out vec4 vFrag Position; // world space
out vec4 vLightPosition; // mvp transformed
void main()
{
vec4 position = vec4(vPosition, 1.0);
vFragPosition = mModel* position;
vLightPosition = vLight;
gl_Position = mCubeProjection * vFragPosition;
}
in vec4 vFragPosition; // world space
in vec4 vLightPosition; // world space
out float depthValue;
void main()
{
depthValue = distance(vFragPosition.xyz, vLightPosition.xyz); // need normalization?
}
uniform mat4 mModel;
uniform mat4 mView;
uniform mat4 mProjection;
uniform vec4 vLight; // it is in world space
out vec3 lw; // light position in world space
out vec3 pw; // pixel position in world space
void main()
{
vec4 position = vec4(vPosition, 1.0);
lw = vLight.xyz;
pw = (mModel* position).xyz;
gl_Position = mProjection* mView * mModel* position;
}
in vec3 lw;
in vec3 pw;
uniform samplerCube cubeMap;
out vec4 outputColor;
void main()
{
vec3 lookup = pw - lw;
float smValue = texture(cubeMap, lookup).r; // retrieves texels from a texture (d, d, d, 1.0)
float distance = length(lookup); // dist from the fragment to the light
float eps = 0.1;
float shadowVal = 1.0;
if (smValue + eps < distance) {
shadowVal = 0.1; // in shadow
}
// here comes the lighting stuff
// ...
outputColor = outputColor * shadowVal;
}
渲染到屏幕的顶点着色器:
GLuint FBO;
GLuint cubeTexture;
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
// Depth texture
glGenTextures(1, &cubeTexture);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTexture);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); // no GL_TEXTURE_WRAP_R
// right, left, top, bottom, front, back
for (int face = 0; face < 6; ++face) {
// create space for the textures, content need not to be specified (last parameter is 0)
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_DEPTH_COMPONENT16, 1024, 768, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
}
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepthf(1.0f);
glm::vec3 camPos = ... // position of the camera, it is in world space
glm::vec4 lightPos = ... // position of the light source, it is in world space
// 1. render into texture
float zNear = 0.1f;
float zFar = 100.0f;
// or should I use ortho instead of perspective?
glm::mat4 projMatrix = glm::perspective(90.0f, (float)esContext->width / esContext->height, zNear, zFar);
// The 6 cameras have to be placed to the light source and they need the proper view matrices
glm::mat4 cubeMapMatrices[6]; // contains six basic and defined rotation matrices for the six directions
cubeMapMatrices[0] = glm::make_mat4(rotPositiveX);
cubeMapMatrices[1] = glm::make_mat4(rotNegativeX);
cubeMapMatrices[2] = glm::make_mat4(rotPositiveY);
cubeMapMatrices[3] = glm::make_mat4(rotNegativeY);
cubeMapMatrices[4] = glm::make_mat4(rotPositiveZ);
cubeMapMatrices[5] = glm::make_mat4(rotNegativeZ);
glm::vec4 translation = lightPos;
glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTexture);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
for (int face = 0; face < 6; ++face) {
glClear(GL_DEPTH_BUFFER_BIT); // do I need this here?
cubeMapMatrices[face][3] = translation; // the translation part is the same for all
cubeMapMatrices[face] = projMatrix * cubeMapMatrices[face]; // now it's an mvp matrix
glUniformMatrix4fv(cubeProjectionMatrixID, 1, GL_FALSE, glm::value_ptr(cubeMapMatrices[face]));
// Attach depth cubemap texture to FBO's depth attachment point
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, cubeTexture, 0);
int err = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (err != GL_FRAMEBUFFER_COMPLETE) {
std::cout << "Framebuffer error, status: " << err << std::endl;
}
RenderScene(); // do the drawing
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// 2. render into screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
RenderScene(); // do the drawing
// swap the buffers
in vec3 vPosition;
uniform mat4 mModel;
uniform mat4 mCubeProjection;
uniform vec4 vLight;
out vec4 vFrag Position; // world space
out vec4 vLightPosition; // mvp transformed
void main()
{
vec4 position = vec4(vPosition, 1.0);
vFragPosition = mModel* position;
vLightPosition = vLight;
gl_Position = mCubeProjection * vFragPosition;
}
in vec4 vFragPosition; // world space
in vec4 vLightPosition; // world space
out float depthValue;
void main()
{
depthValue = distance(vFragPosition.xyz, vLightPosition.xyz); // need normalization?
}
uniform mat4 mModel;
uniform mat4 mView;
uniform mat4 mProjection;
uniform vec4 vLight; // it is in world space
out vec3 lw; // light position in world space
out vec3 pw; // pixel position in world space
void main()
{
vec4 position = vec4(vPosition, 1.0);
lw = vLight.xyz;
pw = (mModel* position).xyz;
gl_Position = mProjection* mView * mModel* position;
}
in vec3 lw;
in vec3 pw;
uniform samplerCube cubeMap;
out vec4 outputColor;
void main()
{
vec3 lookup = pw - lw;
float smValue = texture(cubeMap, lookup).r; // retrieves texels from a texture (d, d, d, 1.0)
float distance = length(lookup); // dist from the fragment to the light
float eps = 0.1;
float shadowVal = 1.0;
if (smValue + eps < distance) {
shadowVal = 0.1; // in shadow
}
// here comes the lighting stuff
// ...
outputColor = outputColor * shadowVal;
}
用于渲染到屏幕的片段着色器:
GLuint FBO;
GLuint cubeTexture;
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
// Depth texture
glGenTextures(1, &cubeTexture);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTexture);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); // no GL_TEXTURE_WRAP_R
// right, left, top, bottom, front, back
for (int face = 0; face < 6; ++face) {
// create space for the textures, content need not to be specified (last parameter is 0)
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_DEPTH_COMPONENT16, 1024, 768, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
}
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepthf(1.0f);
glm::vec3 camPos = ... // position of the camera, it is in world space
glm::vec4 lightPos = ... // position of the light source, it is in world space
// 1. render into texture
float zNear = 0.1f;
float zFar = 100.0f;
// or should I use ortho instead of perspective?
glm::mat4 projMatrix = glm::perspective(90.0f, (float)esContext->width / esContext->height, zNear, zFar);
// The 6 cameras have to be placed to the light source and they need the proper view matrices
glm::mat4 cubeMapMatrices[6]; // contains six basic and defined rotation matrices for the six directions
cubeMapMatrices[0] = glm::make_mat4(rotPositiveX);
cubeMapMatrices[1] = glm::make_mat4(rotNegativeX);
cubeMapMatrices[2] = glm::make_mat4(rotPositiveY);
cubeMapMatrices[3] = glm::make_mat4(rotNegativeY);
cubeMapMatrices[4] = glm::make_mat4(rotPositiveZ);
cubeMapMatrices[5] = glm::make_mat4(rotNegativeZ);
glm::vec4 translation = lightPos;
glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTexture);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
for (int face = 0; face < 6; ++face) {
glClear(GL_DEPTH_BUFFER_BIT); // do I need this here?
cubeMapMatrices[face][3] = translation; // the translation part is the same for all
cubeMapMatrices[face] = projMatrix * cubeMapMatrices[face]; // now it's an mvp matrix
glUniformMatrix4fv(cubeProjectionMatrixID, 1, GL_FALSE, glm::value_ptr(cubeMapMatrices[face]));
// Attach depth cubemap texture to FBO's depth attachment point
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, cubeTexture, 0);
int err = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (err != GL_FRAMEBUFFER_COMPLETE) {
std::cout << "Framebuffer error, status: " << err << std::endl;
}
RenderScene(); // do the drawing
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// 2. render into screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
RenderScene(); // do the drawing
// swap the buffers
in vec3 vPosition;
uniform mat4 mModel;
uniform mat4 mCubeProjection;
uniform vec4 vLight;
out vec4 vFrag Position; // world space
out vec4 vLightPosition; // mvp transformed
void main()
{
vec4 position = vec4(vPosition, 1.0);
vFragPosition = mModel* position;
vLightPosition = vLight;
gl_Position = mCubeProjection * vFragPosition;
}
in vec4 vFragPosition; // world space
in vec4 vLightPosition; // world space
out float depthValue;
void main()
{
depthValue = distance(vFragPosition.xyz, vLightPosition.xyz); // need normalization?
}
uniform mat4 mModel;
uniform mat4 mView;
uniform mat4 mProjection;
uniform vec4 vLight; // it is in world space
out vec3 lw; // light position in world space
out vec3 pw; // pixel position in world space
void main()
{
vec4 position = vec4(vPosition, 1.0);
lw = vLight.xyz;
pw = (mModel* position).xyz;
gl_Position = mProjection* mView * mModel* position;
}
in vec3 lw;
in vec3 pw;
uniform samplerCube cubeMap;
out vec4 outputColor;
void main()
{
vec3 lookup = pw - lw;
float smValue = texture(cubeMap, lookup).r; // retrieves texels from a texture (d, d, d, 1.0)
float distance = length(lookup); // dist from the fragment to the light
float eps = 0.1;
float shadowVal = 1.0;
if (smValue + eps < distance) {
shadowVal = 0.1; // in shadow
}
// here comes the lighting stuff
// ...
outputColor = outputColor * shadowVal;
}
vec3 lw中的;
在vec3-pw;
均匀立方体映射;
输出vec4输出颜色;
void main()
{
vec3查找=pw-lw;
float smValue=texture(cubeMap,lookup).r;//从纹理(d,d,d,1.0)检索texel
浮动距离=长度(查找);//从碎片到灯光的距离
浮动每股收益=0.1;
float shadowVal=1.0;
如果(smValue+eps<距离){
shadowVal=0.1;//在阴影中
}
//灯光的东西来了
// ...
outputColor=outputColor*shadowVal;
}
同样,问题是每个像素都在阴影下。从代码中,我排除了一些到着色器的统一过程,但它们是可以的。你能给我一个建议我应该在代码中修改什么?我的着色器(尤其是第一遍)正确吗?我是否正确设置了立方体映射的变换?多谢各位
附言:这是我在这里的第一个问题,我希望它足够清晰,并满足正确发布问题的要求。基本上,你的问题很简单:你在立方体地图上使用深度附件,深度缓冲区存储透视深度 着色器希望在阴影贴图中看到的是从灯光到最近片段的非透视距离。实际上,在创建阴影贴图时,您在片段着色器中计算了该值,但将其输出到颜色缓冲区(没有附加任何内容)而不是深度缓冲区
此问题至少有三种可能的解决方案(按性能顺序,最差第一):
gl\u FragDepth
而不是depthValue
(实际上是一个颜色缓冲区目标)GL\u COLOR\u ATTACHMENT0
,并使用颜色可渲染格式,而不是GL\u DEPTH\u组件
depthValue
,仅写入透视深度gl\u FragDepth
,您将在许多硬件上禁用硬件深度缓冲区优化,这将使生成阴影贴图的过程性能更差
选项2更好,因为它受益于硬件Z缓冲区优化,但仍然需要大量内存带宽,因为您有效地存储了两个不同的深度值(一个在颜色附件中,一个在深度附件中)
选项3虽然最复杂,但通常表现最好。这是因为只需存储硬件深度,就可以将计算阴影贴图所需的内存带宽减半
如果你有兴趣了解更多关于选项3的信息,我建议你看看。您将实际计算用于比较的透视深度,而不是比较距离。在创建阴影贴图时,在应用阴影时,可以在片段着色器中进行一些额外的计算,以获得更少的内存带宽
现在,为了以最少的工作量解决眼前的问题,您应该采用选项2。将选项3保留在表上,以便将来进行优化;最好在至少有东西能工作之前不要优化东西。谢谢你的回答。选项3不是选项,因为在es 2.0中无法访问gl_FragDepth。因此,正如您所建议的,我选择了选项2。我将相关行更改为glTexImage2D(GL_纹理_立方体_贴图_正X+面,0,GL_RGB,1024,768,0,GL_RGB,GL_无符号_短5_6_5,0);和glFramebufferTexture2D(GL_帧缓冲区,GL_颜色,GL_附件0,GL_纹理,GL_立方体,glu贴图,glu正片,立方体纹理,0);,但当我在第二个片段着色器中调用“纹理”函数时,仍然只有零。对不起,我的格式很差。我也有类似的情况,我发现一些奇怪的事情。如果我只写gl_FragDepth,而不在我的影子fs中输出任何东西,那么cubemap似乎什么也得不到。如果我写的长度,我可以看到它被正确地写在红色(我还附加了一个彩色附件)。为什么会这样?