From 8aa5031fc0e9f8f8f9c19d8e641add898864cafa Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Mon, 7 Apr 2014 17:47:49 +0200 Subject: [PATCH 01/10] FBO: Combined TMP1 and TMP2 should embed DS. --- src/graphics/rtts.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/rtts.cpp b/src/graphics/rtts.cpp index 4532035f2..c012a631a 100644 --- a/src/graphics/rtts.cpp +++ b/src/graphics/rtts.cpp @@ -119,7 +119,7 @@ RTT::RTT() FrameBuffers[FBO_EIGHTH1] = generateFBO(RenderTargetTextures[RTT_EIGHTH1]); FrameBuffers[FBO_EIGHTH2] = generateFBO(RenderTargetTextures[RTT_EIGHTH2]); - FrameBuffers[FBO_COMBINED_TMP1_TMP2] = generateFBO(RenderTargetTextures[RTT_TMP1]); + FrameBuffers[FBO_COMBINED_TMP1_TMP2] = generateFBO(RenderTargetTextures[RTT_TMP1], DepthStencilTexture); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, RenderTargetTextures[RTT_TMP2], 0); if (irr_driver->getGLSLVersion() >= 150) From 0b318b9c7eedf69f4f5b93a6e54458ff124d55e4 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Mon, 7 Apr 2014 21:04:03 +0200 Subject: [PATCH 02/10] Improve quad's fit of pointlight extend --- data/shaders/pointlight.vert | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/data/shaders/pointlight.vert b/data/shaders/pointlight.vert index 540584c4c..b859620c8 100644 --- a/data/shaders/pointlight.vert +++ b/data/shaders/pointlight.vert @@ -16,23 +16,24 @@ const float zNear = 1.; void main(void) { // Beyond that value, light is too attenuated - float r = 40 * Energy; + float r = 50 * Energy; center = Position; energy = Energy; vec4 Center = ViewMatrix * vec4(Position, 1.); + vec4 ProjectedCornerPosition = ProjectionMatrix * (Center + r * vec4(Corner, 0., 0.)); + float adjustedDepth = ProjectedCornerPosition.z; if (Center.z > zNear) // Light is in front of the cam { - vec3 UnitCenter = normalize(-Center.xyz); - float clampedR = min(r, Center.z - 1.); - float cosTheta = dot(UnitCenter, vec3(0., 0., -1)); - float d = clampedR / cosTheta; - Center.xyz += d * UnitCenter; + adjustedDepth = max(Center.z - r, zNear); } else if (Center.z + r > zNear) // Light is behind the cam but in range { - Center.z = zNear; - // TODO: Change r so that we make the screen aligned quad fits light range. + adjustedDepth = zNear; } + + ProjectedCornerPosition /= ProjectedCornerPosition.w; + ProjectedCornerPosition.zw = (ProjectionMatrix * vec4(0., 0., adjustedDepth, 1.)).zw; + ProjectedCornerPosition.xy *= ProjectedCornerPosition.w; col = Color; - gl_Position = ProjectionMatrix * (Center + r * vec4(Corner, 0., 0.)); + gl_Position = ProjectedCornerPosition; } From cafc07680a33d4817fa5509a6366c6890907c338 Mon Sep 17 00:00:00 2001 From: vlj Date: Sun, 6 Apr 2014 21:23:09 +0200 Subject: [PATCH 03/10] Use Blinn Phong model. --- data/shaders/pointlight.frag | 52 +++++++++++++++----------------- data/shaders/sunlight.frag | 13 +++++--- data/shaders/sunlightshadow.frag | 13 +++++--- 3 files changed, 41 insertions(+), 37 deletions(-) diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index cba9e2e49..d9db8a933 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -14,36 +14,34 @@ out vec4 Specular; vec3 DecodeNormal(vec2 n); -void main() { - vec2 texc = gl_FragCoord.xy / screen; - float z = texture(dtex, texc).x; - vec3 norm = normalize(DecodeNormal(2. * texture(ntex, texc).xy - 1.)); +void main() +{ + vec2 texc = gl_FragCoord.xy / screen; + float z = texture(dtex, texc).x; + vec3 norm = normalize(DecodeNormal(2. * texture(ntex, texc).xy - 1.)); + //float roughness = texture(ntex, texc).z; - vec4 xpos = 2.0 * vec4(texc, z, 1.0) - 1.0f; - xpos = invproj * xpos; - xpos /= xpos.w; - vec3 eyedir = normalize(xpos.xyz); + vec4 xpos = 2.0 * vec4(texc, z, 1.0) - 1.0f; + xpos = invproj * xpos; + xpos /= xpos.w; + vec3 eyedir = -normalize(xpos.xyz); - vec3 diffuse = vec3(0.), specular = vec3(0.); + vec4 pseudocenter = ViewMatrix * vec4(center.xyz, 1.0); + pseudocenter /= pseudocenter.w; + vec3 light_pos = pseudocenter.xyz; + vec3 light_col = col.xyz; + float d = distance(light_pos, xpos.xyz); + float att = energy * 200. / (4. * 3.14 * d * d); + float spec_att = (energy + 10.) * 200. / (4. * 3.14 * d * d); - vec4 pseudocenter = ViewMatrix * vec4(center.xyz, 1.0); - pseudocenter /= pseudocenter.w; - vec3 light_pos = pseudocenter.xyz; - vec3 light_col = col.xyz; - float d = distance(light_pos, xpos.xyz); - float att = energy * 200. / (4. * 3.14 * d * d); - float spec_att = (energy + 10.) * 200. / (4. * 3.14 * d * d); + // Light Direction + vec3 L = -normalize(xpos.xyz - light_pos); + // Half Light View direction + vec3 H = normalize(eyedir + L); - // Light Direction - vec3 L = normalize(xpos.xyz - light_pos); + float NdotL = max(0., dot(norm, L)); + float NdotH = max(0., dot(norm, H)); - float NdotL = max(0.0, dot(norm, -L)); - diffuse += NdotL * light_col * att; - // Reflected light dir - vec3 R = reflect(-L, norm); - float RdotE = max(0.0, dot(R, eyedir)); - specular += pow(RdotE, spec) * light_col * spec_att; - - Diffuse = vec4(diffuse, 1.); - Specular = vec4(specular , 1.); + Diffuse = vec4(NdotL * light_col * att, 1.); + Specular = vec4(pow(NdotH, spec) * light_col * NdotL * spec_att, 1.); } diff --git a/data/shaders/sunlight.frag b/data/shaders/sunlight.frag index 0f56d1671..101100c0f 100644 --- a/data/shaders/sunlight.frag +++ b/data/shaders/sunlight.frag @@ -36,14 +36,17 @@ void main() { } vec3 norm = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.)); + vec3 eyedir = -normalize(xpos.xyz); // Normalized on the cpu - vec3 L = direction; + vec3 L = direction; + // Half Light View direction + vec3 H = normalize(eyedir + L); - float NdotL = max(0.0, dot(norm, L)); - vec3 R = reflect(L, norm); - float RdotE = max(0.0, dot(R, normalize(xpos.xyz))); - float Specular = pow(RdotE, 200); + float NdotL = max(0., dot(norm, L)); + float NdotH = max(0., dot(norm, H)); + + float Specular = pow(NdotH, 200) * NdotL; vec3 outcol = NdotL * col; diff --git a/data/shaders/sunlightshadow.frag b/data/shaders/sunlightshadow.frag index dc2db7199..75ecbfb10 100644 --- a/data/shaders/sunlightshadow.frag +++ b/data/shaders/sunlightshadow.frag @@ -64,14 +64,17 @@ void main() { xpos.xyz /= xpos.w; vec3 norm = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.)); + vec3 eyedir = -normalize(xpos.xyz); // Normalized on the cpu - vec3 L = direction; + vec3 L = direction; + // Half Light View direction + vec3 H = normalize(eyedir + L); - float NdotL = max(0.0, dot(norm, L)); - vec3 R = reflect(L, norm); - float RdotE = max(0.0, dot(R, normalize(xpos.xyz))); - float Specular = pow(RdotE, 200); + float NdotL = max(0., dot(norm, L)); + float NdotH = max(0., dot(norm, H)); + + float Specular = pow(NdotH, 200) * NdotL; vec3 outcol = NdotL * col; From 79c64247039247593585488a61cf8b916da32739 Mon Sep 17 00:00:00 2001 From: vlj Date: Sun, 6 Apr 2014 22:19:10 +0200 Subject: [PATCH 04/10] Use specularmap as glossiness map. --- data/shaders/object_pass1.frag | 9 +++++++-- data/shaders/object_pass2.frag | 2 +- data/shaders/objectref_pass1.frag | 5 +++-- data/shaders/pointlight.frag | 5 +++-- data/shaders/sunlight.frag | 4 +++- data/shaders/sunlightshadow.frag | 5 ++++- src/graphics/rtts.cpp | 2 +- src/graphics/shaders.cpp | 7 ++++++- src/graphics/shaders.hpp | 6 +++--- src/graphics/stkmesh.cpp | 5 +++-- 10 files changed, 34 insertions(+), 16 deletions(-) diff --git a/data/shaders/object_pass1.frag b/data/shaders/object_pass1.frag index e699e1593..e8e0df6ba 100644 --- a/data/shaders/object_pass1.frag +++ b/data/shaders/object_pass1.frag @@ -1,6 +1,9 @@ +uniform sampler2D tex; + #if __VERSION__ >= 130 in vec3 nor; -out vec2 EncodedNormal; +in vec2 uv; +out vec3 EncodedNormal; #else varying vec3 nor; #define EncodedNormal gl_FragColor.xy @@ -10,5 +13,7 @@ vec2 EncodeNormal(vec3 n); void main(void) { - EncodedNormal = 0.5 * EncodeNormal(normalize(nor)) + 0.5; + vec4 col = texture(tex, uv); + EncodedNormal.xy = 0.5 * EncodeNormal(normalize(nor)) + 0.5; + EncodedNormal.z = exp2(10. * (1. - col.a) + 1.); } diff --git a/data/shaders/object_pass2.frag b/data/shaders/object_pass2.frag index 727975e99..3f802425b 100644 --- a/data/shaders/object_pass2.frag +++ b/data/shaders/object_pass2.frag @@ -13,6 +13,6 @@ vec3 getLightFactor(float specMapValue); void main(void) { vec4 color = texture(Albedo, uv); - vec3 LightFactor = getLightFactor(1. - color.a); + vec3 LightFactor = getLightFactor(1.); FragColor = vec4(color.xyz * LightFactor, 1.); } diff --git a/data/shaders/objectref_pass1.frag b/data/shaders/objectref_pass1.frag index b32d97f1d..f4cf55e29 100644 --- a/data/shaders/objectref_pass1.frag +++ b/data/shaders/objectref_pass1.frag @@ -3,7 +3,7 @@ uniform sampler2D tex; #if __VERSION__ >= 130 in vec3 nor; in vec2 uv; -out vec2 EncodedNormal; +out vec3 EncodedNormal; #else varying vec3 nor; varying vec2 uv; @@ -16,6 +16,7 @@ void main() { vec4 col = texture(tex, uv); if (col.a < 0.5) discard; - EncodedNormal = 0.5 * EncodeNormal(normalize(nor)) + 0.5; + EncodedNormal.xy = 0.5 * EncodeNormal(normalize(nor)) + 0.5; + EncodedNormal.z = 1.; } diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index d9db8a933..97e48232b 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -19,7 +19,7 @@ void main() vec2 texc = gl_FragCoord.xy / screen; float z = texture(dtex, texc).x; vec3 norm = normalize(DecodeNormal(2. * texture(ntex, texc).xy - 1.)); - //float roughness = texture(ntex, texc).z; + float roughness = texture(ntex, texc).z; vec4 xpos = 2.0 * vec4(texc, z, 1.0) - 1.0f; xpos = invproj * xpos; @@ -41,7 +41,8 @@ void main() float NdotL = max(0., dot(norm, L)); float NdotH = max(0., dot(norm, H)); + float normalisationFactor = (roughness + 2.) / 8.; Diffuse = vec4(NdotL * light_col * att, 1.); - Specular = vec4(pow(NdotH, spec) * light_col * NdotL * spec_att, 1.); + Specular = vec4(pow(NdotH, roughness) * light_col * NdotL * spec_att * normalisationFactor, 1.); } diff --git a/data/shaders/sunlight.frag b/data/shaders/sunlight.frag index 101100c0f..ff02fcfc9 100644 --- a/data/shaders/sunlight.frag +++ b/data/shaders/sunlight.frag @@ -36,6 +36,7 @@ void main() { } vec3 norm = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.)); + float roughness = texture(ntex, uv).z; vec3 eyedir = -normalize(xpos.xyz); // Normalized on the cpu @@ -46,7 +47,8 @@ void main() { float NdotL = max(0., dot(norm, L)); float NdotH = max(0., dot(norm, H)); - float Specular = pow(NdotH, 200) * NdotL; + float normalisationFactor = (roughness + 2.) / 8.; + float Specular = pow(NdotH, roughness) * NdotL * normalisationFactor; vec3 outcol = NdotL * col; diff --git a/data/shaders/sunlightshadow.frag b/data/shaders/sunlightshadow.frag index 75ecbfb10..c3fba5d8d 100644 --- a/data/shaders/sunlightshadow.frag +++ b/data/shaders/sunlightshadow.frag @@ -64,6 +64,7 @@ void main() { xpos.xyz /= xpos.w; vec3 norm = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.)); + float roughness =texture(ntex, uv).z; vec3 eyedir = -normalize(xpos.xyz); // Normalized on the cpu @@ -74,7 +75,9 @@ void main() { float NdotL = max(0., dot(norm, L)); float NdotH = max(0., dot(norm, H)); - float Specular = pow(NdotH, 200) * NdotL; + float normalisationFactor = (roughness + 2.) / 8.; + float Specular = pow(NdotH, roughness) * NdotL * normalisationFactor; + vec3 outcol = NdotL * col; diff --git a/src/graphics/rtts.cpp b/src/graphics/rtts.cpp index c012a631a..9060ee48f 100644 --- a/src/graphics/rtts.cpp +++ b/src/graphics/rtts.cpp @@ -84,7 +84,7 @@ RTT::RTT() RenderTargetTextures[RTT_TMP2] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT); RenderTargetTextures[RTT_TMP3] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT); RenderTargetTextures[RTT_TMP4] = generateRTT(res, GL_R16F, GL_RED, GL_FLOAT); - RenderTargetTextures[RTT_NORMAL_AND_DEPTH] = generateRTT(res, GL_RG16F, GL_RG, GL_FLOAT); + RenderTargetTextures[RTT_NORMAL_AND_DEPTH] = generateRTT(res, GL_RGB16F, GL_RGB, GL_FLOAT); RenderTargetTextures[RTT_COLOR] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT); RenderTargetTextures[RTT_MLAA_COLORS] = generateRTT(res, GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE); RenderTargetTextures[RTT_LOG_LUMINANCE] = generateRTT(res, GL_R16F, GL_RED, GL_FLOAT); diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 3a5b2287a..b7adc0d7d 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -395,8 +395,10 @@ namespace MeshShader GLuint ObjectPass1Shader::Program; GLuint ObjectPass1Shader::attrib_position; GLuint ObjectPass1Shader::attrib_normal; + GLuint ObjectPass1Shader::attrib_texcoord; GLuint ObjectPass1Shader::uniform_MVP; GLuint ObjectPass1Shader::uniform_TIMV; + GLuint ObjectPass1Shader::uniform_tex; void ObjectPass1Shader::init() { @@ -406,14 +408,17 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_pass1.frag").c_str()); attrib_position = glGetAttribLocation(Program, "Position"); attrib_normal = glGetAttribLocation(Program, "Normal"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); + uniform_tex = glGetUniformLocation(Program, "tex"); } - void ObjectPass1Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView) + void ObjectPass1Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_tex) { glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); + glUniform1i(uniform_tex, TU_tex); } GLuint ObjectRefPass1Shader::Program; diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 6e36e76cd..97ae2db1e 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -37,11 +37,11 @@ class ObjectPass1Shader { public: static GLuint Program; - static GLuint attrib_position, attrib_normal; - static GLuint uniform_MVP, uniform_TIMV; + static GLuint attrib_position, attrib_texcoord, attrib_normal; + static GLuint uniform_MVP, uniform_TIMV, uniform_tex; static void init(); - static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_tex); }; class ObjectRefPass1Shader diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 80a3398d1..8d5ef32a9 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -225,7 +225,8 @@ void drawObjectPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjecti GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - MeshShader::ObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView); + setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + MeshShader::ObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0); assert(mesh.vao_first_pass); glBindVertexArray(mesh.vao_first_pass); @@ -743,7 +744,7 @@ void initvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedM { case FPSM_DEFAULT: mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::ObjectPass1Shader::attrib_position, -1, -1, MeshShader::ObjectPass1Shader::attrib_normal, -1, -1, -1, mesh.Stride); + MeshShader::ObjectPass1Shader::attrib_position, MeshShader::ObjectPass1Shader::attrib_texcoord, -1, MeshShader::ObjectPass1Shader::attrib_normal, -1, -1, -1, mesh.Stride); mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::ShadowShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride); break; case FPSM_ALPHA_REF_TEXTURE: From 858c8c760501830c79aedebc50037b1ae9c35da5 Mon Sep 17 00:00:00 2001 From: vlj Date: Sun, 6 Apr 2014 23:26:45 +0200 Subject: [PATCH 05/10] Fix normalmap too --- data/shaders/normalmap.frag | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/data/shaders/normalmap.frag b/data/shaders/normalmap.frag index fe08ff17e..c1d9120d9 100644 --- a/data/shaders/normalmap.frag +++ b/data/shaders/normalmap.frag @@ -4,7 +4,7 @@ uniform sampler2D normalMap; in vec3 tangent; in vec3 bitangent; in vec2 uv; -out vec2 EncodedNormal; +out vec3 EncodedNormal; #else varying vec3 tangent; varying vec3 bitangent; @@ -26,5 +26,6 @@ void main() vec3 Frag_bitangent = cross(Frag_normal, Frag_tangent); vec3 FragmentNormal = TS_normal.x * Frag_tangent + TS_normal.y * Frag_bitangent - TS_normal.z * Frag_normal; - EncodedNormal = 0.5 * EncodeNormal(normalize(FragmentNormal)) + 0.5; + EncodedNormal.xy = 0.5 * EncodeNormal(normalize(FragmentNormal)) + 0.5; + EncodedNormal.z = 1.; } From e00ce85d7c978e034e3e6ceffb3cc3108594a2fb Mon Sep 17 00:00:00 2001 From: vlj Date: Sun, 6 Apr 2014 23:57:54 +0200 Subject: [PATCH 06/10] Support FresnelSchlick factor. --- data/shaders/pointlight.frag | 7 ++----- data/shaders/sunlight.frag | 9 +++------ data/shaders/sunlightshadow.frag | 9 +++------ data/shaders/utils/getSpecular.frag | 11 +++++++++++ src/graphics/shaders.cpp | 3 +++ 5 files changed, 22 insertions(+), 17 deletions(-) create mode 100644 data/shaders/utils/getSpecular.frag diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index 97e48232b..30b891dcd 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -13,6 +13,7 @@ out vec4 Diffuse; out vec4 Specular; vec3 DecodeNormal(vec2 n); +vec3 getSpecular(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness); void main() { @@ -36,13 +37,9 @@ void main() // Light Direction vec3 L = -normalize(xpos.xyz - light_pos); - // Half Light View direction - vec3 H = normalize(eyedir + L); float NdotL = max(0., dot(norm, L)); - float NdotH = max(0., dot(norm, H)); - float normalisationFactor = (roughness + 2.) / 8.; Diffuse = vec4(NdotL * light_col * att, 1.); - Specular = vec4(pow(NdotH, roughness) * light_col * NdotL * spec_att * normalisationFactor, 1.); + Specular = vec4(getSpecular(norm, eyedir, L, light_col, roughness) * NdotL * spec_att, 1.); } diff --git a/data/shaders/sunlight.frag b/data/shaders/sunlight.frag index ff02fcfc9..700a1c3d5 100644 --- a/data/shaders/sunlight.frag +++ b/data/shaders/sunlight.frag @@ -20,6 +20,7 @@ varying vec2 uv; vec3 DecodeNormal(vec2 n); +vec3 getSpecular(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness); void main() { float z = texture(dtex, uv).x; @@ -41,14 +42,10 @@ void main() { // Normalized on the cpu vec3 L = direction; - // Half Light View direction - vec3 H = normalize(eyedir + L); float NdotL = max(0., dot(norm, L)); - float NdotH = max(0., dot(norm, H)); - float normalisationFactor = (roughness + 2.) / 8.; - float Specular = pow(NdotH, roughness) * NdotL * normalisationFactor; + vec3 Specular = getSpecular(norm, eyedir, L, col, roughness) * NdotL; vec3 outcol = NdotL * col; @@ -62,5 +59,5 @@ void main() { }*/ Diff = vec4(NdotL * col, 1.); - Spec = vec4(Specular * col, 1.); + Spec = vec4(Specular, 1.); } diff --git a/data/shaders/sunlightshadow.frag b/data/shaders/sunlightshadow.frag index c3fba5d8d..78b769a27 100644 --- a/data/shaders/sunlightshadow.frag +++ b/data/shaders/sunlightshadow.frag @@ -24,6 +24,7 @@ varying vec2 uv; vec3 DecodeNormal(vec2 n); +vec3 getSpecular(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness); float getShadowFactor(vec3 pos, float bias, int index) { @@ -69,14 +70,10 @@ void main() { // Normalized on the cpu vec3 L = direction; - // Half Light View direction - vec3 H = normalize(eyedir + L); float NdotL = max(0., dot(norm, L)); - float NdotH = max(0., dot(norm, H)); - float normalisationFactor = (roughness + 2.) / 8.; - float Specular = pow(NdotH, roughness) * NdotL * normalisationFactor; + vec3 Specular = getSpecular(norm, eyedir, L, col, roughness) * NdotL; vec3 outcol = NdotL * col; @@ -118,7 +115,7 @@ void main() { else factor = getShadowFactor(xpos.xyz, bias, 3); Diff = vec4(factor * NdotL * col, 1.); - Spec = vec4(factor * Specular * col, 1.); + Spec = vec4(factor * Specular, 1.); return; // float moved = (abs(dx) + abs(dy)) * 0.5; diff --git a/data/shaders/utils/getSpecular.frag b/data/shaders/utils/getSpecular.frag new file mode 100644 index 000000000..629cec7b8 --- /dev/null +++ b/data/shaders/utils/getSpecular.frag @@ -0,0 +1,11 @@ + + +vec3 getSpecular(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness) +{ + // Half Light View direction + vec3 H = normalize(eyedir + lightdir); + float NdotH = max(0., dot(normal, H)); + float normalisationFactor = (roughness + 2.) / 8.; + vec3 FresnelSchlick = color + (1.0f - color) * pow(1.0f - max(0., (dot(eyedir, H))), 5); + return max(pow(NdotH, roughness) * FresnelSchlick * normalisationFactor, vec3(0.)); +} \ No newline at end of file diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index b7adc0d7d..400bfbe1f 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -1707,6 +1707,7 @@ namespace LightShader Program = LoadProgram( GL_VERTEX_SHADER, file_manager->getAsset("shaders/pointlight.vert").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/decodeNormal.frag").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getSpecular.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/pointlight.frag").c_str()); attrib_Position = glGetAttribLocation(Program, "Position"); attrib_Color = glGetAttribLocation(Program, "Color"); @@ -2042,6 +2043,7 @@ namespace FullScreenShader Program = LoadProgram( GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/decodeNormal.frag").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getSpecular.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/sunlight.frag").c_str()); uniform_ntex = glGetUniformLocation(Program, "ntex"); uniform_dtex = glGetUniformLocation(Program, "dtex"); @@ -2106,6 +2108,7 @@ namespace FullScreenShader Program = LoadProgram( GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/decodeNormal.frag").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getSpecular.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/sunlightshadow.frag").c_str()); uniform_ntex = glGetUniformLocation(Program, "ntex"); uniform_dtex = glGetUniformLocation(Program, "dtex"); From 939e574cd8c70de39d230db6431c7be63c8a8631 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Mon, 7 Apr 2014 22:19:25 +0200 Subject: [PATCH 07/10] Make bloom effect more subtle. --- src/graphics/post_processing.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 6141501b3..f1441087a 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -626,27 +626,23 @@ void PostProcessing::render() glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_HALF1)); glViewport(0, 0, UserConfigParams::m_width / 2, UserConfigParams::m_height / 2); renderPassThrough(irr_driver->getRenderTargetTexture(RTT_TMP2)); + renderGaussian6Blur(irr_driver->getFBO(FBO_HALF1), irr_driver->getRenderTargetTexture(RTT_HALF1), + irr_driver->getFBO(FBO_HALF2), irr_driver->getRenderTargetTexture(RTT_HALF2), UserConfigParams::m_width / 2, UserConfigParams::m_height / 2); // To quarter glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_QUARTER1)); glViewport(0, 0, UserConfigParams::m_width / 4, UserConfigParams::m_height / 4); renderPassThrough(irr_driver->getRenderTargetTexture(RTT_HALF1)); + renderGaussian6Blur(irr_driver->getFBO(FBO_QUARTER1), irr_driver->getRenderTargetTexture(RTT_QUARTER1), + irr_driver->getFBO(FBO_QUARTER2), irr_driver->getRenderTargetTexture(RTT_QUARTER2), UserConfigParams::m_width / 4, UserConfigParams::m_height / 4); // To eighth glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_EIGHTH1)); glViewport(0, 0, UserConfigParams::m_width / 8, UserConfigParams::m_height / 8); renderPassThrough(irr_driver->getRenderTargetTexture(RTT_QUARTER1)); - - // Blur it for distribution. - glViewport(0, 0, UserConfigParams::m_width / 2, UserConfigParams::m_height / 2); - renderGaussian6Blur(irr_driver->getFBO(FBO_HALF1), irr_driver->getRenderTargetTexture(RTT_HALF1), - irr_driver->getFBO(FBO_HALF2), irr_driver->getRenderTargetTexture(RTT_HALF2), UserConfigParams::m_width / 2, UserConfigParams::m_height / 2); - glViewport(0, 0, UserConfigParams::m_width / 4, UserConfigParams::m_height / 4); - renderGaussian6Blur(irr_driver->getFBO(FBO_QUARTER1), irr_driver->getRenderTargetTexture(RTT_QUARTER1), - irr_driver->getFBO(FBO_QUARTER2), irr_driver->getRenderTargetTexture(RTT_QUARTER2), UserConfigParams::m_width / 4, UserConfigParams::m_height / 4); - glViewport(0, 0, UserConfigParams::m_width / 8, UserConfigParams::m_height / 8); renderGaussian6Blur(irr_driver->getFBO(FBO_EIGHTH1), irr_driver->getRenderTargetTexture(RTT_EIGHTH1), irr_driver->getFBO(FBO_EIGHTH2), irr_driver->getRenderTargetTexture(RTT_EIGHTH2), UserConfigParams::m_width / 8, UserConfigParams::m_height / 8); + glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height); // Additively blend on top of tmp1 From eb0dfb4530765bc55767ffe74dcc74ba660a111d Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Mon, 7 Apr 2014 22:20:43 +0200 Subject: [PATCH 08/10] Bigger light extend wrt energy. --- data/shaders/pointlight.vert | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/shaders/pointlight.vert b/data/shaders/pointlight.vert index b859620c8..1831d4559 100644 --- a/data/shaders/pointlight.vert +++ b/data/shaders/pointlight.vert @@ -16,7 +16,7 @@ const float zNear = 1.; void main(void) { // Beyond that value, light is too attenuated - float r = 50 * Energy; + float r = 500 * Energy; center = Position; energy = Energy; vec4 Center = ViewMatrix * vec4(Position, 1.); From 8fc3453eda3818329bd0e8badda16cabbdb546ae Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Mon, 7 Apr 2014 22:23:16 +0200 Subject: [PATCH 09/10] Fix instancied glossy map. --- src/graphics/shaders.cpp | 5 ++++- src/graphics/shaders.hpp | 4 ++-- src/graphics/stkinstancedscenenode.cpp | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 400bfbe1f..0f353c9a6 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -526,6 +526,7 @@ namespace MeshShader GLuint InstancedObjectPass1Shader::attrib_scale; GLuint InstancedObjectPass1Shader::uniform_MP; GLuint InstancedObjectPass1Shader::uniform_VM; + GLuint InstancedObjectPass1Shader::uniform_tex; void InstancedObjectPass1Shader::init() { @@ -541,12 +542,14 @@ namespace MeshShader attrib_normal = glGetAttribLocation(Program, "Normal"); uniform_MP = glGetUniformLocation(Program, "ViewProjectionMatrix"); uniform_VM = glGetUniformLocation(Program, "InverseViewMatrix"); + uniform_tex = glGetUniformLocation(Program, "tex"); } - void InstancedObjectPass1Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &ViewMatrix) + void InstancedObjectPass1Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &ViewMatrix, unsigned TU_tex) { glUniformMatrix4fv(uniform_MP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); glUniformMatrix4fv(uniform_VM, 1, GL_FALSE, ViewMatrix.pointer()); + glUniform1i(uniform_tex, TU_tex); } GLuint InstancedObjectRefPass1Shader::Program; diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 97ae2db1e..6486ba511 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -82,10 +82,10 @@ class InstancedObjectPass1Shader public: static GLuint Program; static GLuint attrib_position, attrib_normal, attrib_origin, attrib_orientation, attrib_scale; - static GLuint uniform_MP, uniform_VM; + static GLuint uniform_MP, uniform_VM, uniform_tex; static void init(); - static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &ViewMatrix); + static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &ViewMatrix, unsigned TU_tex); }; class InstancedObjectRefPass1Shader diff --git a/src/graphics/stkinstancedscenenode.cpp b/src/graphics/stkinstancedscenenode.cpp index 5378bdafc..9ce67a9ab 100644 --- a/src/graphics/stkinstancedscenenode.cpp +++ b/src/graphics/stkinstancedscenenode.cpp @@ -189,7 +189,8 @@ static void drawFSPMDefault(GLMesh &mesh, const core::matrix4 &ModelViewProjecti core::matrix4 InverseViewMatrix; irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW).getInverse(InverseViewMatrix); - MeshShader::InstancedObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, InverseViewMatrix); + setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + MeshShader::InstancedObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, InverseViewMatrix, 0); glBindVertexArray(mesh.vao_first_pass); glDrawElementsInstanced(ptype, count, itype, 0, instance_count); From c5fd99a09693e288fab8e49401991c255f0fbd29 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Mon, 7 Apr 2014 22:38:20 +0200 Subject: [PATCH 10/10] Clamp to edge when blurring fbo. --- src/graphics/post_processing.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index f1441087a..3fc43d50b 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -318,6 +318,8 @@ void PostProcessing::renderGaussian3Blur(GLuint in_fbo, GLuint in_tex, GLuint tm glUniform2f(FullScreenShader::Gaussian3VBlurShader::uniform_pixel, inv_width, inv_height); setTexture(0, in_tex, GL_LINEAR, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glUniform1i(FullScreenShader::Gaussian3VBlurShader::uniform_tex, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -330,6 +332,8 @@ void PostProcessing::renderGaussian3Blur(GLuint in_fbo, GLuint in_tex, GLuint tm glUniform2f(FullScreenShader::Gaussian3HBlurShader::uniform_pixel, inv_width, inv_height); setTexture(0, tmp_tex, GL_LINEAR, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glUniform1i(FullScreenShader::Gaussian3HBlurShader::uniform_tex, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -347,6 +351,8 @@ void PostProcessing::renderGaussian6Blur(GLuint in_fbo, GLuint in_tex, GLuint tm glUniform2f(FullScreenShader::Gaussian6VBlurShader::uniform_pixel, inv_width, inv_height); setTexture(0, in_tex, GL_LINEAR, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glUniform1i(FullScreenShader::Gaussian6VBlurShader::uniform_tex, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -359,6 +365,8 @@ void PostProcessing::renderGaussian6Blur(GLuint in_fbo, GLuint in_tex, GLuint tm glUniform2f(FullScreenShader::Gaussian6HBlurShader::uniform_pixel, inv_width, inv_height); setTexture(0, tmp_tex, GL_LINEAR, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glUniform1i(FullScreenShader::Gaussian6HBlurShader::uniform_tex, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);