Volumetric Light not rendering volume correctly - opengl

I've been following this tutorial (https://www.programmersought.com/article/68075912719/) to get volumetric light. But I am not getting the correct output.
The shadow volume is incorrectly rendered and I am not sure what I am doing wrong. My vertex and fragment shader looks exactly like the tutorial but still I'm not getting correct output.
Here is the vertex shader code
#version 450 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoord;
layout (location = 2) in vec3 normal;
uniform mat4 model;
uniform mat4 vp;
uniform float zFar;
uniform float fov;;
uniform float aspectRatio;
out vec2 TexCoord;
out vec2 farPlanePos;
void main(void){
gl_Position = vec4(position, 1.0);
TexCoord = vec2 (texCoord.x, 1 - texCoord.y);
float t = tan(fov/2);
farPlanePos.x = (TexCoord.x * 2 - 1) * zFar * t * aspectRatio;
farPlanePos.y = (TexCoord.y * 2 - 1) * zFar * t;
}
And Here is the fragment shader code
#version 450 core
in vec2 TexCoord;
uniform vec3 cameraPos;
uniform vec3 lightPos;
uniform vec3 lightColor;
uniform mat4 invViewMatrix;
uniform mat4 invProjectionMatrix;
uniform float ambientStrength;
uniform sampler2D gPosition;
uniform sampler2D gNormal;
uniform sampler2D gAlbedoSpec;
uniform sampler2D gDepth;
uniform sampler2D shadowMapTexture;
in vec2 farPlanePos;
uniform float zFar;
uniform float zNear;
float g = 0.0f;
uniform mat4 lightViewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
vec3 yellow_light = vec3(1,198.0/255.0,107.0/255.0);
out vec4 finalColor;
// use linear z depth
vec3 ComputeWorldPos(float depth){
vec4 pos = vec4(vec3(farPlanePos.x, farPlanePos.y, -zFar) * depth , 1.0f);
vec4 ret = invViewMatrix * pos;
return ret.xyz / ret.w;
}
bool IsInShadow(vec4 worldPos){
float fShadow = 0.0;
vec4 lightPos = (lightViewMatrix * (worldPos));
float fDistance = -lightPos.z / zFar;
lightPos = projectionMatrix * lightPos;
vec2 uv = lightPos.xy / lightPos.w * 0.5 + vec2(0.5f, 0.5f);
uv.x = clamp(uv.x, 0.0f, 1.0f);
uv.y = clamp(uv.y, 0.0f, 1.0f);
float offset = 0.5f/zFar;
float distanceMap = texture2D(shadowMapTexture, uv).r;
return fDistance - offset > distanceMap;
}
void main(void){
float depth = texture2D(gDepth, TexCoord).w;
vec3 total_light;
// volume light
{
float I = 0.0f;
float d = depth * zFar;
int virtual_plane_num = 100;
int begin = int(virtual_plane_num * zNear / (d - zNear));
int end = int(virtual_plane_num * (zFar - d) / (d - zNear));
for(int j = begin; j <= virtual_plane_num + begin; j++)
{
float z = 1.0f * j / (begin + virtual_plane_num + end);
vec3 pos = ComputeWorldPos(z);
if(z < depth && !IsInShadow(vec4(pos,1.0f)))
{
//vec3 lightDis = pos - lightPos;
//vec3 viewDis = pos - cameraPos;
//float lightDis2 = lightDis.x * lightDis.x + lightDis.y * lightDis.y + lightDis.z * lightDis.z;
vec3 lightDir = normalize(pos - lightPos);
vec3 viewDir = normalize(pos - cameraPos);
float cosTheta = dot(lightDir,normalize(-lightPos));
float hg = 1.0f/(4.0f*3.14f)* (1.0f - g*g)/ pow(1.0f + g * g - 2.0f * g * dot(lightDir,-viewDir), 1.5f);
if(cosTheta >0.9){
I += clamp(10 * hg / virtual_plane_num, 0.0f, 1.0f);
}
}
}
I = clamp(I , 0.0f,1.0f);
total_light += I * yellow_light;
}
vec3 normal = texture2D(gNormal, TexCoord).xyz * 2 - 1; //result.xyz * 2 - 1;
vec3 worldPos = ComputeWorldPos(depth);
// parallel lights
/*
{
vec3 ViewDir = normalize( cameraPos - worldPos );
vec3 lightDir = normalize(vec3(0.5,1,0.2) );
vec3 halfDir = normalize(lightDir + ViewDir);
float diffuse = 0.3 * clamp(dot(normal, lightDir), 0, 1) ;
vec3 reflectDir = normalize(reflect(-lightDir,normal));
float specular = 0.3 * pow(clamp(dot(reflectDir,halfDir),0,1),50.0);
vec3 color = (diffuse + specular) *vec3(1,1,1);
total_light += color;
}
*/
vec3 color = vec3(texture2D(gAlbedoSpec,TexCoord));
float ambient = 0.1;
finalColor = vec4(total_light + ambient * color,1);
}
So you can see the vertex and fragment shader code is exactly like the blog, but still the output is different.
Unfortunately it doesn't say how to contact the blogger otherwise I would have asked them directly. So the next best option is stockoverflow, so I am asking here.

Ok after 2 days I was able to fix the issue. I think the isInShadow function is incorrect as it always perspective divies by zFar and also doesnt multiply by projection matrix before getting current depth.
So I replaced the code with learnOpengl shadow calculation as below.
bool IsInShadow(vec4 worldPos){
vec4 lightPos = (lightViewMatrix * (worldPos));
//float fDistance = -lightPos.z/ zFar;
lightPos = projectionMatrix * lightPos;
vec3 projCoords = lightPos.xyz / lightPos.w ;
projCoords = projCoords* 0.5 + 0.5f;
//uv.x = clamp(uv.x, 0.0f, 1.0f);
//uv.y = clamp(uv.y, 0.0f, 1.0f);
float offset = 0.5f/zFar;
float distanceMap = texture2D(shadowMapTexture, projCoords.xy).r;
return projCoords.z - offset > distanceMap;
}
And now the code works!!

Related

Have any guys experienced the same occasion with me about ssao in OpenGL?

Most of the shader codes are follow the instruction of LearnOpenGL. I could make sure that the g-buffer and noise data pass into the shader are correct. It seems like some kind of dislocation, but But I really can't figure out why this happened.
misplace ssao
#version 450 core
out float OUT_FragColor;
in vec2 TexCoords;
uniform sampler2D g_position;
uniform sampler2D g_normal;
uniform sampler2D noise_texture;
struct CameraInfo
{
vec4 position;
mat4 view;
mat4 projection;
};
layout(std140, binding = 0) uniform Camera
{
CameraInfo camera;
};
float radius = 0.5;
float bias = 0.025;
uniform int noise_tex_size;
void main()
{
const vec2 noise_scale = vec2(1280.0/noise_tex_size, 720.0/noise_tex_size);
vec3 frag_pos = texture(g_position, TexCoords).xyz;
vec3 normal = normalize(texture(g_normal, TexCoords).xyz);
vec3 random_vec = normalize(texture(noise_texture, TexCoords * noise_scale).xyz);
vec3 tangent = normalize(random_vec - normal * dot(random_vec, normal));
vec3 bitangent = cross(normal, tangent);
mat3 TBN = mat3(tangent, bitangent, normal);
float occlusion = 0.f;
for(int i = 0; i < sample_array.length(); ++i)
{
vec3 sample_pos = TBN * sample_array[i].xyz;
sample_pos = frag_pos + sample_pos * radius;
vec4 offset = vec4(sample_pos, 1.0);
offset = camera.projection * offset; // from view to clip-space
offset.xyz /= offset.w; // perspective divide ?????
offset.xyz = offset.xyz * 0.5 + 0.5; // transform to range 0.0 - 1.0
float sample_depth = texture(g_position, offset.xy).z;
float range_check = smoothstep(0.f, 1.f, radius / abs(frag_pos.z - sample_depth));
occlusion += (sample_depth >= sample_pos.z + bias ? 1.0 : 0.0) * range_check; //ignore sample points that too near the origin point
}
occlusion = 1.f - (occlusion / sample_array.length());
OUT_FragColor = occlusion;
}
transform the g_postion and g_normal into model space
FragPos = (camera.view * vec4(WorldPos, 1.0)).xyz;
mat4 normal_matrix = camera.view * mat4(transpose(inverse(mat3(model))));
FragNormal = mat3(normal_matrix) * normal;

How to convert GLSL shaders to GLSL ES

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

Spotlight with shadows becomes square-like

I've been following a two part tutorial on shadow mapping from OGLDev (part 1, part 2) for a couple of days now, and I've nearly finished implementing it.
My problem is that when I enable shadow maps the illuminated region which shadows appear in appears as a "strip" and I'm unsure if this is intended in the tutorials or not.
Perhaps images will help explain my problem.
However shadows are functional:
My vertex shader for spotlights:
#version 330
in vec2 textureCoordinate;
in vec4 vertex;
uniform mat4 mMatrix;
uniform mat4 pMatrix;
uniform mat4 vMatrix;
uniform mat4 lightV;
uniform mat4 lightP;
uniform vec3 normal;
uniform vec3 eye;
out vec2 TexCoord0;
out vec4 LightSpacePos;
out vec3 Normal0;
out vec3 WorldPos0;
out vec3 EyePos;
void main()
{
EyePos = eye;
TexCoord0 = textureCoordinate;
WorldPos0 = (mMatrix * vertex).xyz;
Normal0 = (mMatrix * vec4(normal, 0.0)).xyz;
mat4 lightMVP = lightP * inverse(lightV) * mMatrix;
LightSpacePos = lightMVP * vertex;
mat4 worldMVP = pMatrix * vMatrix * mMatrix;
gl_Position = worldMVP * vertex;
}
and the fragment shader:
#version 330
struct BaseLight
{
vec4 color;
float intensity;
};
struct Attenuation
{
float constant;
float linear;
float exponent;
};
struct PointLight
{
BaseLight base;
Attenuation atten;
vec3 position;
float range;
};
struct SpotLight
{
struct PointLight base;
vec3 direction;
float cutoff;
};
in vec2 TexCoord0;
in vec3 WorldPos0;
in vec3 EyePos;
in vec4 LightSpacePos;
out vec4 fragColor;
uniform sampler2D sampler;
uniform sampler2D shadowMap;
in vec3 Normal0;
uniform float specularIntensity;
uniform float specularPower;
uniform SpotLight spotLight;
float CalcShadowFactor(vec4 LightSpacePos)
{
vec3 ProjCoords = LightSpacePos.xyz / LightSpacePos.w;
vec2 UVCoords;
UVCoords.x = 0.5 * ProjCoords.x + 0.5;
UVCoords.y = 0.5 * ProjCoords.y + 0.5;
float z = 0.5 * ProjCoords.z + 0.5;
float Depth = texture(shadowMap, UVCoords).x;
if (Depth < z + 0.00001)
return 0.5;
else
return 1.0;
}
vec4 CalcLightInternal(BaseLight Light, vec3 LightDirection, vec3 Normal, float ShadowFactor)
{
vec4 AmbientColor = Light.color * Light.intensity;
float DiffuseFactor = dot(Normal, -LightDirection);
vec4 DiffuseColor = vec4(0, 0, 0, 0);
vec4 SpecularColor = vec4(0, 0, 0, 0);
if (DiffuseFactor > 0) {
DiffuseColor = Light.color * Light.intensity * DiffuseFactor;
vec3 VertexToEye = normalize(EyePos - WorldPos0);
vec3 LightReflect = normalize(reflect(LightDirection, Normal));
float SpecularFactor = dot(VertexToEye, LightReflect);
SpecularFactor = pow(SpecularFactor, specularPower);
if (SpecularFactor > 0) {
SpecularColor = Light.color * specularIntensity * SpecularFactor;
}
}
return (AmbientColor + ShadowFactor * (DiffuseColor + SpecularColor));
}
vec4 CalcPointLight(PointLight l, vec3 Normal, vec4 LightSpacePos)
{
vec3 LightDirection = WorldPos0 - l.position;
float Distance = length(LightDirection);
LightDirection = normalize(LightDirection);
float ShadowFactor = CalcShadowFactor(LightSpacePos);
vec4 Color = CalcLightInternal(l.base, LightDirection, Normal, ShadowFactor);
float Attenuation = l.atten.constant +
l.atten.linear * Distance +
l.atten.exponent * Distance * Distance;
return Color / Attenuation;
}
vec4 CalcSpotLight(SpotLight l, vec3 Normal, vec4 LightSpacePos)
{
vec3 LightToPixel = normalize(WorldPos0 - l.base.position);
float SpotFactor = dot(LightToPixel, l.direction);
if (SpotFactor > l.cutoff) {
vec4 Color = CalcPointLight(l.base, Normal, LightSpacePos);
return Color * (1.0 - (1.0 - SpotFactor) * 1.0/(1.0 - l.cutoff));
}
else {
return vec4(0,0,0,0);
}
}
void main(void)
{
fragColor = texture2D(sampler, TexCoord0.xy) * CalcSpotLight(spotLight, normalize(Normal0), LightSpacePos);
}
This is intended. Since your shadowmap covers a pyramid-like region in space, your spotlight's cone can be occluded by it. This is happening because where you render something that is outside of the shadow camera's view, it will be considered unlitten. Therefore the shadow camera's view pyramid will be visible.
src
To fix this you have 2 options:
1: Make the shadowmap camera's fov bigger, so that the shadow camera's pyramid becomes wider than your spotlight's cone
2: Change the way you calculate shadows on out-of-bounds area. Currently when you sample the shadowmap, and if it's outside of the shadow texture, you apply shadow there. If you change this so that if something that is out of the shadow texture you consider it litten, this problem will disappear.
Edit:
I recommend the second option. A solution for that could be:
Insert the following line into FragmentShader::CalcShadowFactor(), just before the float Depth = ... part
if (UVCoords.x < 0.0 || UVCoords.x > 1.0 || UVCoords.y < 0.0 || UVCoords.y > 1.0) return 1.0;
Note:
There is no universal way to say which is better. In a terrain environment involving sunlight, you may want to consider out-of-bounds regions as litten. However when you use a flashlight for example, that is in the user's hand, you have to consider out-of-bounds regions as unlitten.

Syntax error in GLSL - unexpected NEW_IDENTIFIER

I have been writing a shading language that is meant to simplify writing GLSL. Because of this, I can't really rely on line numbers given by the GLSL compiler. I therefore can't find what this error is trying to say. What does it mean first of all, and then how can I fix it?
Error code:
0:8(18): error: syntax error, unexpected NEW_IDENTIFIER, expecting '{'
I believe that this just means there is a syntax error with the generated GLSL, but I can't find one. What does this error message actually mean?
-- EDIT --
Sorry for not providing code, I wanted to know what the error meant so I could provide the relevant areas of code.
Generated vertex shader:
#version 120
attribute vec3 position;
attribute vec2 texCoord;
attribute vec3 normal;
attribute vec3 tangent;
varying vec2 fragTexCoords;
varying vec3 worldPos;
varying vec4 shadowMapCoords;
varying mat3 tbnMatrix;
uniform mat4 modelMatrix;
uniform mat4 MVPMatrix;
uniform mat4 lightMatrix;
void main() {
gl_Position = MVPMatrix * vec4(position, 1);
fragTexCoords = texCoord;
shadowMapCoords = lightMatrix * vec4(position, 1);
worldPos = (modelMatrix * vec4(position, 1)).xyz;
vec3 n = normalize((modelMatrix * vec4(normal, 0)).xyz);
vec3 t = normalize((modelMatrix * vec4(tangent, 0)).xyz);
t = normalize(t - dot(t, n) * n);
vec3 biTangent = cross(t, n);
tbnMatrix = mat3(t, biTangent, n);
}
And the generated fragment shader:
#version 120
varying vec2 fragTexCoords;
varying vec3 worldPos;
varying vec4 shadowMapCoords;
varying mat3 tbnMatrix;
uniform Material material;
uniform Light light;
uniform vec3 eyePos;
uniform sampler2D shadowMap;
uniform float shadowVarianceMin;
uniform float shadowLightBleedReduction;
bool inRange(float value) {
return value >= 0 && value <= 1;
}
float linStep(float low, float high, float v) {
return clamp((v - low) / (high - low), 0, 1);
}
vec2 calcParallaxTexCoords(sampler2D dispMap, mat3 tbnMatrix, vec3 directionToEye, vec2 texCoords, float scale, float bias) {
return texCoords.xy + (directionToEye * tbnMatrix).xy * (texture2D(dispMap, texCoords.xy).r * scale + bias);
}
float sampleShadowMap(sampler2D shadowMap, vec2 coords, float compare) {
return step(compare, texture2D(shadowMap, coords.xy).r);
}
float sampleVarianceShadowMap(sampler2D shadowMap, vec2 coords, float compare, float varianceMin, float lightBleedReduction) {
vec2 moments = texture2D(shadowMap, coords.xy).xy;
float p = step(compare, moments.x);
float variance = max(moments.y - moments.x * moments.x, varianceMin);
float d = compare - moments.x;
float pMax = linStep(lightBleedReduction, 1, variance / (variance + d * d));
return min(max(p, pMax), 1);
}
struct Light {
vec3 color;
float intensity;
vec3 direction;
};
struct Material {
float roughness;
float fresnelReflectance;
sampler2D diffuseTexture;
sampler2D normalMap;
sampler2D dispMap;
float dispMapScale;
float dispMapBias;
};
vec3 calcLight(Light light, Material material, vec3 surfaceNormal, vec3 eyePos, vec3 diffuseColor, vec3 specularColor) {
vec3 halfVector = normalize(light.direction + eyePos);
float NdotL = clamp(dot(surfaceNormal, light.direction), 0.0, 1.0);
float NdotH = clamp(dot(surfaceNormal, halfVector), 0.0, 1.0);
float NdotV = clamp(dot(surfaceNormal, eyePos), 0.0, 1.0);
float VdotH = clamp(dot(eyePos, halfVector), 0.0, 1.0);
float rSq = material.roughness * material.roughness;
// ----- Fresnel term -----
float fresnel = pow(1 - VdotH, 5.0);
fresnel *= 1 - material.fresnelReflectance;
fresnel += material.fresnelReflectance;
// ----- Geometric attenuation term -----
float geoNum = 2.0 * NdotV;
float geoB = (geoNum * NdotV) / VdotH;
float geoC = (geoNum * NdotL) / VdotH;
float geo = min(1.0, min(geoB, geoC));
// ----- Roughness term -----
float roughnessA = rSq * pow(NdotH, 4.0);
float roughnessB = (NdotH * NdotH - 1.0) / (rSq * NdotH * NdotH);
float roughness = 1.0 / roughnessA * exp(roughnessB);
// ----- Cook-Torrance calculation -----
vec3 specular = vec3(fresnel * roughness * geo) / (NdotV * NdotL);
return max(0.0, NdotL) * (specularColor * specular + diffuseColor);
}
float calcShadowAmount(sampler2D shadowMap, vec4 initialShadowMapCoords) {
vec3 shadowMapCoords = (initialShadowMapCoords.xyz / initialShadowMapCoords.w);
if (inRange(shadowMapCoords.x) && inRange(shadowMapCoords.y) && inRange(shadowMapCoords.z)) {
return sampleVarianceShadowMap(shadowMap, shadowMapCoords.xy, shadowMapCoords.z, shadowVarianceMin, shadowLightBleedReduction);
} else {
return 1.0;
}
}
float calcBasicShadowAmount(sampler2D shadowMap, vec4 initialShadowMapCoords) {
vec3 shadowMapCoords = (initialShadowMapCoords.xyz / initialShadowMapCoords.w);
return sampleShadowMap(shadowMap, shadowMapCoords.xy, shadowMapCoords.z);
}
void main() {
vec3 directionToEye = normalize(eyePos - worldPos);
vec2 texCoords = calcParallaxTexCoords(dispMap, tbnMatrix, directionToEye, fragTexCoords, dispMapScale, dispMapBias);
vec3 normal = normalize(tbnMatrix * (255.0 / 128.0 * texture2D(normalMap, texCoords).xyz - 1));
gl_FragColor = calcLight(light, material, normal, eyePos, texture2D(diffuse, texCoords), vec3(1, 1, 1));
}
GLSL error reporting conventions are vendor-specific and thus difficult to parse. However, in this case 0:8(18): error: syntax error, unexpected NEW_IDENTIFIER, expecting '{' refers to line 8, character 18.
If you look at your fragment shader, on line 8 you have the following:
uniform Material material;
^ char. 18
The problem here is that you have not yet defined the structure of Material.
You will need to move these structs to precede your uniforms:
struct Light {
vec3 color;
float intensity;
vec3 direction;
};
struct Material {
float roughness;
float fresnelReflectance;
sampler2D diffuseTexture;
sampler2D normalMap;
sampler2D dispMap;
float dispMapScale;
float dispMapBias;
};

How to properly convert GLSL 1.2 code to GLSL 1.5

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?