Browse Source

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.
pull/107/head
Vladimír Vondruš 11 years ago
parent
commit
fc5ddeebbf
  1. 13
      src/Magnum/Shaders/Phong.cpp
  2. 121
      src/Magnum/Shaders/Phong.frag
  3. 53
      src/Magnum/Shaders/Phong.h

13
src/Magnum/Shaders/Phong.cpp

@ -94,9 +94,9 @@ Phong::Phong(const Flags flags): transformationMatrixUniform(0), projectionMatri
projectionMatrixUniform = uniformLocation("projectionMatrix"); projectionMatrixUniform = uniformLocation("projectionMatrix");
normalMatrixUniform = uniformLocation("normalMatrix"); normalMatrixUniform = uniformLocation("normalMatrix");
lightUniform = uniformLocation("light"); lightUniform = uniformLocation("light");
if(!(flags & Flag::AmbientTexture)) ambientColorUniform = uniformLocation("ambientColor"); ambientColorUniform = uniformLocation("ambientColor");
if(!(flags & Flag::DiffuseTexture)) diffuseColorUniform = uniformLocation("diffuseColor"); diffuseColorUniform = uniformLocation("diffuseColor");
if(!(flags & Flag::SpecularTexture)) specularColorUniform = uniformLocation("specularColor"); specularColorUniform = uniformLocation("specularColor");
lightColorUniform = uniformLocation("lightColor"); lightColorUniform = uniformLocation("lightColor");
shininessUniform = uniformLocation("shininess"); 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) */ /* Set defaults in OpenGL ES (for desktop they are set in shader code itself) */
#ifdef MAGNUM_TARGET_GLES #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)); setSpecularColor(Vector3(1.0f));
setLightColor(Vector3(1.0f)); setLightColor(Vector3(1.0f));
setShininess(80.0f); setShininess(80.0f);

121
src/Magnum/Shaders/Phong.frag

@ -33,68 +33,75 @@
#define const #define const
#endif #endif
#ifndef GL_ES
#ifdef EXPLICIT_UNIFORM_LOCATION #ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 7) uniform vec3 lightColor = vec3(1.0, 1.0, 1.0); layout(location = 7)
layout(location = 8) uniform float shininess = 80.0;
#else
uniform vec3 lightColor = vec3(1.0, 1.0, 1.0);
uniform float shininess = 80.0;
#endif #endif
#else uniform lowp vec3 lightColor
uniform lowp vec3 lightColor; #ifndef GL_ES
uniform mediump float shininess; = vec3(1.0, 1.0, 1.0)
#endif
;
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 8)
#endif #endif
uniform mediump float shininess
#ifndef GL_ES
= 80.0
#endif
;
#ifdef AMBIENT_TEXTURE #ifdef AMBIENT_TEXTURE
#ifdef EXPLICIT_TEXTURE_LAYER #ifdef EXPLICIT_TEXTURE_LAYER
layout(binding = 0) uniform sampler2D ambientTexture; layout(binding = 0)
#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;
#endif #endif
uniform lowp sampler2D ambientTexture;
#endif #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 DIFFUSE_TEXTURE
#ifdef EXPLICIT_TEXTURE_LAYER #ifdef EXPLICIT_TEXTURE_LAYER
layout(binding = 1) uniform sampler2D diffuseTexture; layout(binding = 1)
#else
uniform sampler2D diffuseTexture;
#endif #endif
#else uniform lowp sampler2D diffuseTexture;
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 4) uniform vec3 diffuseColor;
#else
uniform lowp vec3 diffuseColor;
#endif #endif
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 4)
#endif #endif
uniform lowp vec3 diffuseColor
#if !defined(GL_ES) && defined(DIFFUSE_TEXTURE)
= vec3(1.0)
#endif
;
#ifdef SPECULAR_TEXTURE #ifdef SPECULAR_TEXTURE
#ifdef EXPLICIT_TEXTURE_LAYER #ifdef EXPLICIT_TEXTURE_LAYER
layout(binding = 2) uniform sampler2D specularTexture; layout(binding = 2)
#else
uniform sampler2D specularTexture;
#endif #endif
#else uniform lowp sampler2D specularTexture;
#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;
#endif #endif
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 6)
#endif #endif
uniform lowp vec3 specularColor
#ifndef GL_ES
= vec3(1.0, 1.0, 1.0)
#endif
;
in mediump vec3 transformedNormal; in mediump vec3 transformedNormal;
in highp vec3 lightDirection; in highp vec3 lightDirection;
@ -109,31 +116,37 @@ out lowp vec4 color;
#endif #endif
void main() { void main() {
#ifdef AMBIENT_TEXTURE lowp const vec3 finalAmbientColor =
lowp const vec3 ambientColor = texture(ambientTexture, interpolatedTextureCoords).xyz; #ifdef AMBIENT_TEXTURE
#endif texture(ambientTexture, interpolatedTextureCoords).xyz*
#ifdef DIFFUSE_TEXTURE #endif
lowp const vec3 diffuseColor = texture(diffuseTexture, interpolatedTextureCoords).xyz; ambientColor;
#endif lowp const vec3 finalDiffuseColor =
#ifdef SPECULAR_TEXTURE #ifdef DIFFUSE_TEXTURE
lowp const vec3 specularColor = texture(specularTexture, interpolatedTextureCoords).xyz; texture(diffuseTexture, interpolatedTextureCoords).xyz*
#endif #endif
diffuseColor;
lowp const vec3 finalSpecularColor =
#ifdef SPECULAR_TEXTURE
texture(specularTexture, interpolatedTextureCoords).xyz*
#endif
specularColor;
/* Ambient color */ /* Ambient color */
color.rgb = ambientColor; color.rgb = 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 += diffuseColor*lightColor*intensity; color.rgb += 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 += specularColor*specularity; color.rgb += finalSpecularColor*specularity;
} }
/* Force alpha to 1 */ /* Force alpha to 1 */

53
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(), call at least @ref setTransformationMatrix(), @ref setNormalMatrix(),
@ref setProjectionMatrix(), @ref setDiffuseColor() and @ref setLightPosition(). @ref setProjectionMatrix(), @ref setDiffuseColor() and @ref setLightPosition().
If you want to use texture instead of color, you need to provide also If you want to use textures, you need to provide also @ref TextureCoordinates
@ref TextureCoordinates attribute. Pass appropriate flags to constructor and attribute. Pass appropriate @ref Flags to constructor and then at render time
then at render time don't forget to also call appropriate subset of don't forget to also call appropriate subset of @ref setAmbientTexture(),
@ref setAmbientTexture(), @ref setDiffuseTexture() and @ref setSpecularTexture(). @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 html shaders-phong.png
@image latex shaders-phong.png @image latex shaders-phong.png
@ -184,11 +186,15 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram {
* @brief Set ambient color * @brief Set ambient color
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* If not set, default value is `{0.0f, 0.0f, 0.0f}`. Has no effect if * If @ref Flag::AmbientTexture is set, default value is
* @ref Flag::AmbientTexture is set. * `{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() * @see @ref setAmbientTexture()
*/ */
Phong& setAmbientColor(const Color3& color); Phong& setAmbientColor(const Color3& color) {
setUniform(ambientColorUniform, color);
return *this;
}
/** /**
* @brief Set ambient texture * @brief Set ambient texture
@ -203,10 +209,15 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram {
* @brief Set diffuse color * @brief Set diffuse color
* @return Reference to self (for method chaining) * @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() * @see @ref setDiffuseTexture()
*/ */
Phong& setDiffuseColor(const Color3& color); Phong& setDiffuseColor(const Color3& color) {
setUniform(diffuseColorUniform, color);
return *this;
}
/** /**
* @brief Set diffuse texture * @brief Set diffuse texture
@ -221,11 +232,14 @@ 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)
* *
* If not set, default value is `{1.0f, 1.0f, 1.0f}`. Has no effect if * Default value is `{1.0f, 1.0f, 1.0f}`. Color will be multiplied with
* @ref Flag::SpecularTexture is set. * specular texture if @ref Flag::SpecularTexture is set.
* @see @ref setSpecularTexture() * @see @ref setSpecularTexture()
*/ */
Phong& setSpecularColor(const Color3& color); Phong& setSpecularColor(const Color3& color) {
setUniform(specularColorUniform, color);
return *this;
}
/** /**
* @brief Set specular texture * @brief Set specular texture
@ -326,21 +340,6 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram {
CORRADE_ENUMSET_OPERATORS(Phong::Flags) 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 #endif

Loading…
Cancel
Save