From 69aba7c352dc4d199309b9d4ee60403943d2a0e9 Mon Sep 17 00:00:00 2001 From: Martin Doucha Date: Sun, 29 Dec 2019 14:44:38 +0100 Subject: [PATCH] Fix OpenGL 3.3 specular lighting --- src/graphics/opengl/gl33device.cpp | 9 +++++++++ src/graphics/opengl/shaders/gl33/fs_normal.glsl | 9 +++++---- src/graphics/opengl/shaders/gl33/vs_normal.glsl | 3 +++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/graphics/opengl/gl33device.cpp b/src/graphics/opengl/gl33device.cpp index 0180f247..6d3a91eb 100644 --- a/src/graphics/opengl/gl33device.cpp +++ b/src/graphics/opengl/gl33device.cpp @@ -363,6 +363,7 @@ bool CGL33Device::Create() uni.modelMatrix = glGetUniformLocation(m_normalProgram, "uni_ModelMatrix"); uni.normalMatrix = glGetUniformLocation(m_normalProgram, "uni_NormalMatrix"); uni.shadowMatrix = glGetUniformLocation(m_normalProgram, "uni_ShadowMatrix"); + uni.cameraPosition = glGetUniformLocation(m_normalProgram, "uni_CameraPosition"); uni.primaryTexture = glGetUniformLocation(m_normalProgram, "uni_PrimaryTexture"); uni.secondaryTexture = glGetUniformLocation(m_normalProgram, "uni_SecondaryTexture"); @@ -420,6 +421,7 @@ bool CGL33Device::Create() glUniformMatrix4fv(uni.modelMatrix, 1, GL_FALSE, matrix.Array()); glUniformMatrix4fv(uni.normalMatrix, 1, GL_FALSE, matrix.Array()); glUniformMatrix4fv(uni.shadowMatrix, 1, GL_FALSE, matrix.Array()); + glUniform3f(uni.cameraPosition, 0.0f, 0.0f, 0.0f); glUniform1i(uni.primaryTexture, 0); glUniform1i(uni.secondaryTexture, 1); @@ -660,6 +662,7 @@ void CGL33Device::SetTransform(TransformType type, const Math::Matrix &matrix) else if (type == TRANSFORM_VIEW) { Math::Matrix scale; + Math::Vector cameraPosition; scale.Set(3, 3, -1.0f); m_viewMat = Math::MultiplyMatrices(scale, matrix); @@ -667,6 +670,12 @@ void CGL33Device::SetTransform(TransformType type, const Math::Matrix &matrix) m_combinedMatrixOutdated = true; glUniformMatrix4fv(m_uni->viewMatrix, 1, GL_FALSE, m_viewMat.Array()); + + if (m_uni->cameraPosition >= 0) { + cameraPosition.LoadZero(); + cameraPosition = MatrixVectorMultiply(m_viewMat.Inverse(), cameraPosition); + glUniform3fv(m_uni->cameraPosition, 1, cameraPosition.Array()); + } } else if (type == TRANSFORM_PROJECTION) { diff --git a/src/graphics/opengl/shaders/gl33/fs_normal.glsl b/src/graphics/opengl/shaders/gl33/fs_normal.glsl index e6fd1e07..7b498723 100644 --- a/src/graphics/opengl/shaders/gl33/fs_normal.glsl +++ b/src/graphics/opengl/shaders/gl33/fs_normal.glsl @@ -63,6 +63,7 @@ in VertexData vec4 ShadowCoord; vec4 LightColor; float Distance; + vec3 CameraDirection; } data; out vec4 out_FragColor; @@ -78,17 +79,17 @@ void main() vec4 specular = vec4(0.0f); vec3 normal = normalize(data.Normal); + vec3 camera = normalize(data.CameraDirection); for (int i = 0; i < uni_LightCount; i++) { - vec3 lightDirection = uni_Light[i].Position.xyz; - - vec3 reflectDirection = -reflect(lightDirection, normal); + vec3 lightDirection = normalize(uni_Light[i].Position.xyz); + vec3 reflectAxis = normalize(lightDirection + camera); ambient += uni_Light[i].Ambient; diffuse += clamp(dot(normal, lightDirection), 0.0f, 1.0f) * uni_Light[i].Diffuse; - specular += clamp(pow(dot(normal, lightDirection + reflectDirection), 10.0f), 0.0f, 1.0f) + specular += pow(clamp(dot(normal, reflectAxis), 0.0f, 1.0f), 10.0f) * uni_Light[i].Specular; } diff --git a/src/graphics/opengl/shaders/gl33/vs_normal.glsl b/src/graphics/opengl/shaders/gl33/vs_normal.glsl index aeed3c60..216682f7 100644 --- a/src/graphics/opengl/shaders/gl33/vs_normal.glsl +++ b/src/graphics/opengl/shaders/gl33/vs_normal.glsl @@ -25,6 +25,7 @@ uniform mat4 uni_ViewMatrix; uniform mat4 uni_ModelMatrix; uniform mat4 uni_ShadowMatrix; uniform mat4 uni_NormalMatrix; +uniform vec3 uni_CameraPosition; layout(location = 0) in vec4 in_VertexCoord; layout(location = 1) in vec3 in_Normal; @@ -41,6 +42,7 @@ out VertexData vec4 ShadowCoord; vec4 LightColor; float Distance; + vec3 CameraDirection; } data; void main() @@ -56,4 +58,5 @@ void main() data.Normal = normalize((uni_NormalMatrix * vec4(in_Normal, 0.0f)).xyz); data.ShadowCoord = vec4(shadowCoord.xyz / shadowCoord.w, 1.0f); data.Distance = abs(eyeSpace.z); + data.CameraDirection = uni_CameraPosition - position.xyz; }