PDA

View Full Version : Help with Gouraud/Phong Shading in Shaders



Primus
03-19-2015, 11:18 AM
I am learning OpenGL and trying to implement basic Gouraud and Phong shading using the following vertex and fragment shaders. For Gouraud shading I want to implement the OpenGL light equation and compute the color at every vertex in the vertex shader, and for phong shading I want to calculate the color for each pixel in the fragment shader. Unfortunately I'm not sure exactly how to implement the lighting equation in these shaders to do that given the variables in them. Could anyone point me in the right direction? It would be greatly appreciated!

Vertex Shader


#version 330

uniform mat4 viewMatrix, projMatrix;
uniform mat3 normalMatrix;

layout (location = 0) in vec4 position;
in vec3 normal;
in vec3 color;

layout(location = 1) in vec2 vertexUV;

out vec3 Color;
out vec3 Normal;
out vec4 Position;

// UV is the texture coordinate of this vertex
out vec2 UV;

void main()
{
Color = color;
Normal = normalize(normalMatrix * normal);
UV = vertexUV;

//geometric transformation
gl_Position = projMatrix * viewMatrix * position;

//shading


}

Fragment Shader


#version 330
uniform mat4 viewMatrix, projMatrix;

uniform vec4 Ambient;
uniform vec3 LightColor;
uniform vec3 LightPosition;
uniform float Shininess;
uniform float Strength;
uniform vec3 EyeDirection;

uniform sampler2D myTextureSampler;

in vec3 Color;
in vec3 Normal;
in vec4 Position;

in vec2 UV;

out vec4 outputF;

void main()
{
//find color first here

outputF = vec4(Color,1);
}

Betrayal
03-21-2015, 03:22 AM
Hello Primus,

i'm just going to post shaders for both cases but don't adapt them to your question. You can probably easily adapt them to match your uniforms and attributes.
Also, the shaders are for multiple light sources and lighting is calculated for both faces of a triangle.
LIGHTCOUNT is not an uniform, just replace it by any number you want programmatically.

Gourad Shading.
Vertex Shader:

#version 430

in vec3 VertexPosition;
in vec3 VertexNormal;
in vec2 VertexTex;

out Data
{
vec3 FrontColor;
vec3 BackColor;
vec2 TexCoord;
} data;

struct LightInfo
{
vec3 Position; //Light Position in eye-coords
vec3 La; //Ambient light intensity
vec3 Ld; //Diffuse light intensity
vec3 Ls; //Specular light intensity
};

struct MaterialInfo
{
vec3 Ka; //Ambient reflectivity
vec3 Kd; //Diffuse reflectivity
vec3 Ks; //Specular reflectivity
float Shininess; //Specular shininess factor
};

uniform LightInfo Light[LIGHTCOUNT];
uniform MaterialInfo Material;

uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;
uniform mat4 MVP;


void getEyeSpace( out vec3 norm, out vec3 position )
{
norm = normalize( NormalMatrix * VertexNormal );
position = vec3( ModelViewMatrix * vec4( VertexPosition, 1 ) );
}

vec3 light( int lightIndex, vec3 position, vec3 norm )
{
vec3 s = normalize( vec3( Light[lightIndex].Position - position ) );
vec3 v = normalize( -position.xyz );
vec3 r = reflect( -s, norm );

vec3 ambient = Light[lightIndex].La * Material.Ka;

float sDotN = max( dot( s, norm ), 0.0 );
vec3 diffuse = Light[lightIndex].Ld * Material.Kd * sDotN;

vec3 spec = vec3( 0.0 );
if ( sDotN > 0.0 )
spec = Light[lightIndex].Ls * Material.Ks * pow( max( dot(r,v) , 0.0 ), Material.Shininess );

return ambient + diffuse + spec;
}

void main()
{
vec3 eyeNorm;
vec3 eyePosition;
getEyeSpace( eyeNorm, eyePosition );

data.FrontColor = vec3(0);
data.BackColor = vec3(0);

for( int i=0; i<LIGHTCOUNT; ++i )
{
data.FrontColor += light( i, eyePosition, eyeNorm );
data.BackColor += light( i, eyePosition, -eyeNorm );
}

data.TexCoord = VertexTex;
gl_Position = MVP * vec4( VertexPosition, 1 );
}


Fragment Shader:

#version 430

in Data
{
vec3 FrontColor;
vec3 BackColor;
vec2 TexCoord;
} data;


out vec4 FragColor;

uniform sampler2D Tex;

void main()
{
if ( gl_FrontFacing )
FragColor = vec4(data.FrontColor, 1);
else
FragColor = vec4(data.BackColor, 1);

FragColor *= texture(Tex, data.TexCoord);
}



Phong Shading.
Vertex Shader:

#version 430

in vec3 VertexPosition;
in vec3 VertexNormal;
in vec2 VertexTex;

out Data
{
vec3 Position;
vec3 Normal;
vec2 TexCoord;
} data;

uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;
uniform mat4 MVP;

void main()
{
data.Normal = normalize( NormalMatrix * VertexNormal );
data.Position = vec3( ModelViewMatrix * vec4( VertexPosition, 1 ) );
data.TexCoord = VertexTex;

gl_Position = MVP * vec4( VertexPosition, 1 );
}


Fragment Shader:

#version 430

struct LightInfo
{
vec3 Position; //Light Position in eye-coords
vec3 La; //Ambient light intensity
vec3 Ld; //Diffuse light intensity
vec3 Ls; //Specular light intensity
};

struct MaterialInfo
{
vec3 Ka; //Ambient reflectivity
vec3 Kd; //Diffuse reflectivity
vec3 Ks; //Specular reflectivity
float Shininess; //Specular shininess factor
};

in Data
{
vec3 Position;
vec3 Normal;
vec2 TexCoord;
} data;

out vec4 FragColor;

uniform LightInfo Light[LIGHTCOUNT];
uniform MaterialInfo Material;
uniform sampler2D Tex;

void light( int lightIndex, vec3 position, vec3 norm, out vec3 ambient, out vec3 diffuse, out vec3 spec )
{
vec3 n = normalize( norm );
vec3 s = normalize( Light[lightIndex].Position - position );
vec3 v = normalize( -position );
vec3 r = reflect( -s, n );

ambient = Light[lightIndex].La * Material.Ka;

float sDotN = max( dot( s, n ), 0.0 );
diffuse = Light[lightIndex].Ld * Material.Kd * sDotN;


spec = Light[lightIndex].Ls * Material.Ks * pow( max( dot(r,v) , 0.0 ), Material.Shininess );
}

void main()
{

vec3 ambientSum = vec3(0);
vec3 diffuseSum = vec3(0);
vec3 specSum = vec3(0);
vec3 ambient, diffuse, spec;

if ( gl_FrontFacing )
{
for( int i=0; i<LIGHTCOUNT; ++i )
{
light( i, data.Position, data.Normal, ambient, diffuse, spec );
ambientSum += ambient;
diffuseSum += diffuse;
specSum += spec;
}
}
else
{
for( int i=0; i<LIGHTCOUNT; ++i )
{
light( i, data.Position, -data.Normal, ambient, diffuse, spec );
ambientSum += ambient;
diffuseSum += diffuse;
specSum += spec;
}
}
ambientSum /= LIGHTCOUNT;

vec4 texColor = texture(Tex, data.TexCoord);

FragColor = vec4( ambientSum + diffuseSum, 1 ) * texColor + vec4( specSum, 1 );
}