From 03694d9c7c025e39f41cd7d858703ab5a14b021e Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Mon, 15 Dec 2014 00:18:03 +0100 Subject: [PATCH] Factorise SH coefficient in an UBO --- data/shaders/header.txt | 38 ++++++++++++++++++++++++++++++ data/shaders/utils/DiffuseIBL.frag | 29 +++++++++++++---------- src/graphics/irr_driver.hpp | 2 ++ src/graphics/render.cpp | 9 +++++++ src/graphics/shaders.cpp | 17 +++++++++++++ src/graphics/shaders.hpp | 2 +- src/graphics/shaders_util.hpp | 3 +++ 7 files changed, 86 insertions(+), 14 deletions(-) diff --git a/data/shaders/header.txt b/data/shaders/header.txt index 98e73f6a9..37712f7d7 100644 --- a/data/shaders/header.txt +++ b/data/shaders/header.txt @@ -5,6 +5,10 @@ uniform mat4 InverseViewMatrix; uniform mat4 InverseProjectionMatrix; uniform mat4 ProjectionViewMatrix; uniform vec2 screen; + +uniform float blueLmn[9]; +uniform float greenLmn[9]; +uniform float redLmn[9]; #else layout (std140) uniform MatrixesData { @@ -16,4 +20,38 @@ layout (std140) uniform MatrixesData mat4 ShadowViewProjMatrixes[4]; vec2 screen; }; + +// Expand because of catalyst (14.12) not correctly associating array in UBO +layout (std140) uniform LightingData +{ + float bL00; + float bL1m1; + float bL10; + float bL11; + float bL2m2; + float bL2m1; + float bL20; + float bL21; + float bL22; + + float gL00; + float gL1m1; + float gL10; + float gL11; + float gL2m2; + float gL2m1; + float gL20; + float gL21; + float gL22; + + float rL00; + float rL1m1; + float rL10; + float rL11; + float rL2m2; + float rL2m1; + float rL20; + float rL21; + float rL22; +}; #endif \ No newline at end of file diff --git a/data/shaders/utils/DiffuseIBL.frag b/data/shaders/utils/DiffuseIBL.frag index d06a24861..bbd36d71a 100644 --- a/data/shaders/utils/DiffuseIBL.frag +++ b/data/shaders/utils/DiffuseIBL.frag @@ -1,31 +1,34 @@ // From "An Efficient Representation for Irradiance Environment Maps" article // See http://graphics.stanford.edu/papers/envmap/ - // Coefficients are calculated in IBL.cpp -uniform float blueLmn[9]; -uniform float greenLmn[9]; -uniform float redLmn[9]; -mat4 getMatrix(float L[9]) +mat4 getMatrix(float L00, float L1m1, float L10, float L11, float L2m2, float L2m1, float L20, float L21, float L22) { float c1 = 0.429043, c2 = 0.511664, c3 = 0.743125, c4 = 0.886227, c5 = 0.247708; return mat4( - c1 * L[8] /*L22*/, c1 * L[4] /*L2-2*/, c1 * L[7] /*L21*/, c2 * L[3] /*L11*/, - c1 * L[4], - c1 * L[8], c1 * L[5] /*L2-1*/, c2 * L[1] /*L1-1*/, - c1 * L[7], c1 * L[5], c3 * L[6] /*L20*/, c2 * L[2] /*L10*/, - c2 * L[3], c2 * L[1], c2 * L[2], c4 * L[0] /*L00*/ - c5 * L[6] + c1 * L22, c1 * L2m2, c1 * L21, c2 * L11, + c1 * L2m2, - c1 * L22, c1 * L2m1, c2 * L1m1, + c1 * L21, c1 * L2m1, c3 * L20, c2 * L10, + c2 * L11, c2 * L1m1, c2 * L10, c4 * L00 - c5 * L20 ); } vec3 DiffuseIBL(vec3 normal) { - // Convert normal in world space (where SH coordinates were computed) + // Convert normal in wobLd space (where SH coordinates were computed) vec4 extendednormal = transpose(ViewMatrix) * vec4(normal, 0.); extendednormal.w = 1.; - mat4 rmat = getMatrix(redLmn); - mat4 gmat = getMatrix(greenLmn); - mat4 bmat = getMatrix(blueLmn); + +#ifdef UBO_DISABLED + mat4 rmat = getMatrix(redLmn[0], redLmn[1], redLmn[2], redLmn[3], redLmn[4], redLmn[5], redLmn[6], redLmn[7], redLmn[8]); + mat4 gmat = getMatrix(greenLmn[0], greenLmn[1], greenLmn[2], greenLmn[3], greenLmn[4], greenLmn[5], greenLmn[6], greenLmn[7], greenLmn[8]); + mat4 bmat = getMatrix(blueLmn[0], blueLmn[1], blueLmn[2], blueLmn[3], blueLmn[4], blueLmn[5], blueLmn[6], blueLmn[7], blueLmn[8]); +#else + mat4 rmat = getMatrix(rL00, rL1m1, rL10, rL11, rL2m2, rL2m1, rL20, rL21, rL22); + mat4 gmat = getMatrix(gL00, gL1m1, gL10, gL11, gL2m2, gL2m1, gL20, gL21, gL22); + mat4 bmat = getMatrix(bL00, bL1m1, bL10, bL11, bL2m2, bL2m1, bL20, bL21, bL22); +#endif float r = dot(extendednormal, rmat * extendednormal); float g = dot(extendednormal, gmat * extendednormal); diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index b5732f2f3..e51e55e50 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -238,9 +238,11 @@ private: std::vector SphericalHarmonicsTextures; bool m_skybox_ready; +public: float blueSHCoeff[9]; float greenSHCoeff[9]; float redSHCoeff[9]; +private: /** Keep a trace of the origin file name of a texture. */ std::map m_texturesFileName; diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 1c7e8b13f..0e9728c9d 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -342,6 +342,7 @@ void IrrDriver::renderGLSL(float dt) void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned pointlightcount, std::vector& glows, float dt, bool hasShadow, bool forceRTT) { glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO); + glBindBufferBase(GL_UNIFORM_BUFFER, 1, SharedObject::LightingDataUBO); m_scene_manager->setActiveCamera(camnode); PROFILER_PUSH_CPU_MARKER("- Draw Call Generation", 0xFF, 0xFF, 0xFF); @@ -961,6 +962,14 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz tmp[145] = float(height); glBindBuffer(GL_UNIFORM_BUFFER, SharedObject::ViewProjectionMatrixesUBO); glBufferSubData(GL_UNIFORM_BUFFER, 0, (16 * 9 + 2) * sizeof(float), tmp); + + float Lighting[27]; + memcpy(Lighting, blueSHCoeff, 9 * sizeof(float)); + memcpy(&Lighting[9], greenSHCoeff, 9 * sizeof(float)); + memcpy(&Lighting[18], redSHCoeff, 9 * sizeof(float)); + + glBindBuffer(GL_UNIFORM_BUFFER, SharedObject::LightingDataUBO); + glBufferSubData(GL_UNIFORM_BUFFER, 0, 27 * sizeof(float), Lighting); } diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index d2fc9213d..670dd50c1 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -427,6 +427,16 @@ static void initShadowVPMUBO() glBindBuffer(GL_UNIFORM_BUFFER, 0); } +GLuint SharedObject::LightingDataUBO; + +static void initLightingDataUBO() +{ + glGenBuffers(1, &SharedObject::LightingDataUBO); + glBindBuffer(GL_UNIFORM_BUFFER, SharedObject::LightingDataUBO); + glBufferData(GL_UNIFORM_BUFFER, 27 * sizeof(float), 0, GL_STREAM_DRAW); + glBindBuffer(GL_UNIFORM_BUFFER, 0); +} + GLuint SharedObject::ParticleQuadVBO = 0; static void initParticleQuadVBO() @@ -527,6 +537,7 @@ void Shaders::loadShaders() initCubeVBO(); initFrustrumVBO(); initShadowVPMUBO(); + initLightingDataUBO(); initParticleQuadVBO(); } @@ -574,6 +585,12 @@ void bypassUBO(GLuint Program) glUniformMatrix4fv(IPM, 1, GL_FALSE, irr_driver->getInvProjMatrix().pointer()); GLint Screen = glGetUniformLocation(Program, "screen"); glUniform2f(Screen, irr_driver->getCurrentScreenSize().X, irr_driver->getCurrentScreenSize().Y); + GLint bLmn = glGetUniformLocation(Program, "blueLmn[0]"); + glUniform1fv(bLmn, 9, irr_driver->blueSHCoeff); + GLint gLmn = glGetUniformLocation(Program, "greenLmn[0]"); + glUniform1fv(gLmn, 9, irr_driver->greenSHCoeff); + GLint rLmn = glGetUniformLocation(Program, "redLmn[0]"); + glUniform1fv(rLmn, 9, irr_driver->redSHCoeff); } namespace UtilShader diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 43a9a56a0..2c7d785ce 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -31,7 +31,7 @@ class SharedObject public: static GLuint billboardvbo; static GLuint cubevbo, cubeindexes, frustrumvbo, frustrumindexes, ParticleQuadVBO; - static GLuint ViewProjectionMatrixesUBO; + static GLuint ViewProjectionMatrixesUBO, LightingDataUBO; static GLuint FullScreenQuadVAO; static GLuint UIVAO; }; diff --git a/src/graphics/shaders_util.hpp b/src/graphics/shaders_util.hpp index e917125fc..8532ed876 100644 --- a/src/graphics/shaders_util.hpp +++ b/src/graphics/shaders_util.hpp @@ -171,6 +171,9 @@ protected: GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); if (uniform_ViewProjectionMatrixesUBO != GL_INVALID_INDEX) glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); + GLuint uniform_LightingUBO = glGetUniformBlockIndex(Program, "LightingData"); + if (uniform_LightingUBO != GL_INVALID_INDEX) + glUniformBlockBinding(Program, uniform_LightingUBO, 1); } template