From da2ac0047867d4a3fa9383236d8c61e1e05b256b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 11 Sep 2015 18:36:01 +0200 Subject: [PATCH] Shaders: ability to do alpha-masking with Phong. All Color3 parameters are now Color4, but the API should be backwards compatible as Color4 is implicitly convertible from Color3. --- src/Magnum/Shaders/Phong.cpp | 10 ++++----- src/Magnum/Shaders/Phong.frag | 39 +++++++++++++++------------------ src/Magnum/Shaders/Phong.h | 41 +++++++++++++++++++++++++---------- 3 files changed, 52 insertions(+), 38 deletions(-) diff --git a/src/Magnum/Shaders/Phong.cpp b/src/Magnum/Shaders/Phong.cpp index 4f76a9e44..61aa8a37e 100644 --- a/src/Magnum/Shaders/Phong.cpp +++ b/src/Magnum/Shaders/Phong.cpp @@ -113,13 +113,13 @@ 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 /* Default to fully opaque white so we can see the textures */ - if(flags & Flag::AmbientTexture) setAmbientColor(Vector3{1.0f}); - else setAmbientColor({}); + if(flags & Flag::AmbientTexture) setAmbientColor(Color4{1.0f}); + else setAmbientColor(Color4{0.0f, 1.0f}); - if(flags & Flag::DiffuseTexture) setDiffuseColor(Vector3{1.0f}); + if(flags & Flag::DiffuseTexture) setDiffuseColor(Color4{1.0f}); - setSpecularColor(Vector3(1.0f)); - setLightColor(Vector3(1.0f)); + setSpecularColor(Color4{1.0f}); + setLightColor(Color4{.0f}); setShininess(80.0f); #endif } diff --git a/src/Magnum/Shaders/Phong.frag b/src/Magnum/Shaders/Phong.frag index 3abae5a6d..cfd49b846 100644 --- a/src/Magnum/Shaders/Phong.frag +++ b/src/Magnum/Shaders/Phong.frag @@ -36,9 +36,9 @@ #ifdef EXPLICIT_UNIFORM_LOCATION layout(location = 7) #endif -uniform lowp vec3 lightColor +uniform lowp vec4 lightColor #ifndef GL_ES - = vec3(1.0, 1.0, 1.0) + = vec4(1.0) #endif ; @@ -61,12 +61,12 @@ uniform lowp sampler2D ambientTexture; #ifdef EXPLICIT_UNIFORM_LOCATION layout(location = 5) #endif -uniform lowp vec3 ambientColor +uniform lowp vec4 ambientColor #ifndef GL_ES #ifndef AMBIENT_TEXTURE - = vec3(0.0) + = vec4(0.0, 0.0, 0.0, 1.0) #else - = vec3(1.0) + = vec4(1.0) #endif #endif ; @@ -81,9 +81,9 @@ uniform lowp sampler2D diffuseTexture; #ifdef EXPLICIT_UNIFORM_LOCATION layout(location = 4) #endif -uniform lowp vec3 diffuseColor +uniform lowp vec4 diffuseColor #if !defined(GL_ES) && defined(DIFFUSE_TEXTURE) - = vec3(1.0) + = vec4(1.0) #endif ; @@ -97,9 +97,9 @@ uniform lowp sampler2D specularTexture; #ifdef EXPLICIT_UNIFORM_LOCATION layout(location = 6) #endif -uniform lowp vec3 specularColor +uniform lowp vec4 specularColor #ifndef GL_ES - = vec3(1.0, 1.0, 1.0) + = vec4(1.0) #endif ; @@ -116,39 +116,36 @@ out lowp vec4 color; #endif void main() { - lowp const vec3 finalAmbientColor = + lowp const vec4 finalAmbientColor = #ifdef AMBIENT_TEXTURE - texture(ambientTexture, interpolatedTextureCoords).xyz* + texture(ambientTexture, interpolatedTextureCoords)* #endif ambientColor; - lowp const vec3 finalDiffuseColor = + lowp const vec4 finalDiffuseColor = #ifdef DIFFUSE_TEXTURE - texture(diffuseTexture, interpolatedTextureCoords).xyz* + texture(diffuseTexture, interpolatedTextureCoords)* #endif diffuseColor; - lowp const vec3 finalSpecularColor = + lowp const vec4 finalSpecularColor = #ifdef SPECULAR_TEXTURE - texture(specularTexture, interpolatedTextureCoords).xyz* + texture(specularTexture, interpolatedTextureCoords)* #endif specularColor; /* Ambient color */ - color.rgb = finalAmbientColor; + color = 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 += finalDiffuseColor*lightColor*intensity; + color += 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 += finalSpecularColor*specularity; + color += finalSpecularColor*specularity; } - - /* Force alpha to 1 */ - color.a = 1.0; } diff --git a/src/Magnum/Shaders/Phong.h b/src/Magnum/Shaders/Phong.h index 4bfe6f7dc..9276cf5f4 100644 --- a/src/Magnum/Shaders/Phong.h +++ b/src/Magnum/Shaders/Phong.h @@ -81,7 +81,7 @@ Matrix4 transformationMatrix = Matrix4::translation(Vector3::zAxis(-5.0f)); Matrix4 projectionMatrix = Matrix4::perspectiveProjection(35.0_degf, 1.0f, 0.001f, 100.0f); Shaders::Phong shader; -shader.setDiffuseColor(Color3::fromHSV(216.0_degf, 0.85f, 1.0f)) +shader.setDiffuseColor(Color4::fromHSV(216.0_degf, 0.85f, 1.0f)) .setShininess(200.0f) .setLightPosition({5.0f, 5.0f, 7.0f}) .setTransformationMatrix(transformationMatrix) @@ -128,6 +128,22 @@ shader.setTextures(nullptr, &diffuseTexture, &specularTexture) mesh.draw(shader); @endcode +### Alpha-masked drawing + +For general alpha-masked drawing you need to provide ambient texture with alpha +channel and set alpha channel of diffuse/specular color to `0.0f` so only +ambient alpha will be taken into account. If you have diffuse texture combined +with the alpha mask, you can use that texture for both ambient and diffuse +part and then separate the alpha like this: +@code +Shaders::Phong shader{Shaders::Phong::AmbientTexture| + Shaders::Phong::DiffuseTexture}; +shader.setTextures(&diffuseAlphaTexture, &diffuseAlphaTexture, nullptr) + .setAmbientColor({0.0f, 0.0f, 0.0f, 1.0f}) + .setDiffuseColor(Color4{diffuseRgb, 0.0f}) + .setSpecularColor(Color4{specularRgb, 0.0f}); +@endcode + @see @ref shaders */ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram { @@ -187,11 +203,11 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram { * @return Reference to self (for method chaining) * * 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}`. + * `{1.0f, 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, 1.0f}`. * @see @ref setAmbientTexture() */ - Phong& setAmbientColor(const Color3& color) { + Phong& setAmbientColor(const Color4& color) { setUniform(ambientColorUniform, color); return *this; } @@ -210,11 +226,11 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram { * @return Reference to self (for method chaining) * * If @ref Flag::DiffuseTexture is set, default value is - * `{1.0f, 1.0f, 1.0f}` and the color will be multiplied with diffuse - * texture. + * `{1.0f, 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 Color4& color) { setUniform(diffuseColorUniform, color); return *this; } @@ -232,11 +248,12 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram { * @brief Set specular color * @return Reference to self (for method chaining) * - * Default value is `{1.0f, 1.0f, 1.0f}`. Color will be multiplied with - * specular texture if @ref Flag::SpecularTexture is set. + * Default value is `{1.0f, 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 Color4& color) { setUniform(specularColorUniform, color); return *this; } @@ -317,9 +334,9 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram { * @brief Set light color * @return Reference to self (for method chaining) * - * If not set, default value is `{1.0f, 1.0f, 1.0f}`. + * If not set, default value is `{1.0f, 1.0f, 1.0f, 1.0f}`. */ - Phong& setLightColor(const Color3& color) { + Phong& setLightColor(const Color4& color) { setUniform(lightColorUniform, color); return *this; }