Browse Source

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.
pull/110/head
Vladimír Vondruš 11 years ago
parent
commit
da2ac00478
  1. 10
      src/Magnum/Shaders/Phong.cpp
  2. 39
      src/Magnum/Shaders/Phong.frag
  3. 41
      src/Magnum/Shaders/Phong.h

10
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) */ /* Set defaults in OpenGL ES (for desktop they are set in shader code itself) */
#ifdef MAGNUM_TARGET_GLES #ifdef MAGNUM_TARGET_GLES
/* Default to fully opaque white so we can see the textures */ /* Default to fully opaque white so we can see the textures */
if(flags & Flag::AmbientTexture) setAmbientColor(Vector3{1.0f}); if(flags & Flag::AmbientTexture) setAmbientColor(Color4{1.0f});
else setAmbientColor({}); 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)); setSpecularColor(Color4{1.0f});
setLightColor(Vector3(1.0f)); setLightColor(Color4{.0f});
setShininess(80.0f); setShininess(80.0f);
#endif #endif
} }

39
src/Magnum/Shaders/Phong.frag

@ -36,9 +36,9 @@
#ifdef EXPLICIT_UNIFORM_LOCATION #ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 7) layout(location = 7)
#endif #endif
uniform lowp vec3 lightColor uniform lowp vec4 lightColor
#ifndef GL_ES #ifndef GL_ES
= vec3(1.0, 1.0, 1.0) = vec4(1.0)
#endif #endif
; ;
@ -61,12 +61,12 @@ uniform lowp sampler2D ambientTexture;
#ifdef EXPLICIT_UNIFORM_LOCATION #ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 5) layout(location = 5)
#endif #endif
uniform lowp vec3 ambientColor uniform lowp vec4 ambientColor
#ifndef GL_ES #ifndef GL_ES
#ifndef AMBIENT_TEXTURE #ifndef AMBIENT_TEXTURE
= vec3(0.0) = vec4(0.0, 0.0, 0.0, 1.0)
#else #else
= vec3(1.0) = vec4(1.0)
#endif #endif
#endif #endif
; ;
@ -81,9 +81,9 @@ uniform lowp sampler2D diffuseTexture;
#ifdef EXPLICIT_UNIFORM_LOCATION #ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 4) layout(location = 4)
#endif #endif
uniform lowp vec3 diffuseColor uniform lowp vec4 diffuseColor
#if !defined(GL_ES) && defined(DIFFUSE_TEXTURE) #if !defined(GL_ES) && defined(DIFFUSE_TEXTURE)
= vec3(1.0) = vec4(1.0)
#endif #endif
; ;
@ -97,9 +97,9 @@ uniform lowp sampler2D specularTexture;
#ifdef EXPLICIT_UNIFORM_LOCATION #ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 6) layout(location = 6)
#endif #endif
uniform lowp vec3 specularColor uniform lowp vec4 specularColor
#ifndef GL_ES #ifndef GL_ES
= vec3(1.0, 1.0, 1.0) = vec4(1.0)
#endif #endif
; ;
@ -116,39 +116,36 @@ out lowp vec4 color;
#endif #endif
void main() { void main() {
lowp const vec3 finalAmbientColor = lowp const vec4 finalAmbientColor =
#ifdef AMBIENT_TEXTURE #ifdef AMBIENT_TEXTURE
texture(ambientTexture, interpolatedTextureCoords).xyz* texture(ambientTexture, interpolatedTextureCoords)*
#endif #endif
ambientColor; ambientColor;
lowp const vec3 finalDiffuseColor = lowp const vec4 finalDiffuseColor =
#ifdef DIFFUSE_TEXTURE #ifdef DIFFUSE_TEXTURE
texture(diffuseTexture, interpolatedTextureCoords).xyz* texture(diffuseTexture, interpolatedTextureCoords)*
#endif #endif
diffuseColor; diffuseColor;
lowp const vec3 finalSpecularColor = lowp const vec4 finalSpecularColor =
#ifdef SPECULAR_TEXTURE #ifdef SPECULAR_TEXTURE
texture(specularTexture, interpolatedTextureCoords).xyz* texture(specularTexture, interpolatedTextureCoords)*
#endif #endif
specularColor; specularColor;
/* Ambient color */ /* Ambient color */
color.rgb = finalAmbientColor; color = finalAmbientColor;
mediump vec3 normalizedTransformedNormal = normalize(transformedNormal); mediump vec3 normalizedTransformedNormal = normalize(transformedNormal);
highp vec3 normalizedLightDirection = normalize(lightDirection); highp vec3 normalizedLightDirection = normalize(lightDirection);
/* Add diffuse color */ /* Add diffuse color */
lowp float intensity = max(0.0, dot(normalizedTransformedNormal, normalizedLightDirection)); lowp float intensity = max(0.0, dot(normalizedTransformedNormal, normalizedLightDirection));
color.rgb += finalDiffuseColor*lightColor*intensity; color += finalDiffuseColor*lightColor*intensity;
/* Add specular color, if needed */ /* Add specular color, if needed */
if(intensity > 0.001) { if(intensity > 0.001) {
highp vec3 reflection = reflect(-normalizedLightDirection, normalizedTransformedNormal); highp vec3 reflection = reflect(-normalizedLightDirection, normalizedTransformedNormal);
mediump float specularity = pow(max(0.0, dot(normalize(cameraDirection), reflection)), shininess); 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;
} }

41
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); Matrix4 projectionMatrix = Matrix4::perspectiveProjection(35.0_degf, 1.0f, 0.001f, 100.0f);
Shaders::Phong shader; 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) .setShininess(200.0f)
.setLightPosition({5.0f, 5.0f, 7.0f}) .setLightPosition({5.0f, 5.0f, 7.0f})
.setTransformationMatrix(transformationMatrix) .setTransformationMatrix(transformationMatrix)
@ -128,6 +128,22 @@ shader.setTextures(nullptr, &diffuseTexture, &specularTexture)
mesh.draw(shader); mesh.draw(shader);
@endcode @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 @see @ref shaders
*/ */
class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram { 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) * @return Reference to self (for method chaining)
* *
* If @ref Flag::AmbientTexture is set, default value is * If @ref Flag::AmbientTexture is set, default value is
* `{1.0f, 1.0f, 1.0f}` and the color will be multiplied with ambient * `{1.0f, 1.0f, 1.0f, 1.0f}` and the color will be multiplied with
* texture, otherwise default value is `{0.0f, 0.0f, 0.0f}`. * ambient texture, otherwise default value is `{0.0f, 0.0f, 0.0f, 1.0f}`.
* @see @ref setAmbientTexture() * @see @ref setAmbientTexture()
*/ */
Phong& setAmbientColor(const Color3& color) { Phong& setAmbientColor(const Color4& color) {
setUniform(ambientColorUniform, color); setUniform(ambientColorUniform, color);
return *this; return *this;
} }
@ -210,11 +226,11 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram {
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* If @ref Flag::DiffuseTexture is set, default value is * If @ref Flag::DiffuseTexture is set, default value is
* `{1.0f, 1.0f, 1.0f}` and the color will be multiplied with diffuse * `{1.0f, 1.0f, 1.0f, 1.0f}` and the color will be multiplied with
* texture. * diffuse texture.
* @see @ref setDiffuseTexture() * @see @ref setDiffuseTexture()
*/ */
Phong& setDiffuseColor(const Color3& color) { Phong& setDiffuseColor(const Color4& color) {
setUniform(diffuseColorUniform, color); setUniform(diffuseColorUniform, color);
return *this; return *this;
} }
@ -232,11 +248,12 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram {
* @brief Set specular color * @brief Set specular color
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Default value is `{1.0f, 1.0f, 1.0f}`. Color will be multiplied with * Default value is `{1.0f, 1.0f, 1.0f, 1.0f}`. Color will be
* specular texture if @ref Flag::SpecularTexture is set. * multiplied with specular texture if @ref Flag::SpecularTexture is
* set.
* @see @ref setSpecularTexture() * @see @ref setSpecularTexture()
*/ */
Phong& setSpecularColor(const Color3& color) { Phong& setSpecularColor(const Color4& color) {
setUniform(specularColorUniform, color); setUniform(specularColorUniform, color);
return *this; return *this;
} }
@ -317,9 +334,9 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram {
* @brief Set light color * @brief Set light color
* @return Reference to self (for method chaining) * @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); setUniform(lightColorUniform, color);
return *this; return *this;
} }

Loading…
Cancel
Save