I cannot get the following shader to work.
Vertex Shader
#version 430
in vec4 vPosition;
in vec4 vColor;
in vec2 vTexCoord;
in vec3 vNormal;
in vec3 vTangent;
in vec3 vBitangent;
//out vec4 color;
out vec2 texCoord;
uniform mat4 Model;
uniform mat4 View;
uniform mat4 Projection;
out vec3 LightDirection_cameraspace;
out vec3 Position_worldspace;
uniform vec3 LightPosition;
out vec3 EyeDirection_cameraspace;
out vec3 LightDirection_tangentspace;
out vec3 EyeDirection_tangentspace;
void main()
{
gl_Position = Projection * View * Model * vPosition;
Position_worldspace = (Model * vPosition).xyz;
vec3 vertexPosition_cameraspace = (View * Model * vPosition).xyz;
EyeDirection_cameraspace = vec3(0, 0, 0) - vertexPosition_cameraspace;
vec3 LightPosition_cameraspace = (View * vec4(LightPosition, 1)).xyz;
LightDirection_cameraspace = LightPosition_cameraspace + EyeDirection_cameraspace;
texCoord = vTexCoord;
mat4 ModelView = View * Model;
mat3 MV3x3 = mat3(ModelView);
vec3 vertexTangent_cameraspace = MV3x3 * vTangent;
vec3 vertexBitangent_cameraspace = MV3x3 * vBitangent;
vec3 vertexNormal_cameraspace = MV3x3 * vNormal;
mat3 TBN = transpose(mat3(
vertexTangent_cameraspace,
vertexBitangent_cameraspace,
vertexNormal_cameraspace
));
LightDirection_tangentspace = TBN * LightDirection_cameraspace;
EyeDirection_tangentspace = TBN * EyeDirection_cameraspace;
}
Fragment Shader
#version 430
in vec4 vColor;
in vec2 texCoord;
out vec4 fColor;
uniform sampler2D tex;
in vec3 Position_worldspace;
in vec3 EyeDirection_cameraspace;
uniform vec3 LightPosition;
//uniform sampler2D DiffuseTex; pretty much just tex
uniform sampler2D NormalTex;
uniform sampler2D SpecularTex;
in vec3 LightDirection_tangentspace;
in vec3 EyeDirection_tangentspace;
void main()
{
vec3 LightColor = vec3(1, 1, 1);
float LightPower = 50.0f;
//vec3 MaterialDiffuseColor = texture2D(tex, texCoord).rgb; // EDITABLE VALU 3 LINE
//vec3 MaterialAmbientColor = vec3(0.1, 0.1, 0.1) * MaterialDiffuseColor;
//vec3 MaterialSpecularColor = texture2D(SpecularTex, texCoord).rgb * 0.3;
vec3 MaterialDiffuseColor = vec3(0.5, 0.5, 0.5);
vec3 MaterialAmbientColor = vec3(0.1, 0.1, 0.1);
vec3 MaterialSpecularColor = vec3(1, 1, 1);
vec3 TextureNormal_tangentspace = normalize(texture2D(NormalTex, vec2(texCoord.x, texCoord.y)).rgb * 2.0 - 1.0); // EDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDIT this line if upside down
float distance = length(LightPosition - Position_worldspace);
vec3 n = TextureNormal_tangentspace;
vec3 l = normalize(LightDirection_tangentspace);
float cosTheta = clamp(dot(n, l), 0, 1);
vec3 E = normalize(EyeDirection_tangentspace);
vec3 R = reflect(-l, n);
float cosAlpha = clamp(dot(E, R), 0, 1);
fColor = vec4(MaterialAmbientColor + MaterialDiffuseColor * LightColor * LightPower * cosTheta / (distance*distance) + MaterialSpecularColor * LightColor * LightPower * pow(cosAlpha,5) / (distance*distance), 1.0);
}
Here's an imgur album with photos including the diffuse, specular, and normal maps as well as the image the program produces. http://imgur.com/a/8MMU1
P.S. The shader DOES compile, it just does not produce the desired image.
Firstly, nice code! I've seen shaders far more difficult to read than that.
You can simplify the projection/view/model transformations so there are no duplicates...
vec4 worldPosition = Modle * vPosition;
vec4 cameraPosition = View * worldPosition;
vec4 clipPosition = Projection * cameraPosition;
gl_Position = clipPosition;
To transform the normal, you need a normal matrix (inverse transpose modelview), otherwise scales can mess things up.
It's pretty common to compute LightPosition_cameraspace outside the shader, since it doesn't change. You also don't need Position_worldspace as distance can be computed in camera/eye space. View * Model is pretty expensive, and can be computed once and passed in. Now that View isn't needed, you can simply replace both View and Model with the single ModelView matrix.
The binormal can be computed implicitly from the normal and tangent via a cross product. This saves a fair bit of storage and memory bandwidth. If your normal/tangent are not perpendicular it may be necessary to use two cross products to ensure all three are orthonormal.
The main problem seems to be in your last line...
fColor = vec4(
MaterialAmbientColor
+ (
MaterialDiffuseColor * LightColor * LightPower * cosTheta
/ (distance*distance)
)
+ (
MaterialSpecularColor * LightColor * LightPower * pow(cosAlpha,5)
/ (distance*distance)
)
, 1.0);
LightPower is scaling your diffuse and specular components. Change to the following
float attenuation = 1.0/distance*distance; //just for readability
fColor = vec4(
MaterialAmbientColor
+ (
MaterialDiffuseColor * LightColor * cosTheta * attenuation
)
+ (
MaterialSpecularColor * LightColor * pow(cosAlpha, LightPower) * attenuation
)
, 1.0);
If after this you're still not seeing the right result, you'll have to start doing some debugging of each variable to narrow down the trouble maker. For example, as #user1118321 suggested check the colours aren't just black or something. Check your LightDirection_tangentspace with fColor = vec4(l,1) - you might look for (0,0,1)/blue for the parts that face the light directly. Make sure tangent/normals/light position are non-zero, the normal texture is bound etc (fColor = vec4(n,1)).
Related
I'm porting an openGL application to webassembly using Emscripten. I've written a bunch of shaders in GLSL (330) for the native version. However for the webversion I need shaders written in GLSL ES (300 es). How would I go about converting my shaders from GLSL to GLSL ES?
Possibilities I have considered so far:
GLSL -> SPIR-V -> GLSL ES,
having a bunch of #ifdef statements in the GLSL code in order to make blocks of code only execute for GLSL ES or GLSL,
writing custom C++ code that dynamically creates GLSL / GLSL ES code depending on what you need
simply having two nearly identical copies of all the shaders, one in GLSL and the other in GLSL ES
Example of GLSL vertex shader:
#version 330 core
#define NR_LIGHTS 10
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
out vec3 normalViewSpace;
out vec3 posViewSpace;
out vec2 textureCoords;
out vec4 positionsLightSpace[NR_LIGHTS];
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform mat3 normalMatrix;
uniform mat4 lightMatrices[NR_LIGHTS];
void main()
{
vec4 posViewSpaceV4;
posViewSpaceV4 = viewMatrix * modelMatrix * vec4(position, 1.0);
posViewSpace = posViewSpaceV4.xyz;
gl_Position = projectionMatrix * posViewSpaceV4;
normalViewSpace = mat3(viewMatrix) * normalMatrix * normal;
for( int i = 0; i
Example of GLSL fragment shader:
#version 330 core
#define NR_LIGHTS 10
struct Material {
vec3 ambient;
vec3 diffuse;
vec3 specular;
float shininess;
float alpha;
};
struct Light {
vec3 posViewSpace;
vec3 ambient;
vec3 diffuse;
vec3 specular;
float constant;
float linear;
float quadratic;
vec3 directionViewSpace;
float cutOff;
float outerCutOff;
sampler2D shadowMap;
};
out vec4 FragColor;
in vec3 normalViewSpace;
in vec3 posViewSpace;
in vec4 positionsLightSpace[NR_LIGHTS];
uniform Material material;
uniform Light lights[NR_LIGHTS];
float shadowCalculation(vec4 posLightSpace, sampler2D shadowMap, Light light)
{
// perform perspective divide
vec3 projCoords = posLightSpace.xyz / posLightSpace.w; // range [-1, 1]
// transform range [0, 1]
projCoords = projCoords * 0.5 + 0.5;
float closestDepth = texture(shadowMap, projCoords.xy).r;
float currentDepth = projCoords.z;
vec3 lightDir = normalize(light.posViewSpace - posViewSpace);
float bias = max(0.00005 * (1.0 - dot(normalViewSpace, lightDir)), 0.000005); // solves shadow acne
float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
return shadow;
}
vec3 calcSpotLight( Light light, vec3 normal, vec3 position, float shadow) // normal and position in view space, although this function should not care about which space it's in
{
vec3 result = vec3(0.0, 0.0, 0.0);
vec3 lightDir = normalize(light.posViewSpace - position);
float theta = dot(lightDir, normalize(-light.directionViewSpace));
float epsilon = light.cutOff - light.outerCutOff;
float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0); // interpolate between inner and outer cutOff and clamp to 0 and 1
if( intensity > 0 ) // if inside spot radius
{
// attenuation
float distance = length(light.posViewSpace - position);
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
if( attenuation > 0.001 )
{
// ambient
vec3 ambient = material.ambient * light.ambient;
// diffuse
vec3 norm = normalize(normalViewSpace);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * material.diffuse * light.diffuse;
// specular
vec3 viewDir = normalize(-position); // in view space the camera is at (0, 0, 0)
vec3 reflectDir = reflect(-lightDir, norm); // reflect function expect vector FROM light source TO position
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
vec3 specular = material.specular * spec * light.specular;
// result
result = intensity * attenuation * (ambient + (1.0 - shadow) * (diffuse + specular));
}
}
return result;
}
void main()
{
vec3 result = material.ambient * 0.08;
for( int i = 0; i
I am implementing a basic phong lighting GLSL shader; I have looked up some things on the internet, and found that the phong effect was created by adding an ambient, diffuse, and specular layer on the object (see image below, from tom dalling's site); problem is I have seen a lot of examples, and none of them really suits my GLSL set-up. Can any of you give me a code example of the correct way to implement the phong effect which would fit my GLSL set-up ? :
PS : This question could be put on hold because of the fact that it may be based on user opinion : In my mind, it is not, because I would like to know the most effective, and better way of implementing it.
Here is my vertex shader :
#version 120
uniform mat4 modelView;
uniform mat4 MVP;
uniform float time;
attribute vec3 position;
attribute vec2 texCoord;
attribute vec3 normal;
varying vec3 position0;
varying vec2 texCoord0;
varying vec3 normal0;
varying mat4 modelView0;
void main()
{
//Updating varyings...
position0 = position;
texCoord0 = texCoord;
normal0 = (MVP * vec4(normal, 0.0)).xyz;
modelView0 = modelView;
//set position
gl_Position = MVP * vec4(position, 1.0);
}
and my fragment shader :
#version 120
varying vec3 position0;
varying vec2 texCoord0;
varying vec3 normal0;
varying mat4 modelView0;
uniform sampler2D diffuse;
void main()
{
vec4 surfaceColor = texture2D(diffuse, texCoord0);
gl_FragColor = (texture2D(diffuse, texCoord0))
* clamp(dot(-vec3(0.0, 0.5, 0.5), normal0), 0, 1.0);
}
try this:
void main()
{
vec4 texread = texture2D(diffuse, texCoord0);
vec3 normal = normalize(normal0);
vec3 material_kd = vec3(1.0,1.0,1.0);
vec3 material_ks = vec3(1.0,1.0,1.0);
vec3 material_ka = vec3(0.2,0.2,0.2);
vec3 material_ke = vec3(0.0,0.0,0.0);
float material_shininess = 60;
vec3 lightpos = vec3(0.0,10.0,5.0);
vec3 lightcolor = vec3(1.0,1.0,1.0);
vec3 lightdir = normalize(lightpos - worldPosition);
float shade = clamp(dot(lightdir, normal), 0.0, 1.0);
vec3 toWorldpos = normalize((worldPosition) - u_eyePos);
vec3 reflectDir = reflect( toWorldpos, normal );
vec4 specular = vec4(pow(clamp(dot(lightdir, reflectDir),0.0,1.0), material_shininess) * lightcolor * material_ks, 1.0);
vec4 shaded = texread * vec4(material_kd, 1.0) * vec4(lightcolor , 1.0) * shade;
vec4 ambient = texread * vec4(material_ka, 1.0);
vec4 emission = vec4(material_ke, 1.0);
gl_FragColor = shaded + specular + emission + ambient;
}
it may have some compilation errors though as i didnt run it...
you may need to upload your eye position as a uniform (u_eyePos), and calculate the worldposition (worldPosition) for it to work
I made my own sphong shader : here is the code :
fragment shader :
#version 150
uniform mat4 modelView;
uniform mat3 normalMatrix;
uniform vec3 cameraPosition;
uniform sampler2D materialTex;
uniform float materialShininess;
uniform vec3 materialSpecularColor;
uniform vec3 lightPosition;//light settings
uniform vec3 lightIntensities;
uniform float lightAttenuation;
uniform float lightAmbientCoeff;
in vec3 position0;
in vec2 texCoord0;
in vec3 normal0;
out vec4 fragmentColor;
void main()
{
//calculate normal in world coordinates
vec3 normal = normalize(normalMatrix * normal0);
//calculate the location of this fragment (pixel) in world coordinates
vec3 surfacePos = vec3(modelView * vec4(position0, 1));
//color of the current fragment
vec4 surfaceColor = texture(materialTex, texCoord0);
//calculate the vector from this pixels surface to the light source
vec3 surfaceToLight = normalize(lightPosition - surfacePos);
//cam distance
vec3 surfaceToCamera = normalize(cameraPosition - surfacePos);
///////////////////////////DIFUSE///////////////////////////////////////
//calculate the cosine of the angle of incidence
//float diffuseCoeff = dot(normal, surfaceToLight) / (length(surfaceToLight) * length(normal));
float diffuseCoeff = max(0.0, dot(normal, surfaceToLight));
vec3 diffuse = diffuseCoeff * surfaceColor.rgb * lightIntensities;
/////////////////////////AMBIENT////////////////////////////////////////
vec3 ambient = lightAmbientCoeff * surfaceColor.rgb * lightIntensities;
/////////////////////////SPECULAR//////////////////////////////////////
float specularCoeff = 0.0;
if(diffuseCoeff > 0.0)
specularCoeff = pow(max(0.0, dot(surfaceToCamera, reflect(-surfaceToLight, normal))), materialShininess);
vec3 specular = specularCoeff * materialSpecularColor * lightIntensities;
////////////////////////ATTENUATION///////////////////////////////////
float distanceToLight = length(lightPosition - surfacePos);
float attenuation = 1.0 / (1.0 + lightAttenuation * pow(distanceToLight, 2));
/////////////////////////////////FINAL/////////////////////////////////
vec3 linearColor = ambient + attenuation * (diffuse + specular);
//finalColor with gamma correction
vec3 gamma = vec3(1.0/2.2);
fragmentColor = vec4(pow(linearColor, gamma), surfaceColor.a);
//fragmentColor = vec4(diffuseCoeff * lightIntensities * surfaceColor.rgb, surfaceColor.a);
}
I was trying to add a normal map effect to a shader tutorial I have found here but with no luck.
UPDATE 1:
I updated the code adding a tangent space matrix
Vertex shader:
#version 330
in vec3 inPosition;
in vec3 vertNormal;
in vec2 vertTexCoord;
in vec4 vertNormalMapping;
out vec3 fragVert;
out vec3 fragNormal;
out vec2 fragTexCoord;
out vec4 fragNormalMapping;
out mat3 TBNMatrix;
uniform mat4 modelViewProjectionMatrix;
uniform mat4 camera;
void main(){
vec3 tangent;
vec3 binormal;
vec3 c1 = cross( vertNormal, vec3(0.0, 0.0, 1.0) );
vec3 c2 = cross( vertNormal, vec3(0.0, 1.0, 0.0) );
if( length(c1)>length(c2) )
{
tangent = c1;
}
else
{
tangent = c2;
}
tangent = normalize(tangent);
binormal = cross(vertNormal, tangent);
binormal = normalize(binormal);
mat3 normalMatrix = transpose(inverse(mat3(camera * modelViewProjectionMatrix )));
vec3 n = normalize(normalMatrix * vertNormal);
vec3 t = normalize(normalMatrix * tangent.xyz);
vec3 b = normalize(normalMatrix * binormal.xyz);
TBNMatrix = mat3(t, b, n);
fragTexCoord = vertTexCoord;
fragNormal = vertNormal;
fragVert = inPosition;
fragNormalMapping = vertNormalMapping;
gl_Position = camera * modelViewProjectionMatrix * vec4(inPosition, 1.0);
}
Fragment shader
#version 330
precision highp float;
uniform vec3 cameraPosition;
uniform mat4 modelViewProjectionMatrix;
uniform mat4 camera;
uniform sampler2D tex;
uniform sampler2D heightMap;
uniform float materialShininess;
uniform vec3 materialSpecularColor;
uniform struct Light {
vec3 position;
vec3 intensities; //a.k.a the color of the light
float attenuation;
float ambientCoefficient;
} light;
in vec3 fragNormal;
in vec3 fragVert;
in vec2 fragTexCoord;
in vec4 fragNormalMapping;
in mat3 TBNMatrix;
out vec4 finalColor;
void main() {
vec3 surfacePos = vec3(modelViewProjectionMatrix * vec4(fragVert, 1));
vec4 surfaceColor = texture(tex, fragTexCoord);
vec3 surfaceToLight = TBNMatrix * (light.position - surfacePos) ;
vec3 surfaceToCamera = TBNMatrix * (cameraPosition - surfacePos);
vec3 normal = normalize(texture(heightMap, fragTexCoord).xyz * 2.0 - 1.0);
//ambient
vec3 ambient = light.ambientCoefficient * surfaceColor.rgb * light.intensities;
//diffuse
float diffuseCoefficient = max(0.0, dot(normal, surfaceToLight));
vec3 diffuse = diffuseCoefficient * surfaceColor.rgb * light.intensities;
//specular
float specularCoefficient = 0.0;
if(diffuseCoefficient > 0.0)
specularCoefficient = pow(max(0.0, dot(surfaceToCamera, reflect(-surfaceToLight, normal))), materialShininess);
vec3 specular = specularCoefficient * materialSpecularColor * light.intensities;
//attenuation
float distanceToLight = length(light.position - surfacePos);
float attenuation = 1.0 / (1.0 + light.attenuation * pow(distanceToLight, 2));
//linear color (color before gamma correction)
vec3 linearColor = ambient + attenuation*(diffuse + specular);
//final color (after gamma correction)
vec3 gamma = vec3(1.0/2.2);
finalColor = vec4(pow(linearColor, gamma), surfaceColor.a);
}
The result is better but now the lighting is calculated wrong O.O
//OLD
I have tried with a blank color texture and a correct normal map texture and the result is this: The normal map is calculated correctly but... these lines are not so cool to see :-(
Any idea of what is the cause? thank you everyone for the help =D
posting here for clarity...
mv = camera * transform;//modelview
mvp = proj * camera * transform;//modelviewprojection
mvi = transpose(inverse(mv))//modelview inverse (=gl_NormalMatrix)
so you should have in place of modelViewProjectionMatrix passed to the shader the modelView and the projection separately, and compute the resulting mvp in the vertex shader.
(or precompute them all on cpu side)
I've been trying to update some code to be OpenGL 3.2 compliant, but I'm having trouble with my shaders. I've been reading up on the differences online, and my shaders compile, but my screen remains my glClearColor. I have a vertex and fragment shader (doing phong shading). Everything works great under OpenGL 2.1 / GLSL 1.2, the problems only arise under OpenGL 3.2 / GLSL 1.5
Here are my version 1.2 shaders:
Vertex:
#version 120
uniform mat4 uProjMatrix;
uniform mat4 uViewMatrix;
uniform mat4 uModelMatrix;
uniform mat4 uNormalMatrix;
attribute vec3 aPosition;
attribute vec3 aNormal;
varying vec3 vWorldPosition;
varying vec3 vNormal;
void main() {
// Transforms
vec4 lPosition = uModelMatrix * vec4(aPosition.x, aPosition.y, aPosition.z, 1);
vWorldPosition = vec3(lPosition.x, lPosition.y, lPosition.z);
gl_Position = uProjMatrix * uViewMatrix * lPosition;
// Calculate the relative normal
vec4 lNormal = vec4(aNormal.x, aNormal.y, aNormal.z, 0);
lNormal = uNormalMatrix * lNormal;
vNormal = vec3(lNormal.x, lNormal.y, lNormal.z);
}
Fragment:
#version 120
struct Light {
vec3 position, color;
float constFalloff, linearFalloff, squareFalloff;
};
struct Material {
vec3 ambient, diffuse, specular, emission;
float shininess;
};
uniform Light uLights[10];
uniform int uNumLights;
uniform Material uMaterial;
uniform vec3 uCameraPos;
varying vec3 vWorldPosition;
varying vec3 vNormal;
void main() {
vec3 lNormal = normalize(vNormal);
vec3 finalColor = vec3(0.0, 0.0, 0.0);
for(int i = 0; i < uNumLights; ++i) {
// Diffuse light
vec3 toLight = uLights[i].position - vWorldPosition;
float lightDistance = length(toLight);
toLight = normalize(toLight);
float diffuseAmount = max(dot(lNormal, toLight), 0.0);
// Specular light
vec3 toCamera = normalize(uCameraPos - vWorldPosition);
vec3 reflection = normalize(2.0 * dot(toLight, lNormal) * lNormal - toLight);
float specularAmount = pow(max(dot(toCamera, reflection), 0.0), uMaterial.shininess);
// Falloff
float falloff = 1.0 / (uLights[i].constFalloff
+ uLights[i].linearFalloff * lightDistance
+ uLights[i].squareFalloff * lightDistance * lightDistance);
finalColor += ((uMaterial.diffuse * diffuseAmount
+ uMaterial.specular * specularAmount) * falloff
+ uMaterial.ambient) * uLights[i].color;
}
finalColor += uMaterial.emission;
gl_FragColor = vec4(finalColor.r, finalColor.g, finalColor.b, 1.0);
}
And my version 1.5 shaders:
Vertex:
#version 150 core
uniform mat4 uProjMatrix;
uniform mat4 uViewMatrix;
uniform mat4 uModelMatrix;
uniform mat4 uNormalMatrix;
in vec3 aPosition;
in vec3 aNormal;
out vec3 vWorldPosition;
out vec3 vNormal;
void main() {
// Transforms
vec4 lPosition = uModelMatrix * vec4(aPosition.x, aPosition.y, aPosition.z, 1);
vWorldPosition = vec3(lPosition.x, lPosition.y, lPosition.z);
gl_Position = uProjMatrix * uViewMatrix * lPosition;
// Calculate the relative normal
vec4 lNormal = vec4(aNormal.x, aNormal.y, aNormal.z, 0);
lNormal = uNormalMatrix * lNormal;
vNormal = vec3(lNormal.x, lNormal.y, lNormal.z);
}
Fragment:
#version 150 core
struct Light {
vec3 position, color;
float constFalloff, linearFalloff, squareFalloff;
};
struct Material {
vec3 ambient, diffuse, specular, emission;
float shininess;
};
uniform Light uLights[10];
uniform int uNumLights;
uniform Material uMaterial;
uniform vec3 uCameraPos;
in vec3 vWorldPosition;
in vec3 vNormal;
out vec4 outColor;
void main() {
vec3 lNormal = normalize(vNormal);
vec3 finalColor = vec3(0.0, 0.0, 0.0);
for(int i = 0; i < uNumLights; ++i) {
// Diffuse light
vec3 toLight = uLights[i].position - vWorldPosition;
float lightDistance = length(toLight);
toLight = normalize(toLight);
float diffuseAmount = max(dot(lNormal, toLight), 0.0);
// Specular light
vec3 toCamera = normalize(uCameraPos - vWorldPosition);
vec3 reflection = normalize(2.0 * dot(toLight, lNormal) * lNormal - toLight);
float specularAmount = pow(max(dot(toCamera, reflection), 0.0), uMaterial.shininess);
// Falloff
float falloff = 1.0 / (uLights[i].constFalloff
+ uLights[i].linearFalloff * lightDistance
+ uLights[i].squareFalloff * lightDistance * lightDistance);
finalColor += ((uMaterial.diffuse * diffuseAmount
+ uMaterial.specular * specularAmount) * falloff
+ uMaterial.ambient) * uLights[i].color;
}
finalColor += uMaterial.emission;
outColor = vec4(finalColor.r, finalColor.g, finalColor.b, 1.0);
}
I do not get any errors from compiling / linking the 1.5 shaders, but nothing draws. What am I missing?
Below is listed the shader code for normal mapping. Nevertheless there is something wrong with the code since the resulting image is incorrect. The normals seem to be off. Other features seem to work fine so I believe the problem is with the shaders. Any ideas what could be wrong?
Vertex shader
#version 150
in vec3 position;
in vec2 texcoord;
in vec3 normal;
in vec3 tangent;
in vec3 bitangent;
out vec2 Texcoord;
out vec3 VertexPos_World;
out vec3 LightDir_Tan;
uniform vec3 lightPos0_World;
uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;
void main()
{
gl_Position = proj * view * model * vec4(position, 1.0);
Texcoord = texcoord;
VertexPos_World = (model * vec4(position, 1.0)).xyz;
vec3 normal_Cam = (view * model * vec4(normal, 1.0)).xyz;
vec3 tangent_Cam = (view * model * vec4(tangent, 1.0)).xyz;
vec3 bitangent_Cam = (view * model * vec4(bitangent, 1.0)).xyz;
mat3 TBN = transpose(mat3(tangent_Cam, bitangent_Cam, normal_Cam));
vec3 lightDir_Cam = lightPos_Cam - vertexPos_Cam;
LightDir_Tan = TBN * lightDir_Cam;
}
Fragment Shader
#version 150
in vec2 Texcoord;
in vec3 VertexPos_World;
in vec3 LightDir_Tan;
out vec4 outColor;
uniform vec3 lightPos0_World;
uniform vec3 lightColor0;
uniform float lightPower0;
uniform vec3 ambientColor;
uniform vec3 diffuseColor;
uniform sampler2D tex0;
uniform sampler2D tex0normal;
void main()
{
float lightDistance = length(lightPos0_World - VertexPos_World);
vec3 materialDiffuseColor = texture(tex0, Texcoord).xyz * diffuseColor;
vec3 materialAmbientColor = ambientColor * materialDiffuseColor;
vec3 n = normalize(texture(tex0normal, Texcoord).rgb * 2.0 - 1.0);
vec3 l = normalize(LightDir_Tan);
float diff = clamp(dot(n,l), 0, 1);
outColor.rgb =
materialAmbientColor +
materialDiffuseColor * lightColor0 * lightPower0 * diff / (lightDistance * lightDistance);
}
This might not be the only issue, but in your shader you have:
vec3 normal_Cam = (view * model * vec4(normal, 1.0)).xyz;
vec3 tangent_Cam = (view * model * vec4(tangent, 1.0)).xyz;
vec3 bitangent_Cam = (view * model * vec4(bitangent, 1.0)).xyz;
This should be:
vec3 normal_Cam = (view * model * vec4(normal, 0.0)).xyz;
vec3 tangent_Cam = (view * model * vec4(tangent, 0.0)).xyz;
vec3 bitangent_Cam = (view * model * vec4(bitangent, 0.0)).xyz;
Using 0.0 instead of 1.0 because these are direction vectors, not positions, so you want to ignore the translations in the matrices.
Also, you should multiply those matrices in your application and use a uniform view_model in your shader (otherwise you do this work per-vertex instead of per-model).
Your normals are most likely very off. Make sure that instead of submitting a cube with 8 vertices, you submit a cube with 4 vertices per face so that you can send the correct normals per face. Otherwise, the interpolator will simply use the normals from indexed neighbour triangles and that is what causes that issue.