我想知道如何处理延迟渲染的点光源阴影?
点阴影不为我显示。我认为这与以下行有关:float shadow = calculate_shadows(FragPos);至于定向阴影,我将fragpos与lightSpaceMatrix(lightView * lightProj)乘以一个就可以了,但是对于点阴影,我没有使用lightSpaceMatrix。
轻片段着色器
#version 420 core
out vec4 FragColor;
in vec2 _texcoord;
uniform vec3 camera_pos;
uniform sampler2D gPosition;
uniform sampler2D gNormal;
uniform sampler2D gAlbedo;
uniform sampler2D gSpecular;
uniform sampler2D gMetalness;
uniform samplerCube gPointShadowmap;
uniform mat4 viewMatrix;
uniform vec3 lightPos;
vec3 FragPos;
vec3 Normal;
float calculate_shadows(vec3 light_space_pos)
{
// perform perspective divide
vec3 fragToLight = light_space_pos - vec3(0.0f, 0.0f, 0.0f);
// get closest depth value from light's perspective (using [0,1] range fragPosLight as coords)
float closestDepth = texture(gPointShadowmap, fragToLight).r;
// it is currently in linear range between [0,1], let's re-transform it back to original depth value
closestDepth *= 25.0f;
// now get current linear depth as the length between the fragment and light position
float currentDepth = length(fragToLight);
// test for shadows
float bias = 0.05; // we use a much larger bias since depth is now in [near_plane, far_plane] range
float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
//FragColor = vec4(vec3(closestDepth / 25.0f), 1.0);
return shadow;
}
void main(void)
{
FragPos = texture(gPosition, _texcoord).rgb;
Normal = texture(gNormal, _texcoord).rgb;
vec3 Diffuse = texture(gAlbedo, _texcoord).rgb;
float Emissive = texture(gAlbedo, _texcoord).a;
vec3 Specular = texture(gAlbedo, _texcoord).rgb;
vec3 Metalness = texture(gMetalness, _texcoord).rgb; // Reflection pass
float AmbientOcclusion = texture(gSsao, _texcoord).r;
vec3 lightColor = vec3(0.3);
// ambient
vec3 ambient = 0.3 * Diffuse;
// diffuse
vec3 lightDir = normalize(vec3(0.0, 0.0, 0.0) - FragPos);
float diff = max(dot(lightDir, Normal), 0.0);
vec3 diffuse = diff * lightColor;
// specular
vec3 viewDir = normalize(camera_pos - FragPos);
vec3 reflectDir = reflect(-lightDir, Normal);
float spec = 0.0;
vec3 halfwayDir = normalize(lightDir + viewDir);
spec = pow(max(dot(Normal, halfwayDir), 0.0), 64.0);
vec3 specular = spec * lightColor;
// calculate shadow
float shadow = calculate_shadows(FragPos);
vec3 lighting = (ambient + (1.0 - shadow) * (diffuse + specular));
FragColor = vec4(lighting, 1.0);
}
点阴影顶点着色器
#version 330 core
layout(location = 0) in vec3 position;
uniform mat4 model;
void main(void)
{
gl_Position = model * vec4(position, 1.0);
}
pointshadows片段着色器
#version 330 core
in vec4 FragPos;
void main(void)
{
float lightDistance = length(FragPos.xyz - vec3(0.0, 3.0, 0.0));
// map to [0;1] range by dividing by far_plane
lightDistance = lightDistance / 25.0;
// write this as modified depth
gl_FragDepth = lightDistance;
}
点阴影几何着色器
#version 330 core
layout (triangles) in;
layout (triangle_strip, max_vertices = 18) out;
uniform mat4 shadowMatrices[6];
out vec4 FragPos;
void main(void)
{
for(int face = 0; face < 6; ++face)
{
gl_Layer = face; // built-in variable that specifies to which face we render.
for(int i = 0; i < 3; ++i) // for each triangle's vertices
{
FragPos = gl_in[i].gl_Position;
gl_Position = shadowMatrices[face] * FragPos;
EmitVertex();
}
EndPrimitive();
}
}
Temp PointShadow类
#ifndef __POINTSHADOWPASS
#define __POINTSHADOWPASS
#include "Content.h"
class PointShadowPass
{
private:
static unsigned int _shadow_fbo;
public:
static unsigned int _shadow_texture;
static glm::vec3 lightPos;
static std::vector<glm::mat4> shadowTransforms;
PointShadowPass() {}
~PointShadowPass() {}
inline static void Initialise()
{
lightPos = glm::vec3(0.0f, 0.0f, 0.0f);
glGenFramebuffers(1, &_shadow_fbo);
glGenTextures(1, &_shadow_texture);
glBindTexture(GL_TEXTURE_2D, _shadow_texture);
for (unsigned int i = 0; i < 6; i++)
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
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);
glBindFramebuffer(GL_FRAMEBUFFER, _shadow_fbo);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, _shadow_texture, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
inline static void Render(unsigned int pointshadow_program, Camera* camera, std::vector<Actor*> _actors)
{
glDisable(GL_BLEND); // Disable blending for opique materials
glEnable(GL_DEPTH_TEST); // Enable depth test
glm::mat4 model;
glm::mat4 shadowProj = glm::perspective(glm::radians(90.0f), (float)1024 / (float)1024, 1.0f, 25.0f);
shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)));
shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)));
shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
glViewport(0, 0, 1024, 1024);
glBindFramebuffer(GL_FRAMEBUFFER, _shadow_fbo);
glClear(GL_DEPTH_BUFFER_BIT);
glUseProgram(pointshadow_program);
for (unsigned int i = 0; i < 6; ++i)
glUniformMatrix4fv(glGetUniformLocation(pointshadow_program, ("shadowMatrices[" + std::to_string(i) + "]").c_str()), 1, GL_FALSE, glm::value_ptr(shadowTransforms[i]));
for (unsigned int i = 0; i < _actors.size(); i++)
{
model = _actors[i]->GetModelMatrix() * camera->GetViewMatrix();
glUniformMatrix4fv(glGetUniformLocation(pointshadow_program, "model"), 1, GL_FALSE, glm::value_ptr(model)); // set the model matrix uniform
_actors[i]->Render();
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
};
std::vector<glm::mat4> PointShadowPass::shadowTransforms;
unsigned int PointShadowPass::_shadow_fbo;
unsigned int PointShadowPass::_shadow_texture;
glm::vec3 PointShadowPass::lightPos;
#endif
我设法显示一些东西(阴影随着相机旋转而移动)
答案 0 :(得分:0)
在阅读您的评论时,您似乎对延迟渲染中可以包含的信息有一些误解?
您说所有坐标都必须在屏幕空间中,这是不正确的。对于延迟渲染,您有一个G缓冲区,可以在其中放入所需的任何信息。要获取世界位置信息,您有两种选择,要么有一个世界位置缓冲区,所以您知道每个片段在世界上的什么位置。或者,您也可以从深度缓冲区和相机投影矩阵中重新计算这些信息。
如果您有在正向渲染中工作的点阴影计算,则可以在延迟渲染中执行相同的操作,在进行所有光计算的着色器中,您需要阴影立方体贴图,光位置,并且您像以前那样进行计算
编辑:
查看calculate_shadows(vec3 light_space_pos)
的代码,在延迟渲染中,您不会将其发送到光源空间中,而会将其发送到世界空间中。因此该函数应为:
calculate_shadows(vec3 frag_world_pos)
您有第一行vec3 fragToLight = light_space_pos - vec3(0.0f, 0.0f, 0.0f);
应为vec3 fragToLight = frag_world_pos- lightPos
。
或者在使用该功能之前进行此计算。无论哪种方式,都需要点光源的位置来计算片段和光源之间的方向和距离。