I am developing a small OpenGL engine and currently stuck at the following GLSL problem:
I am trying to implement a shader for multiple lights and it generates the correct result but only if I put the calculation of the diffuse light inside an (completely useless) if statement. The specultar light component is always correctly rendered.
Works:
for( int i = 0; i < uNumLights; ++i ) {
//...
if( <anything> == <something> ) {
lDiffuseLight += vAmbientDiffuseMaterial * uLights[i].color * lIntensity;
}
}
Does not work:
for( int i = 0; i < uNumLights; ++i ) {
//...
lDiffuseLight += vAmbientDiffuseMaterial * uLights[i].color * lIntensity;
}
Furthermore it has no effect if I use a constant instead of an uniform for the loop condition.
Why does the code with the if work and without the if not? How can I make my shader work without silly if statements?
The full shader code:
The Vertex Shader:
#version 330
const int MAX_LIGHTS = 4;
in vec3 iVertex;
in vec3 iNormals;
uniform mat4 uModelView;
uniform mat4 uMVP;
uniform mat3 uNormal;
smooth out vec3 vPosition;
smooth out vec3 vModelView;
smooth out vec3 vNormals;
// Colors...
smooth out vec3 vAmbientDiffuseMaterial; // Make some colors...
smooth out vec3 vAmbientLight;
smooth out vec3 vLightDirection[MAX_LIGHTS];
uniform vec3 uAmbientColor;
uniform int uNumLights;
uniform struct Light {
vec3 color;
vec3 position;
} uLights[MAX_LIGHTS];
void main(void) {
vAmbientDiffuseMaterial = clamp(iVertex, 0.0, 1.0);
vAmbientLight = vAmbientDiffuseMaterial * uAmbientColor;
gl_Position = uMVP * vec4( iVertex.xyz, 1.0 );
vPosition = gl_Position.xyz;
vNormals = normalize( uNormal * iNormals );
vModelView = ( uModelView * vec4( iVertex , 1 )).xyz;
for( int i = 0; i < uNumLights; ++i ) {
vLightDirection[i] = normalize( uLights[i].position - vModelView );
}
}
The fragment shader:
#version 330
const int MAX_LIGHTS = 4;
uniform mat4 uModelView;
out vec4 oFinalColor;
smooth in vec3 vPosition;
smooth in vec3 vModelView;
smooth in vec3 vNormals;
smooth in vec3 vAmbientDiffuseMaterial;
smooth in vec3 vAmbientLight;
smooth in vec3 vLightDirection[MAX_LIGHTS];
// Light stuff
uniform int uNumLights;
uniform struct Light {
vec3 color;
vec3 position;
} uLights[MAX_LIGHTS];
const vec3 cSpecularMaterial = vec3( 0.9, 0.9, 0.9 );
const float cShininess = 30.0;
void main(void) {
vec3 lReflection, lSpecularLight = vec3( 0 ), lDiffuseLight = vec3( 0 );
float lIntensity;
// Specular Light
for( int i = 0; i < uNumLights; ++i ) {
lReflection = normalize( reflect( -vLightDirection[i], vNormals) );
lIntensity = max( 0.0, dot( -normalize(vModelView), lReflection ) );
lSpecularLight += cSpecularMaterial * uLights[i].color * pow( lIntensity, cShininess );
// Diffuse Light
lIntensity = max( 0, dot( vNormals, vLightDirection[i] ) );
// Here is the strange if part:
// Only with the if lDiffuseLight is what it is supposed to be.
if( uLights[i].color != vec3( 0, 0, 0 ) ) {
lDiffuseLight += vAmbientDiffuseMaterial * uLights[i].color * lIntensity;
}
}
oFinalColor = vec4( vAmbientLight + lDiffuseLight + lSpecularLight, 1 );
}
I have tested all uniforms and they are all correct set in the shader.
Related
I need to flip my textures upside-down in shaders before applying perspective transformations. I modified vertTexCoord in vert.glsl, but I don't know where to use it in swap.glsl. The way to do it like
gl_FragColor = texture2D(texture, vertTexCoord );
does not work, because I also need the texture to be modified in perspective.
vert.glsl:
#define PROCESSING_COLOR_SHADER
uniform mat4 transform;
uniform mat4 texMatrix;
attribute vec4 vertex;
attribute vec4 color;
attribute vec2 texCoord;
varying vec4 vertColor;
varying vec4 vertTexCoord;
void main() {
gl_Position = transform * vertex;
vertColor = color;
vertTexCoord = texMatrix * vec4(texCoord, 1.0, 1.0);
}
swap.glsl:
#ifdef GL_ES
precision highp float;
#endif
// General parameters
uniform sampler2D from;
uniform sampler2D to;
uniform float progress;
uniform vec2 resolution;
uniform float reflection;
uniform float perspective;
uniform float depth;
varying vec4 vertColor;
varying vec4 vertTexCoord;
const vec4 black = vec4(0.0, 0.0, 0.0, 1.0);
const vec2 boundMin = vec2(0.0, 0.0);
const vec2 boundMax = vec2(1.0, 1.0);
bool inBounds (vec2 p) {
return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));
}
vec2 project (vec2 p) {
return p * vec2(1.0, -1.2) + vec2(0.0, -0.02);
}
vec4 bgColor (vec2 p, vec2 pfr, vec2 pto) {
vec4 c = black;
pfr = project(pfr);
if (inBounds(pfr)) {
c += mix(black, texture2D(from, pfr), reflection * mix(1.0, 0.0, pfr.y));
}
pto = project(pto);
if (inBounds(pto)) {
c += mix(black, texture2D(to, pto), reflection * mix(1.0, 0.0, pto.y));
}
return c;
}
void main() {
vec2 p = gl_FragCoord.xy / resolution.xy;
vec2 pfr, pto = vec2(-1.);
float size = mix(1.0, depth, progress);
float persp = perspective * progress;
pfr = (p + vec2(-0.0, -0.5)) * vec2(size/(1.0-perspective*progress), size/(1.0-size*persp*p.x)) + vec2(0.0, 0.5);
size = mix(1.0, depth, 1.-progress);
persp = perspective * (1.-progress);
pto = (p + vec2(-1.0, -0.5)) * vec2(size/(1.0-perspective*(1.0-progress)), size/(1.0-size*persp*(0.5-p.x))) + vec2(1.0, 0.5);
bool fromOver = progress < 0.5;
if (fromOver) {
if (inBounds(pfr)) {
gl_FragColor = texture2D(from, pfr);
}
else if (inBounds(pto)) {
gl_FragColor = texture2D(to, pto);
}
else {
gl_FragColor = bgColor(p, pfr, pto);
}
}
else {
if (inBounds(pto)) {
gl_FragColor = texture2D(to, pto);
}
else if (inBounds(pfr)) {
gl_FragColor = texture2D(from, pfr);
}
else {
gl_FragColor = bgColor(p, pfr, pto);
}
}
}
You sample the texture at
(u,v)
If you want to flip the Y-axis, just sample at
(u, 1.0f -v)
So your updated main will look like:
void main() {
gl_Position = transform * vertex;
vertColor = color;
newTCoord = texCoord;
newTCoord.y = 1.0 - newTCoord.y;
vertTexCoord = vec4(newTCoord, 1.0, 1.0);
}
the problem is that i pass few lights to the shader but it showing shadow only for the first one.
the lighting applied also for the lights that their shadows are not seen.
i checked the shadow maps and they being passed correctly.
the fragment shader:
#version 420 compatibility
#define MAX_LIGHTS 8
struct lightSource
{
vec4 position;
vec4 diffuse;
vec4 specular;
float constantAttenuation, linearAttenuation, quadraticAttenuation;
float spotCutoff, spotExponent, intensity;
vec3 spotDirection;
sampler2D TexShadow;
samplerCube TexShadowPoint;
};
struct material
{
vec4 ambient;
vec4 diffuse;
vec4 specular;
float shininess;
};
uniform material frontMaterial;
uniform lightSource lights[MAX_LIGHTS];
uniform int numberOfLights;
uniform vec4 scene_ambient;
uniform mat4 inversedViewMatrix;
uniform sampler2D Tex;
uniform sampler2D TexNorm;
in vec4 position; // position of the vertex (and fragment) in world space
in vec3 varyingNormalDirection; // surface normal vector in world space
in vec2 ex_UV;
in vec4 ShadowCoords[MAX_LIGHTS];
vec2 poissonDisk[16] = vec2[](
vec2( -0.94201624, -0.39906216 ), vec2( 0.94558609, -0.76890725 ),
vec2( -0.094184101, -0.92938870 ), vec2( 0.34495938, 0.29387760 ),
vec2( -0.91588581, 0.45771432 ), vec2( -0.81544232, -0.87912464 ),
vec2( -0.38277543, 0.27676845 ), vec2( 0.97484398, 0.75648379 ),
vec2( 0.44323325, -0.97511554 ), vec2( 0.53742981, -0.47373420 ),
vec2( -0.26496911, -0.41893023 ), vec2( 0.79197514, 0.19090188 ),
vec2( -0.24188840, 0.99706507 ), vec2( -0.81409955, 0.91437590 ),
vec2( 0.19984126, 0.78641367 ), vec2( 0.14383161, -0.14100790 )
);
float rand(vec2 co)
{
return fract(sin(dot(co, vec2(12.9898, 78.233)) * 43758.5453));
}
float linstep(float low, float high, float v)
{
return clamp((v-low)/(high-low), 0.0, 1.0);
}
float VSM(sampler2D depths, vec2 uv, float compare)
{
vec2 moments = texture2D(depths, uv).xy;
float p = smoothstep(compare - 0.02, compare, moments.x);
float variance = max(moments.y - moments.x*moments.x, -0.001);
float d = compare - moments.x;
float p_max;
p_max = linstep(0.6, 1.0, variance / (variance + d*d));
return clamp(max(p, p_max), 0.0, 1.0) / 2;
}
void main(void)
{
vec3 normalDirection;
//sample the normal map and covert from 0:1 range to -1:1 range
if (texture2D(TexNorm, ex_UV).rgb != vec3(0.0, 0.0, 0.0))
{
vec3 mapped_Normals = texture2D(TexNorm, ex_UV).rgb * 2.0 - 1.0;
normalDirection = normalize(mapped_Normals); //normal mapped normals
}
else
normalDirection = normalize(varyingNormalDirection);
vec4 texColor = texture2D(Tex, ex_UV);// usual processing of texture coordinates
vec3 viewDirection = normalize(vec3(inversedViewMatrix * vec4(0.0, 0.0, 0.0, 1.0) - position));
vec3 lightDirection;
float attenuation;
//initialize total lighting with ambient lighting
vec3 totalAmbientDiffuse = vec3(scene_ambient) * vec3(frontMaterial.ambient);
vec3 totalSpecular;
for (int index = 0; index < numberOfLights; index++) // for all light sources
{
float Visibility;
if (lights[index].position.w == 0.0) // directional light
{
attenuation = 1.0; // no attenuation
lightDirection = normalize(vec3(lights[index].position));
//int num = int(rand(position.xyz) * 16);
Visibility = VSM(lights[index].TexShadow, ShadowCoords[index].xy + poissonDisk[int(rand(position.xy + vec2(position.z,-position.z)) * 16)] /2000, ShadowCoords[index].z);
}
else // point light or spotlight (or other kind of light)
{
vec3 positionToLightSource = vec3(lights[index].position - position);
float Distance = length(positionToLightSource);
lightDirection = normalize(positionToLightSource);
attenuation = 1.0 / (lights[index].constantAttenuation + lights[index].linearAttenuation * Distance + lights[index].quadraticAttenuation * Distance * Distance);
if (lights[index].spotCutoff <= 90.0) // spotlight
{
Visibility = VSM(lights[index].TexShadow, ShadowCoords[index].xy / ShadowCoords[index].w + poissonDisk[int(rand(position.xy + vec2(position.z,-position.z)) * 16)] / 700, ShadowCoords[index].z / ShadowCoords[index].w);
float clampedCosine = max(0.0, dot(-lightDirection, normalize(lights[index].spotDirection)));
if (clampedCosine < cos(radians(lights[index].spotCutoff))) // outside of spotlight cone
{
attenuation = 0.0;
}
else
{
attenuation = attenuation * pow(clampedCosine, lights[index].spotExponent);
}
}
else // point light
{
//point light shadow calculations
}
}
vec3 diffuseReflection = attenuation * vec3(lights[index].diffuse) * vec3(frontMaterial.diffuse) * max(0.0, dot(normalDirection, lightDirection));
vec3 specularReflection;
if (dot(normalDirection, lightDirection) < 0.0) // light source on the wrong side
{
specularReflection = vec3(0.0, 0.0, 0.0); // no specular reflection
}
else // light source on the right side
{
specularReflection = attenuation * vec3(lights[index].specular) * vec3(frontMaterial.specular)
* pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), frontMaterial.shininess);
}
totalAmbientDiffuse += diffuseReflection * lights[index].intensity * Visibility;
totalSpecular += specularReflection * lights[index].intensity * Visibility;
}
gl_FragColor = vec4(totalAmbientDiffuse, 1.0) * texColor + vec4(totalSpecular, 1.0);
}
I'm searching for a way to interpolate / smooth a texture which is red from a texture atlas.
That problem is that if i set the MIN_FILTER to GL_LINEAR i'll get bleeding at the edges. (the pixel of the next texture are used for interpolation)
I tried solving this by writing a shader which does the interpolation manually but to detect which pixels it has to ignore, the shader has to know the texCoords of the vertices so that it can calculate if the pixel used is in or outside of the triangle. To get the texCoords into the shader i tried to use uniform but i use DisplayLists (i considered switching to VBOs, but my first implemetation used them and it was extremly slow) which makes it very complicated.
How can i smooth my textures without bleeding?
Another problem is that the method that checks if a point is in a triangle doesn't seem to work.
Vertex Shader:
#version 130
void main()
{
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
gl_FrontColor = gl_Color;
gl_Position = ftransform();
}
Fragement Shader:
#version 130
uniform sampler2D tex;
uniform vec2 texCoord[4];
float textureSize;
float texelSize;
bool pointInTriangle(vec3 P, vec3 A, vec3 B, vec3 C)
{
vec3 u = B - A;
vec3 v = C - A;
vec3 w = P - A;
vec3 vCrossW = cross(v, w);
vec3 vCrossU = cross(v, u);
if(dot(vCrossW, vCrossU) < 0)
{
return false;
}
vec3 uCrossW = cross(u, w);
vec3 uCrossV = cross(u, v);
if(dot(uCrossW, uCrossV) < 0)
{
return false;
}
float denom = length(uCrossV);
float r = length(vCrossW);
float t = length(uCrossW);
return (r + t <= 1);
}
vec4 texture2DBilinear(sampler2D textureSampler, vec2 uv)
{
vec4 tl = texture2D(textureSampler, uv);
vec4 tr = texture2D(textureSampler, uv + vec2(texelSize, 0));
vec4 bl = texture2D(textureSampler, uv + vec2(0, texelSize));
vec4 br = texture2D(textureSampler, uv + vec2(texelSize , texelSize));
vec2 f = fract( uv.xy * textureSize );
vec4 tA = mix( tl, tr, f.x );
vec4 tB = mix( bl, br, f.x );
return mix( tA, tB, f.y );
}
void main()
{
ivec2 textureSize2d = textureSize(tex,0);
textureSize = float(textureSize2d.x);
texelSize = 1.0 / textureSize;
//texture coordinate:
vec2 texCoord = (gl_TexCoord[0].st);
//vec4 color = texture2D(tex,gl_TexCoord[0].st);
gl_FragColor = texture2DBilinear(tex, texCoord) * gl_Color;
//TEST IF METHOD WORKS
if(pointInTriangle(vec3(1,1,0),vec3(0,0,0),vec3(3,0,0),vec3(0,3,0)))
{
//pointInTriangle DOES NOT WORK!
gl_FragColor = gl_Color;
}
}
Can someone please help me review my glsl shader program. The Issue I am having is that despite the location of the light, the far edges of my mesh is black when it should not be.
To help illustrate, i provide this picture (Note the red,green, blue with white dot is the light position):
VertexShader:
#version 330
struct Matrix {
mat4 mvp;
mat4 mv;
mat4 view;
mat4 projection;
};
struct Light {
vec3 position; //Supplied in eye space(camera view )
vec3 color;
vec3 direction;
float intensity;
vec3 ambient;
};
attribute vec3 inputPosition;
attribute vec3 inputNormal;
attribute vec2 inputTexture;
attribute ivec2 number_influence;
attribute ivec4 boneIDs;
attribute vec4 boneWeights;
//--------------------------------------------
// UNIFORM:INPUT Supplied Data from C++ application
//--------------------------------------------
uniform Matrix matrix;
uniform Light light;
uniform vec3 cameraPosition; //position of viewer
// Bone deformation matrices
uniform mat4 boneFinalMatrix [30];
uniform mat4 boneInvBindPosition[30];
uniform mat4 boneTranslation [30];
//Output Variables
out vec3 oFragNormal;
out vec2 oTexCoord;
out vec3 oFragPosition;
void main() {
mat3 Normal_Matrix = mat3( transpose(inverse(matrix.view)) );
//PLACE HOLDER
vec4 INPUT= vec4(inputPosition , 1.0);
vec4 vertex= vec4(0.0,0.0,0.0,0.0);
vec3 normal= vec3(0.0,0.0,0.0);
int id = 0;
mat4 im;
vec4 O;
float weight;
mat4 locTrans;
mat4 invMatrix;
mat4 transform;
mat4 iBindMatrix;
mat4 FinalTranform;
mat4 Ttrans;
for( int i = 0; i < number_influence.x; i++ ){
id = boneIDs[i];
weight = boneWeights[id];
if(weight <= 0.0) weight = 1.0;
invMatrix = boneInvBindPosition[id];
locTrans = boneTranslation[id];
transform = boneFinalMatrix[id] ;
FinalTranform += transform * weight;
iBindMatrix+= (invMatrix)*weight;
Ttrans += locTrans * weight;
}
vertex = ( FinalTranform )* ( iBindMatrix * (INPUT )) ;
normal = mat3(FinalTranform) * mat3(iBindMatrix) * inputNormal ;
// output the transformed vertex
gl_Position = matrix.projection * matrix.view * vertex;
oFragPosition = vec3(matrix.view * vertex);
oFragNormal = Normal_Matrix * normal;
//store the texture data
oTexCoord = inputTexture.xy;
}
FragmentShader
#version 330
const vec4 AMBIENT = vec4(0.452, 0.452, 0.479, 1.0); //0.2 for all component is a good dark value
struct Light {
vec3 position;
vec3 diffuse;
vec3 direction;
float specularExponent;
vec3 ambient;
vec3 specular;
};
//the image
uniform sampler2D textureSampler;
uniform sampler2D normalSampler;
uniform vec3 cameraPosition;
uniform vec3 materialDiffuse;
uniform vec3 materialSpecular;
uniform Light light[10];
uniform int numberLights;
out vec4 finalOutput;
in vec2 oTexCoord;
in vec3 oFragNormal;
in vec3 oFragPosition;
void main() {
int i=0;
vec3 N = normalize( oFragNormal );
//V = frag to viewier vector
vec3 V = normalize( cameraPosition - oFragPosition );
vec4 texColor = texture2D(textureSampler, oTexCoord);
vec3 mDiffuse = vec3(0.0);
vec3 mSpecular = vec3(0.0);
float N_dot_L = 0.0;
float N_dot_H = 0.0;
vec3 L;
vec3 H;
for( i= 0; i < numberLights; i++){
L = normalize( oFragPosition - light[i].position );
//Diffuse: CmaterialDiffuseColor = max( Normal * LightDir, 0) * CmaterialColor * ClightColor
N_dot_L = max ( dot ( N, L), 0.0 ) ;
mDiffuse += materialDiffuse * light[i].diffuse * N_dot_L ;
//Specular: CmaterialSpecularColor = max(Normal * HalfAngleLightandViewVector, 0) ^ exp * CmaterialColor * ClightColor
H = normalize( (L + V)/2.0 );
N_dot_H = max( dot ( N , H ), 0.0 ) ;
mSpecular += materialSpecular * light[i].specular * vec3(pow(N_dot_H, light[i].specularExponent) );
}
finalOutput = texColor * vec4(mDiffuse,1.0 ) ;
finalOutput.a=1.0;
}
I found the solution to my problem: in the vertex shader I was transforming the vertex position and normal using my cameras view matrix. I removed it and now all works well.
Vertex Shader:
#version 330
struct Matrix {
mat4 mvp;
mat4 mv;
mat4 view;
mat4 projection;
};
struct Light {
vec3 position; //Supplied in eye space(camera view )
vec3 color;
vec3 direction;
float intensity;
vec3 ambient;
};
attribute vec3 inputPosition;
attribute vec3 inputNormal;
attribute vec2 inputTexture;
attribute ivec2 number_influence;
attribute ivec4 boneIDs;
attribute vec4 boneWeights;
//--------------------------------------------
// UNIFORM:INPUT Supplied Data from C++ application
//--------------------------------------------
uniform Matrix matrix;
uniform Light light;
uniform vec3 cameraPosition; //position of viewer
// Bone deformation matrices
uniform mat4 boneFinalMatrix [30];
uniform mat4 boneInvBindPosition[30];
uniform mat4 boneTranslation [30];
//Output Variables
out vec3 oFragNormal;
out vec2 oTexCoord;
out vec3 oFragPosition;
void main() {
//PLACE HOLDER
vec4 vertex= vec4(0.0,0.0,0.0,0.0);
vec3 normal= vec3(0.0,0.0,0.0);
int id = 0;
mat4 im;
vec4 O;
float weight;
mat4 locTrans;
mat4 invMatrix;
mat4 transform;
mat4 iBindMatrix;
mat4 FinalTranform;
mat4 Ttrans;
for( int i = 0; i < number_influence.x; i++ ){
id = boneIDs[i];
weight = boneWeights[id];
if(weight <= 0.0) weight = 1.0;
invMatrix = boneInvBindPosition[id];
locTrans = boneTranslation[id];
transform = boneFinalMatrix[id] ;
FinalTranform += transform * weight;
iBindMatrix+= (invMatrix)*weight;
Ttrans += locTrans * weight;
}
mat4 BoneFinal = ( FinalTranform )* ( iBindMatrix );
vertex = BoneFinal * vec4(inputPosition , 1.0) ;
mat3 transInvView = mat3( transpose(inverse(matrix.view )) );
mat3 transInvBone = mat3( transpose ( inverse (BoneFinal)) );
normal = vec3( normalize ( BoneFinal * vec4(inputNormal,0.0) ) );
mat3 Normal_Matrix = mat3( transpose(inverse(matrix.view )) );
// output the transformed vertex
gl_Position = matrix.projection * matrix.view * vertex;
oFragPosition = vec3( vertex);
oFragNormal = normal;
//store the texture data
oTexCoord = inputTexture.xy;
}
Fragment Shader:
#version 330
const vec4 AMBIENT = vec4(0.452, 0.452, 0.479, 1.0); //0.2 for all component is a good dark value
struct Light {
vec3 position;
vec3 diffuse;
vec3 direction;
float specularExponent;
vec3 ambient;
vec3 specular;
};
//the image
uniform sampler2D textureSampler;
uniform sampler2D normalSampler;
uniform vec3 cameraPosition;
uniform vec3 materialDiffuse;
uniform vec3 materialSpecular;
uniform vec3 materialAmbient;
uniform Light light[10];
uniform int numberLights;
out vec4 finalOutput;
in vec2 oTexCoord;
in vec3 oFragNormal;
in vec3 oFragPosition;
void main() {
int i=0;
vec3 N = normalize( oFragNormal );
//V = frag to viewier vector
vec3 V = normalize( vec3(0.0) - oFragPosition );
vec4 texColor = texture2D(textureSampler, oTexCoord);
vec3 mAmbient = vec3(0.0);
vec3 mDiffuse = vec3(0.0);
vec3 mSpecular = vec3(0.0);
float N_dot_L = 0.0;
float N_dot_H = 0.0;
vec3 L;
vec3 H;
for( i= 0; i < numberLights; i++){
L = normalize( oFragPosition - light[i].position );
mAmbient = materialAmbient * light[i].ambient;
//Diffuse: CmaterialDiffuseColor = max( Normal * LightDir, 0) * CmaterialColor * ClightColor
N_dot_L = max ( dot ( N, L), 0.0 ) ;
mDiffuse += materialDiffuse * light[i].diffuse * N_dot_L ;
//Specular: CmaterialSpecularColor = max(Normal * HalfAngleLightandViewVector, 0) ^ exp * CmaterialColor * ClightColor
H = normalize( (L + V));
N_dot_H = max( dot ( N , H ), 0.0 ) ;
mSpecular += materialSpecular * light[i].specular * vec3(pow(N_dot_H, light[i].specularExponent) );
}
finalOutput = texColor * (vec4(mDiffuse,1.0 ) + vec4(mAmbient, 1.0) );
finalOutput.a=1.0;
}
Thank you all for your help.
I've been having problems sending the shininess factor to my bump mapping shader.
The result always looks like this: http://i.imgur.com/unzdx.jpg
But if I hard code the value inside the shader to 0.0 it's working just fine.
When I send 0.0 to the shader it's turning out like in the picture above.
Any ideas?
Here's my shader
#version 110
uniform sampler2D tex;
uniform sampler2D bmap;
uniform bool boolBump;
uniform vec4 vecColor;
uniform bool onlyColor;
uniform float fTransparencyThresh;
uniform float fShininess;
uniform float alpha;
varying vec3 vecLight;
varying vec3 vecEye;
varying vec3 vecNormal;
vec4 getLighting()
{
//Ambient part
vec4 color = (gl_FrontLightModelProduct.sceneColor * gl_FrontMaterial.ambient) + (gl_LightSource[0].ambient * gl_FrontMaterial.ambient);
//For bump mapping, the normal comes from the bump map texture lookup
vec3 n = normalize(vecNormal);
if(boolBump)
{
n = normalize(texture2D(bmap, gl_TexCoord[0].st).xyz * 2.0 - 1.0);
}
vec3 l = normalize(vecLight);
//Lambert term
float NdotL = dot(n, l);
if(NdotL > 0.0)
{
//Diffuse part
color += gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * max(0.0, NdotL);
//Specular part
vec3 e = normalize(vecEye);
vec3 r = normalize(-reflect(l,n));
float spec = pow(max(0.0, dot(r, e)), fShininess);
color += gl_LightSource[0].specular * gl_FrontMaterial.specular * spec;
}
return color;
}
void main(void)
{
vec4 texel = texture2D(tex, gl_TexCoord[0].st);
if(texel.a < fTransparencyThresh)
discard;
//Get shading
vec4 color = getLighting();
//Color only mode?
if(onlyColor)
{
color *= vecColor;
}
else
{
color *= texel;
}
//Set fragment color, alpha comes from MTL file
gl_FragColor = vec4(color.xyz, alpha);
}
Edit, OpenGL code:
void MyClass::sendToShader(const OBJ::StelModel* pStelModel, Effect cur, bool& tangEnabled, int& tangLocation)
{
int location;
tangEnabled = false;
if(cur != No)
{
location = curShader->uniformLocation("fTransparencyThresh");
curShader->setUniform(location, fTransparencyThresh);
location = curShader->uniformLocation("alpha");
curShader->setUniform(location, pStelModel->pMaterial->alpha);
location = curShader->uniformLocation("fShininess");
curShader->setUniform(location, 0.0f);
...
Edit: Even this wont work:
GLint loc = glGetUniformLocation(curShader->program, "fShininess");
glUniform1f(loc, 0.0f);
Note that pow(0, 0) is undefined. This means spec is undefined if dot(r, e) == 0 and fShininess == 0.
Do you make sure the program is actively bound when you call glUniform? Do you check glGetError anywhere?