Странное поведение отображения тенейC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Странное поведение отображения теней

Сообщение Anonymous »

Я пытаюсь реализовать отображение теней с помощью OpenGL и GLSL 120:
ShadowPass.vert

Код: Выделить всё

#version 120
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
ShadowPass.frag

Код: Выделить всё

#version 120

uniform float near_plane;
uniform float far_plane;

void main()
{
float z = gl_FragCoord.z;
float n = near_plane;
float f = far_plane;
float c = (2.0 * n) / (f + n - z * (f - n));
gl_FragDepth = c;
}
RenderPass.vert

Код: Выделить всё

#version 120

varying vec3 position;
varying vec3 normal;
varying vec3 FragPos;
varying vec4 FragPosLightSpace;
uniform mat4 lightSpaceMatrix;

void main()
{
vec4 eyeCoordPos = gl_ModelViewMatrix * gl_Vertex;
position = eyeCoordPos.xyz / eyeCoordPos.w;
normal = normalize(gl_NormalMatrix * gl_Normal);
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_FrontColor = gl_Color;

FragPos = gl_Vertex.xyz;
FragPosLightSpace = lightSpaceMatrix * gl_Vertex;

gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
RenderPass.frag

Код: Выделить всё

#version 120

#define USE_INNER_AND_OUTER_CONES

#if defined(USE_INNER_AND_OUTER_CONES)
uniform float cosOuterCone;
uniform float cosInnerCone;
#endif

varying vec3 position;
varying vec3 normal;
uniform bool computeShadows;
uniform sampler2D colorMap;
uniform sampler2D shadowMap;

uniform vec3 lightPos;
varying vec3 FragPos;
varying vec4 FragPosLightSpace;

vec4 ShadowCalculation()
{
vec3 projCoords = FragPosLightSpace.xyz / FragPosLightSpace.w;
projCoords = projCoords * 0.5 + 0.5;  // Bias Matrix...
float closestDepth = texture2D(shadowMap, projCoords.xy).r;
float z = projCoords.z;
float n = 1.0;
float f = 1000.0;
float currentDepth = (2.0 * n) / (f + n - z * (f - n));
vec3 shadow = vec3(1.0, 1.0, 1.0);
float bias = 0.0005;
if(closestDepth + bias < currentDepth)
{
shadow = vec3(0.5, 0.5, 0.5); // Shadow color
}

return vec4(shadow, 1.0);
}

void main()
{
vec3 l = gl_LightSource[0].position.xyz - position;
float d = length(l);
float atten = 1.0 / (gl_LightSource[0].constantAttenuation +
gl_LightSource[0].linearAttenuation * d +
gl_LightSource[0].quadraticAttenuation * d * d);

l = normalize(l);

float spotDot = dot(-l, normalize(gl_LightSource[0].spotDirection));

#if defined(USE_INNER_AND_OUTER_CONES)
float spotEffect = smoothstep(cosOuterCone, cosInnerCone, spotDot);
#else
float spotEffect = (spotDot < gl_LightSource[0].spotCosCutoff)
? 0.0 : pow(spotDot, gl_LightSource[0].spotExponent);
#endif

atten *= spotEffect;

vec3 n = normalize(normal);
vec3 v = normalize(-position);
vec3 h = normalize(l + v);

float nDotL = max(0.0, dot(n, l));
float nDotH = max(0.0, dot(n, h));
float power = (nDotL == 0.0) ? 0.0 : pow(nDotH, gl_FrontMaterial.shininess);

vec4 ambient = gl_FrontLightProduct[0].ambient * atten;
vec4 diffuse = gl_FrontLightProduct[0].diffuse * nDotL * atten;
vec4 specular = gl_FrontLightProduct[0].specular * power * atten;
vec4 lightColor = gl_FrontLightModelProduct.sceneColor + ambient + diffuse + specular;

vec4 finalColor = vec4(0);

if (computeShadows)
{
vec4 shadow = ShadowCalculation();
finalColor = shadow * texture2D(colorMap, gl_TexCoord[0].st) * lightColor;
}
else
{
finalColor = lightColor * texture2D(colorMap, gl_TexCoord[0].st);
}

gl_FragColor = finalColor;
}
Сцена рендеринга приложения

Код: Выделить всё

glBindFramebuffer(GL_FRAMEBUFFER, shadowMapFBO);

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_DEPTH_BUFFER_BIT);

pShaderMgr->bind(0);

glUniform1f(glGetUniformLocation(pShaderMgr->id(0), "near_plane"), near_plane);
glUniform1f(glGetUniformLocation(pShaderMgr->id(0), "far_plane"), far_plane);

glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective(45.0f, static_cast(SHADOW_WIDTH) / static_cast(SHADOW_HEIGHT), near_plane, far_plane);
//glOrtho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane);
// OR
lightProjection = glm::perspective(glm::radians(45.0f), static_cast(SHADOW_WIDTH) / static_cast(SHADOW_HEIGHT), near_plane, far_plane);
//lightProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane);
glLoadMatrixf((float*)&lightProjection);
//glGetFloatv(GL_PROJECTION_MATRIX, (float*)&lightProjection);

lightView = glm::lookAt(glm::vec3(LightPosition[0], LightPosition[1], LightPosition[2]),
glm::vec3(LightDirection[0], LightDirection[1], LightDirection[2]),
glm::vec3(0.0, 1.0, 0.0));

lightSpaceMatrix = /*biasMatrix*/ lightProjection * lightView;

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLoadMatrixf((float*)&lightView);

glPushMatrix();
glTranslatef(0.0f, 1.0f, 0.0f);
DrawCubeVBO();
glPopMatrix();

glPushMatrix();
glTranslatef(-1.0f, 4.0f, 1.0f);
DrawCubeVBO();
glPopMatrix();

glBindFramebuffer(GL_FRAMEBUFFER, 0);

pShaderMgr->unbind();

///////////////////////////////////  COLOR BUFFER   /////////////////////////////////////////////////////////

glViewport(0, 0, WIDTH, HEIGHT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Limpa a tela e o Depth Buffer
glLoadIdentity();                                   // Inicializa a Modelview Matrix Atual

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective(45.0f, static_cast(WIDTH) / static_cast(HEIGHT), near_plane, far_plane);
// OR
glm::mat4 camProjection = glm::perspective(glm::radians(45.0f), static_cast(WIDTH) / static_cast(HEIGHT), near_plane, far_plane);
glLoadMatrixf((float*)&camProjection);

pCamera->setView();

// Desenha os eixos do sistema cartesiano
DrawAxis();

// Modo FILL ou WIREFRAME (pressione barra de espaço)
if (bIsWireframe)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
else
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                               DESENHA OS OBJETOS DA CENA (INÍCIO)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

pShaderMgr->bind(1);
glUniform1i(glGetUniformLocation(pShaderMgr->id(1), "colorMap"), 0);
glUniform1i(glGetUniformLocation(pShaderMgr->id(1), "shadowMap"), 1);
glUniform1i(glGetUniformLocation(pShaderMgr->id(1), "computeShadows"), true);
glUniform1f(glGetUniformLocation(pShaderMgr->id(1), "cosInnerCone"), g_cosInnerCone);
glUniform1f(glGetUniformLocation(pShaderMgr->id(1), "cosOuterCone"), g_cosOuterCone);
glUniform3f(glGetUniformLocation(pShaderMgr->id(1), "lightPos"), LightPosition[0], LightPosition[1], LightPosition[2]);
glUniformMatrix4fv(glGetUniformLocation(pShaderMgr->id(1), "lightSpaceMatrix"), 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix));

// Setup lighting and shaders.
glPushAttrib(GL_LIGHTING_BIT);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, SPOT_OUTER_CONE);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 2.0f);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, LightDirection);
glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);

glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
pTextures->ApplyTexture(0);

glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, shadowMap);

// Draw Cubes
glPushMatrix();
glTranslatef(0.0f, 1.0f, 0.0f);
DrawCubeVBO();
glPopMatrix();

glPushMatrix();
glTranslatef(-1.0f, 4.0f, 1.0f);
DrawCubeVBO();
glPopMatrix();

// Draw Ground
glActiveTexture(GL_TEXTURE0);
pTextures->ApplyTexture(2);
glUniform1i(glGetUniformLocation(pShaderMgr->id(1), "computeShadows"), true);

glPushMatrix();
glTranslatef(0.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2d(0.0f, 0.0f); glVertex3f(-20.0f, 0.0f, 20.0f);
glTexCoord2d(0.0f, 1.0f); glVertex3f(20.0f, 0.0f, 20.0f);
glTexCoord2d(1.0f, 1.0f); glVertex3f(20.0f, 0.0f, -20.0f);
glTexCoord2d(1.0f, 0.0f); glVertex3f(-20.0f, 0.0f, -20.0f);
glEnd();
glPopMatrix();

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);

pShaderMgr->unbind();

glDisable(GL_LIGHT0);
glDisable(GL_LIGHTING);
glPopAttrib();
Проблема заключается в сопоставлении карты теней с объектами сцены. Результат можно увидеть на этом изображении:
Изображение
< /p>
Тень отображается неправильно. Похоже, что это повторяется в объектах.
Я считаю, что это проблема при рендеринге кубов в функции рендеринга. Кто-нибудь может подсказать, почему на кубиках не правильно рассчитываются тени? Верх кубиков должен быть на свету...

Подробнее здесь: https://stackoverflow.com/questions/781 ... -behaviour
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Glsl рендеринг теней с помощью карты теней (+moderngl)
    Anonymous » » в форуме Python
    0 Ответы
    13 Просмотры
    Последнее сообщение Anonymous
  • Glsl рендеринг теней с помощью карт теней
    Anonymous » » в форуме Python
    0 Ответы
    15 Просмотры
    Последнее сообщение Anonymous
  • Видим странное поведение при попытке добавить PCF в шейдер карты теней.
    Anonymous » » в форуме C#
    0 Ответы
    15 Просмотры
    Последнее сообщение Anonymous
  • Представление имеет набор теней, но не может эффективно вычислять тень в React Native.
    Гость » » в форуме IOS
    0 Ответы
    109 Просмотры
    Последнее сообщение Гость
  • Представление имеет набор теней, но не может эффективно вычислять тень в React Native.
    Гость » » в форуме Javascript
    0 Ответы
    58 Просмотры
    Последнее сообщение Гость

Вернуться в «C++»