From fc5ddeebbff2542b51a52e58d0eeabed213293cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 6 Sep 2015 11:04:53 +0200 Subject: [PATCH] Shaders: ability to have both color and texture in Phong. Also probably fixed a few issues when compiling the shader on older GLSL (missing precision qualifiers). And less crazy preprocessor. --- src/Magnum/Shaders/Phong.cpp | 13 ++-- src/Magnum/Shaders/Phong.frag | 121 +++++++++++++++++++--------------- src/Magnum/Shaders/Phong.h | 53 ++++++++------- 3 files changed, 102 insertions(+), 85 deletions(-) diff --git a/src/Magnum/Shaders/Phong.cpp b/src/Magnum/Shaders/Phong.cpp index f665e93b9..4f76a9e44 100644 --- a/src/Magnum/Shaders/Phong.cpp +++ b/src/Magnum/Shaders/Phong.cpp @@ -94,9 +94,9 @@ Phong::Phong(const Flags flags): transformationMatrixUniform(0), projectionMatri projectionMatrixUniform = uniformLocation("projectionMatrix"); normalMatrixUniform = uniformLocation("normalMatrix"); lightUniform = uniformLocation("light"); - if(!(flags & Flag::AmbientTexture)) ambientColorUniform = uniformLocation("ambientColor"); - if(!(flags & Flag::DiffuseTexture)) diffuseColorUniform = uniformLocation("diffuseColor"); - if(!(flags & Flag::SpecularTexture)) specularColorUniform = uniformLocation("specularColor"); + ambientColorUniform = uniformLocation("ambientColor"); + diffuseColorUniform = uniformLocation("diffuseColor"); + specularColorUniform = uniformLocation("specularColor"); lightColorUniform = uniformLocation("lightColor"); shininessUniform = uniformLocation("shininess"); } @@ -112,7 +112,12 @@ Phong::Phong(const Flags flags): transformationMatrixUniform(0), projectionMatri /* Set defaults in OpenGL ES (for desktop they are set in shader code itself) */ #ifdef MAGNUM_TARGET_GLES - setAmbientColor({}); + /* Default to fully opaque white so we can see the textures */ + if(flags & Flag::AmbientTexture) setAmbientColor(Vector3{1.0f}); + else setAmbientColor({}); + + if(flags & Flag::DiffuseTexture) setDiffuseColor(Vector3{1.0f}); + setSpecularColor(Vector3(1.0f)); setLightColor(Vector3(1.0f)); setShininess(80.0f); diff --git a/src/Magnum/Shaders/Phong.frag b/src/Magnum/Shaders/Phong.frag index 30c70d195..3abae5a6d 100644 --- a/src/Magnum/Shaders/Phong.frag +++ b/src/Magnum/Shaders/Phong.frag @@ -33,68 +33,75 @@ #define const #endif -#ifndef GL_ES #ifdef EXPLICIT_UNIFORM_LOCATION -layout(location = 7) uniform vec3 lightColor = vec3(1.0, 1.0, 1.0); -layout(location = 8) uniform float shininess = 80.0; -#else -uniform vec3 lightColor = vec3(1.0, 1.0, 1.0); -uniform float shininess = 80.0; +layout(location = 7) #endif -#else -uniform lowp vec3 lightColor; -uniform mediump float shininess; +uniform lowp vec3 lightColor + #ifndef GL_ES + = vec3(1.0, 1.0, 1.0) + #endif + ; + +#ifdef EXPLICIT_UNIFORM_LOCATION +layout(location = 8) #endif +uniform mediump float shininess + #ifndef GL_ES + = 80.0 + #endif + ; #ifdef AMBIENT_TEXTURE #ifdef EXPLICIT_TEXTURE_LAYER -layout(binding = 0) uniform sampler2D ambientTexture; -#else -uniform sampler2D ambientTexture; -#endif -#else -#ifndef GL_ES -#ifdef EXPLICIT_UNIFORM_LOCATION -layout(location = 5) uniform vec3 ambientColor = vec3(0.0, 0.0, 0.0); -#else -uniform vec3 ambientColor = vec3(0.0, 0.0, 0.0); -#endif -#else -uniform lowp vec3 ambientColor; +layout(binding = 0) #endif +uniform lowp sampler2D ambientTexture; #endif +#ifdef EXPLICIT_UNIFORM_LOCATION +layout(location = 5) +#endif +uniform lowp vec3 ambientColor + #ifndef GL_ES + #ifndef AMBIENT_TEXTURE + = vec3(0.0) + #else + = vec3(1.0) + #endif + #endif + ; + #ifdef DIFFUSE_TEXTURE #ifdef EXPLICIT_TEXTURE_LAYER -layout(binding = 1) uniform sampler2D diffuseTexture; -#else -uniform sampler2D diffuseTexture; +layout(binding = 1) #endif -#else -#ifdef EXPLICIT_UNIFORM_LOCATION -layout(location = 4) uniform vec3 diffuseColor; -#else -uniform lowp vec3 diffuseColor; +uniform lowp sampler2D diffuseTexture; #endif + +#ifdef EXPLICIT_UNIFORM_LOCATION +layout(location = 4) #endif +uniform lowp vec3 diffuseColor + #if !defined(GL_ES) && defined(DIFFUSE_TEXTURE) + = vec3(1.0) + #endif + ; #ifdef SPECULAR_TEXTURE #ifdef EXPLICIT_TEXTURE_LAYER -layout(binding = 2) uniform sampler2D specularTexture; -#else -uniform sampler2D specularTexture; +layout(binding = 2) #endif -#else -#ifndef GL_ES -#ifdef EXPLICIT_UNIFORM_LOCATION -layout(location = 6) uniform vec3 specularColor = vec3(1.0, 1.0, 1.0); -#else -uniform vec3 specularColor = vec3(1.0, 1.0, 1.0); -#endif -#else -uniform lowp vec3 specularColor; +uniform lowp sampler2D specularTexture; #endif + +#ifdef EXPLICIT_UNIFORM_LOCATION +layout(location = 6) #endif +uniform lowp vec3 specularColor + #ifndef GL_ES + = vec3(1.0, 1.0, 1.0) + #endif + ; in mediump vec3 transformedNormal; in highp vec3 lightDirection; @@ -109,31 +116,37 @@ out lowp vec4 color; #endif void main() { - #ifdef AMBIENT_TEXTURE - lowp const vec3 ambientColor = texture(ambientTexture, interpolatedTextureCoords).xyz; - #endif - #ifdef DIFFUSE_TEXTURE - lowp const vec3 diffuseColor = texture(diffuseTexture, interpolatedTextureCoords).xyz; - #endif - #ifdef SPECULAR_TEXTURE - lowp const vec3 specularColor = texture(specularTexture, interpolatedTextureCoords).xyz; - #endif + lowp const vec3 finalAmbientColor = + #ifdef AMBIENT_TEXTURE + texture(ambientTexture, interpolatedTextureCoords).xyz* + #endif + ambientColor; + lowp const vec3 finalDiffuseColor = + #ifdef DIFFUSE_TEXTURE + texture(diffuseTexture, interpolatedTextureCoords).xyz* + #endif + diffuseColor; + lowp const vec3 finalSpecularColor = + #ifdef SPECULAR_TEXTURE + texture(specularTexture, interpolatedTextureCoords).xyz* + #endif + specularColor; /* Ambient color */ - color.rgb = ambientColor; + color.rgb = finalAmbientColor; mediump vec3 normalizedTransformedNormal = normalize(transformedNormal); highp vec3 normalizedLightDirection = normalize(lightDirection); /* Add diffuse color */ lowp float intensity = max(0.0, dot(normalizedTransformedNormal, normalizedLightDirection)); - color.rgb += diffuseColor*lightColor*intensity; + color.rgb += finalDiffuseColor*lightColor*intensity; /* Add specular color, if needed */ if(intensity > 0.001) { highp vec3 reflection = reflect(-normalizedLightDirection, normalizedTransformedNormal); mediump float specularity = pow(max(0.0, dot(normalize(cameraDirection), reflection)), shininess); - color.rgb += specularColor*specularity; + color.rgb += finalSpecularColor*specularity; } /* Force alpha to 1 */ diff --git a/src/Magnum/Shaders/Phong.h b/src/Magnum/Shaders/Phong.h index 170ff122d..4bfe6f7dc 100644 --- a/src/Magnum/Shaders/Phong.h +++ b/src/Magnum/Shaders/Phong.h @@ -44,10 +44,12 @@ to provide @ref Position and @ref Normal attributes in your triangle mesh and call at least @ref setTransformationMatrix(), @ref setNormalMatrix(), @ref setProjectionMatrix(), @ref setDiffuseColor() and @ref setLightPosition(). -If you want to use texture instead of color, you need to provide also -@ref TextureCoordinates attribute. Pass appropriate flags to constructor and -then at render time don't forget to also call appropriate subset of -@ref setAmbientTexture(), @ref setDiffuseTexture() and @ref setSpecularTexture(). +If you want to use textures, you need to provide also @ref TextureCoordinates +attribute. Pass appropriate @ref Flags to constructor and then at render time +don't forget to also call appropriate subset of @ref setAmbientTexture(), +@ref setDiffuseTexture() and @ref setSpecularTexture(). The texture is +multipled by the color, which is by default set to fully opaque white for +enabled textures. @image html shaders-phong.png @image latex shaders-phong.png @@ -184,11 +186,15 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram { * @brief Set ambient color * @return Reference to self (for method chaining) * - * If not set, default value is `{0.0f, 0.0f, 0.0f}`. Has no effect if - * @ref Flag::AmbientTexture is set. + * If @ref Flag::AmbientTexture is set, default value is + * `{1.0f, 1.0f, 1.0f}` and the color will be multiplied with ambient + * texture, otherwise default value is `{0.0f, 0.0f, 0.0f}`. * @see @ref setAmbientTexture() */ - Phong& setAmbientColor(const Color3& color); + Phong& setAmbientColor(const Color3& color) { + setUniform(ambientColorUniform, color); + return *this; + } /** * @brief Set ambient texture @@ -203,10 +209,15 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram { * @brief Set diffuse color * @return Reference to self (for method chaining) * - * Has no effect if @ref Flag::DiffuseTexture is used. + * If @ref Flag::DiffuseTexture is set, default value is + * `{1.0f, 1.0f, 1.0f}` and the color will be multiplied with diffuse + * texture. * @see @ref setDiffuseTexture() */ - Phong& setDiffuseColor(const Color3& color); + Phong& setDiffuseColor(const Color3& color) { + setUniform(diffuseColorUniform, color); + return *this; + } /** * @brief Set diffuse texture @@ -221,11 +232,14 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram { * @brief Set specular color * @return Reference to self (for method chaining) * - * If not set, default value is `{1.0f, 1.0f, 1.0f}`. Has no effect if - * @ref Flag::SpecularTexture is set. + * Default value is `{1.0f, 1.0f, 1.0f}`. Color will be multiplied with + * specular texture if @ref Flag::SpecularTexture is set. * @see @ref setSpecularTexture() */ - Phong& setSpecularColor(const Color3& color); + Phong& setSpecularColor(const Color3& color) { + setUniform(specularColorUniform, color); + return *this; + } /** * @brief Set specular texture @@ -326,21 +340,6 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram { CORRADE_ENUMSET_OPERATORS(Phong::Flags) -inline Phong& Phong::setAmbientColor(const Color3& color) { - if(!(_flags & Flag::AmbientTexture)) setUniform(ambientColorUniform, color); - return *this; -} - -inline Phong& Phong::setDiffuseColor(const Color3& color) { - if(!(_flags & Flag::DiffuseTexture)) setUniform(diffuseColorUniform, color); - return *this; -} - -inline Phong& Phong::setSpecularColor(const Color3& color) { - if(!(_flags & Flag::SpecularTexture)) setUniform(specularColorUniform, color); - return *this; -} - }} #endif