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");
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);

121
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 */

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(),
@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

Loading…
Cancel
Save