Карта теней OpenGL не визуализируется над теневыми объектами

В моей реализации карты теней для направленных источников света у меня есть коллекция элементов, которые я повторяю для отображения их глубины в буфере глубины, а затем повторяю их снова для нормального отображения с помощью сгенерированной карты теней, каждый элемент имеет bool свойство называется castShadow который я проверяю, если true, добавьте его в буфер глубины, проблема в том, что если элемент отбрасывает тень и визуализируется в буфер глубины, он вообще не может получать тени, как только я установил в false значение, тогда он не будет отображаться при глубине начала получать тени без проблем.
поэтому в функции рендеринга сначала я визуализирую буфер глубины следующим образом:

Когда объект отбрасывает тень, он не получает тени
Когда объект отбрасывает тень, он не't receive shadows

Когда объект не отбрасывает тень, он получает тени
Когда объект не't cast shadow it receives shadows

void Engine::renderDepthMaps() {
if (sun != nullptr) {
if (sun->castShadow) {
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glClear(GL_DEPTH_BUFFER_BIT);
glm::vec3 pos = -500.0f * sun->direction;
glm::mat4 lightSpaceProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, -10.0f, 1000.0f);
glm::mat4 lightSpaceView = glm::lookAt(pos, player->getPosition(), glm::vec3(0, 1, 0));
lightSpaceMatrix = lightSpaceProjection * lightSpaceView;
Shader& shader = shaders.getShader(DEPTH);
shader.use();
shaders.setDepthLightSpaceUniform(shader, lightSpaceMatrix);
for (item_it it = engineItems.begin(); it != engineItems.end(); ++it) {
if (it->get()->castShadow)
it->get()->renderDepth(deltaFirst);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
}
}

и функция рендеринга:

void Engine::renderMeshes() {
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Shader& basicShader = shaders.getShader(BASIC);
basicShader.use();
sun->setUniforms(basicShader.getProgramID(), "directLights");
shaders.setLightSpaceUniform(basicShader, sun, lightSpaceMatrix, depthMap);
shaders.setShaderViewUniforms(basicShader, camera);
terrain->render(basicShader, deltaFirst);
for (item_it it = basicItems.begin(); it != basicItems.end(); ++it) {
if (it->get()->type != "terrain")
it->get()->render(basicShader, deltaFirst);
}
}

и шейдеры:
вершина:

    #version 300 es
precision highp float;

layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 texCoord;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform mat4 lightSpaceMatrix;
uniform mat3 normalMatrix;

out vec4 FragPosLightSpace;
out vec2 TexCoords;
out vec3 Normal;
out vec3 viewPos;
out vec3 fragPos;

void main(){
TexCoords = texCoord;
Normal=normalMatrix*normal;
fragPos = vec3(model * vec4(position,1.0f));
FragPosLightSpace =lightSpaceMatrix * model * vec4(position,1.0f);
gl_Position = projection * view * model * vec4(position,1.0f);
}

фрагмент:

    #version 300 es
precision highp float;

out vec4 glFragColor;

vec2 poissonDisk[4] = vec2[](
vec2( -0.94201624, -0.39906216 ),
vec2( 0.94558609, -0.76890725 ),
vec2( -0.094184101, -0.92938870 ),
vec2( 0.34495938, 0.29387760 )
);

struct DirectLight {
vec3 direction;
vec3 color;
float intensity;
};

in vec3 Normal;
in vec2 TexCoords;
in vec3 fragPos;
in vec4 FragPosLightSpace;

uniform int has_texture;
uniform vec3 matDiffuse;
uniform sampler2D  shadowMap;
uniform sampler2D  mat_diffuse;
uniform sampler2D mat_specular;
uniform vec3 matSpecular;
uniform float shininess;
uniform DirectLight sun;
uniform int castShadow;
uniform vec3 viewPos;

void main(){
vec3 tex=vec3(1),spe=vec3(1);
if(has_texture==1){
tex=vec3(texture(mat_diffuse, TexCoords));
spe=vec3(texture(mat_specular,TexCoords));
}
vec3 diffColor   = matDiffuse  * tex;
vec3 specColor   = matSpecular * spe;
vec3 ambient     = vec3(0.4,0.4,0.4)*diffColor;
vec3 lightDir    = normalize(-sun.direction);

float diff       = max(dot(Normal,lightDir), 0.0);
vec3  diffuse    = sun.color * diff * diffColor;

vec3  viewDir    = normalize(viewPos - fragPos);
vec3  reflectDir = reflect(-lightDir, Normal);
float spec       = pow(max(dot(viewDir, reflectDir), 0.0), shininess);
vec3  specular   = spec * specColor * sun.color;

vec3  color      = ambient + diffuse + specular;
float gamma = 2.2;
color.rgb = pow(color.rgb, vec3(1.0/gamma));
if(castShadow==1){
vec3 projCoords = FragPosLightSpace.xyz / FragPosLightSpace.w;
projCoords = projCoords * 0.5 + 0.5;
float shadow = 1.0;
for (int i=0;i<4;i++){
shadow -= 0.2*(1.0-texture( shadowMap, projCoords.xy + poissonDisk[i]/700.0).r);
}
if(projCoords.z > 1.0)
shadow = 0.0;
color *=shadow;
}
glFragColor=vec4(color,1.0f);
}

Другая проблема: светлая космическая перспективная матрица glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, -10.0f, 1000.0f) и размер карты теней равен 1024, когда объект находится за пределами этой матрицы, он создает очень длинную тень и имеет неправильное направление, как показано на следующем рисунке:
введите описание изображения здесь

1

Решение

Задача ещё не решена.

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

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

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