WebGL: adding specular light without the help of THREE.JS - glsl

I'm making some first steps in webgl programming. Created a simple setup following this tutorial. Managed to add a few things of my own, though stumbled with adding light, particularly - specular light.
As I assume, most of it would be implemented in my fragment shader, and maybe some additions in the vertex shader and the Light module. So that's the code I provide below.
Vertex shader:
attribute vec3 position;
attribute vec3 normal;
attribute vec2 uv;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
varying vec3 vNormal;
varying vec2 vUv;
void main() {
vUv = uv;
vNormal = (model * vec4(normal, 0.)).xyz;
gl_Position = projection * view * model * vec4(position, 1.);
}
Fragment shader:
#ifdef GL_ES
precision highp float;
#endif
uniform vec3 lightDirection;
uniform float ambientLight;
uniform sampler2D diffuse;
varying vec3 vNormal;
varying vec2 vUv;
void main() {
float lightness = -clamp(dot(normalize(vNormal), normalize(lightDirection)), -1., 0.);
lightness = ambientLight + (1. - ambientLight) * lightness;
gl_FragColor = vec4(texture2D(diffuse, vUv).rgb * lightness, 1.);
}
Light.js module:
function Light () {
this.lightDirection = new Vector3(-1, -1, -1)
this.ambientLight = 0.3
}
Light.prototype.use = function (shaderProgram) {
var dir = this.lightDirection
var gl = shaderProgram.gl
gl.uniform3f(shaderProgram.lightDirection, dir.x, dir.y, dir.z)
gl.uniform1f(shaderProgram.ambientLight, this.ambientLight)
}
I would really appreciate your suggestions here. Thanks in advance!

The most common and simplest light models are the Phong reflection model or the Blinn–Phong model model.
The following shader code, is based on your original code and implements the Blinn–Phong model model. In compare to your code, the light calculations are done in view space, because the specular highlight depends on the view position, which is (0, 0, 0) in view space. So the light direction has to be transformed to view space.
Vertex shader:
attribute vec3 position;
attribute vec3 normal;
attribute vec2 uv;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform vec3 lightDirection;
varying vec3 vPos;
varying vec3 vNormal;
varying vec2 vUv;
varying vec3 lightDirectionView;
void main()
{
lightDirectionView = (view * vec4(lightDirection, 0.)).xyz;
mat4 modelView = view * model;
vec4 viewPos = modelView * vec4(position, 1.0)
vPos = viewPos.xyz;
vUv = uv;
vNormal = (modelView * vec4(normal, 0.)).xyz;
gl_Position = projection * viewPos;
}
Fragemnt shader:
#ifdef GL_ES
precision highp float;
#endif
uniform float shininess;
uniform float ambientLight;
uniform sampler2D diffuse;
varying vec3 vPos;
varying vec3 vNormal;
varying vec2 vUv;
varying vec3 lightDirectionView;
void main()
{
vec3 color = texture2D(diffuse, vUv).rgb;
vec3 N = normalize( vNormal );
vec3 L = normalize( -lightDirectionView );
vec3 V = normalize( -vPos );
vec3 H = normalize( V + L );
float NdotL = dot(N, L);
float NdotH = dot(N, H);
float kDiffuse = max(0.0, NdotL);
// float kSpecular = (shininess + 2.0) * pow(max(0.0, NdotH), shininess) / (2.0 * 3.14159265);
float kSpecular = pow(max(0.0, NdotH), shininess);
vec3 light_col = color * (kDiffuse + kSpecular);
gl_FragColor = vec4(light_col, 1.0);
}
The value of the uniform shininess has to be a positive value in range [1, 100].
See also Phong and Gouraud Shading WebGL.

Related

OpenGL: Problem with lighting when rotating mesh

I'm drawing some static geometry (a sphere, a cube, etc.) together with some dynamic geometry (a rotating torus.)
I can see that there is a problem because specular lighting on the torus is static and the torus is rendered dark when the rotation angle changes...
I'm targeting OpenGL 2.1 (desktop), OpenGL ES2 (mobile) and WebGL1 (web). Here is a gist with the full code. There is also a WebGL demo.
The framework used is chronotext-cross. It provides a level of abstraction above GL. It should be straightforward to understand. In any case I can provide pointers, as the author.
The C++ code, abridged:
void Sketch::setup()
{
Box()
.setFrontFace(CCW)
.setColor(0.75f, 0.75f, 0.75f, 1)
.setSize(300, 5, 300)
.append(geometryBatch, Matrix().translate(-150, -5, -150));
Sphere()
.setFrontFace(CCW)
.setColor(0.25f, 1.0f, 0.0f, 1)
.setSectorCount(60)
.setStackCount(30)
.setRadius(40)
.append(geometryBatch, Matrix().translate(-75, -40, 100));
Torus()
.setFrontFace(CCW)
.setSliceCount(20)
.setLoopCount(60)
.setInnerRadius(12)
.setOuterRadius(48)
.append(torusBatch, Matrix());
}
void Sketch::resize()
{
camera
.setFov(45)
.setClip(0.1f, 1000.0f)
.setWindowSize(windowInfo.size);
}
void Sketch::draw()
{
camera.getViewMatrix()
.setIdentity()
.scale(1, -1, 1)
.translate(0, 0, -400)
.rotateX(-30 * D2R)
.rotateY(15 * D2R);
State state;
state
.setShader(shader)
.setShaderMatrix<MODEL>(Matrix())
.setShaderMatrix<VIEW>(camera.getViewMatrix())
.setShaderMatrix<PROJECTION>(camera.getProjectionMatrix())
.setShaderMatrix<NORMAL>(camera.getNormalMatrix())
.setShaderUniform("u_eye_position", camera.getEyePosition())
.setShaderUniform("u_light_position", camera.getEyePosition())
.setShaderUniform("u_shininess", 50.0f)
.apply();
geometryBatch.flush();
Matrix modelMatrix;
modelMatrix
.translate(75, -60, 100)
.rotateY(clock()->getTime());
state
.setShaderMatrix<MODEL>(modelMatrix)
.apply();
torusBatch.flush();
}
The vertex shader:
attribute vec4 a_position;
attribute vec3 a_normal;
attribute vec4 a_color;
attribute vec2 a_coord;
uniform mat4 u_model_matrix;
uniform mat4 u_view_matrix;
uniform mat4 u_projection_matrix;
uniform mat3 u_normal_matrix;
uniform vec3 u_eye_position;
uniform vec3 u_light_position;
varying vec3 v_normal;
varying vec4 v_color;
varying vec2 v_coord;
varying vec3 v_surface_to_light;
varying vec3 v_surface_to_view;
void main() {
v_normal = u_normal_matrix * a_normal;
v_color = a_color;
v_coord = a_coord;
v_surface_to_light = (u_view_matrix * (vec4(u_light_position, 1.0) - a_position)).xyz;
v_surface_to_view = (u_view_matrix * (vec4(u_eye_position, 1.0) - a_position)).xyz;
gl_Position = u_projection_matrix * u_view_matrix * u_model_matrix * a_position;
}
The fragment shader:
#ifdef GL_ES
precision highp float;
#endif
uniform sampler2D u_sampler;
uniform float u_shininess;
varying vec3 v_normal;
varying vec4 v_color;
varying vec2 v_coord;
varying vec3 v_surface_to_light;
varying vec3 v_surface_to_view;
void main() {
vec3 normal = normalize(v_normal);
vec3 surfaceToLightDirection = normalize(v_surface_to_light);
vec3 surfaceToViewDirection = normalize(v_surface_to_view);
vec3 halfVector = normalize(surfaceToLightDirection + surfaceToViewDirection);
float specular = 0.0;
float light = dot(normal, surfaceToLightDirection);
if (light > 0.0) {
specular = pow(dot(normal, halfVector), u_shininess);
}
vec4 color = v_color * texture2D(u_sampler, v_coord);
gl_FragColor = vec4(color.rgb * light + specular, 1.0);
}
I found the solution: passing a new normal matrix (extracted from the model-view matrix) to the shader when drawing the dynamic mesh.
Matrix modelMatrix;
modelMatrix
.translate(75, -60, 100)
.rotateY(clock()->getTime());
Matrix modelViewMatrix = modelMatrix * camera.getViewMatrix();
state
.setShaderMatrix<MODEL>(modelMatrix)
.setShaderMatrix<NORMAL>(modelViewMatrix.getNormalMatrix())
.apply();

Processing output nothing using gouraud shading

sorry, I am a new on opengl es and processing
below processing and shaders output only background
PShader Gouraud,Phong;
rocket = loadShape("rocket.obj");
rocket.setFill(color(800, 0, 0));
Gouraud= loadShader("gouraudfragment.glsl","gouraudvertex.glsl");
Phong= loadShader("phongfragment.glsl","phongvertex.glsl");
background(0);
pushMatrix();
shader(Gouraud);
translate(130,height/2.0);
rotateY(rc);
rotateX(0.4);
noStroke();
fill(#800080);
box(100);
rc+=(0.02+speedCube);
rc*=dirCube;
popMatrix();
pushMatrix();
shader(Gouraud);
translate(width/2, height/2 + 100, -200);
rotateZ(PI);
rotateY(rr);
shape(rocket,100,100);
rr +=( 0.02+speedRocket);
rr*=dirRocket;
popMatrix();
vertex shader
varying vec3 N;
varying vec3 v;
varying vec4 diffuse;
varying vec4 spec;
attribute vec4 position;
attribute vec3 normal;
uniform mat4 modelview;
uniform mat4 projectionMatrix;
uniform mat3 normalMatrix;
uniform vec4 lightPosition;
uniform vec3 lightAmbient;
uniform vec3 lightDiffuse;
uniform vec3 lightSpecular;
uniform float SpecularPower;
void main()
{
vec4 diffuse;
vec4 spec;
vec4 ambient;
v = vec3(modelview * position);
N = normalize(normalMatrix * normal);
gl_Position = projectionMatrix * position;
vec3 L = normalize(lightPosition.xyz - v);
vec3 E = normalize(-v);
vec3 R = normalize(reflect(-L,N));
ambient = vec4(lightAmbient,100.0);
diffuse = vec4(clamp( lightDiffuse * max(dot(N,L), 0.0) , 0.0, 1.0 ) ,100.0);
spec = vec4(clamp (lightSpecular * pow(max(dot(R,E),0.0),0.3*SpecularPower) , 0.0, 1.0 ),100.0);
color = ambient + diffuse + spec;
}
fragment shader
void main()
{
gl_FragColor = color;
}
please help!
before apply gouraud shading
after apply gouraud shading
The prcessing load the obj and the draw a cube and apply a gouraud shader, but after that only backgroud are shown, the obj loaded and cube is gone. nothing shown!
the shader doesn't even compile and link. The vertex shader has 1 varying output (color), so the framgent shader needs the input varying vec4 color;.
varying vec4 color;
When you set the clip space position, then the vertex coordinate has to be transformed by the model view and projection matrix:
gl_Position = projectionMatrix * modelview * position;
The types specifications of v and N are missing and the types of ambient, diffuse and spec are vec4 rather than vec3.
Vertex shader:
attribute vec4 position;
attribute vec3 normal;
varying vec4 color;
uniform mat4 modelview;
uniform mat4 projectionMatrix;
uniform mat3 normalMatrix;
uniform vec4 lightPosition;
uniform vec3 lightAmbient;
uniform vec3 lightDiffuse;
uniform vec3 lightSpecular;
uniform float SpecularPower;
void main()
{
vec3 v = vec3(modelview * position);
vec3 N = normalize(normalMatrix * normal);
gl_Position = projectionMatrix * modelview * position;
vec3 L = normalize(lightPosition.xyz - v);
vec3 E = normalize(-v);
vec3 R = normalize(reflect(-L,N));
vec4 ambient = vec4(lightAmbient,100.0);
vec4 diffuse = vec4(clamp( lightDiffuse * max(dot(N,L), 0.0) , 0.0, 1.0 ) ,100.0);
vec4 spec = vec4(clamp (lightSpecular * pow(max(dot(R,E),0.0),0.3*SpecularPower) , 0.0, 1.0 ),100.0);
color = ambient + diffuse + spec;
}
Fragment shader:
varying vec4 color;
void main()
{
gl_FragColor = color;
}
Of course you have to set at least an ambient light source ambientLight().
You can use a directionalLight(), pointLight() or spotLight(), too.
But note, your shader can handle 1 light source only. More the 1 light source would gain
OpenGL error 1282 at top endDraw(): invalid operation
If you want to use more than 1 light source then you would have to use uniform arrays int the vertex shader for lightPosition, lightAmbient, lightDiffuse, and lightSpecular. See Types of shaders in Processing(https://processing.org/tutorials/pshader/)

Normal maps and specular with reflections

I'm using ogre3d meshy to view a model. I have written a shader that works with normal maps, reflection, specular maps. But normal maps doesn't work as shown in the picture.
The reflection is working as you see, and sepcular maps is working, but I don't need see the normal maps and bump mapping is working though.
I have tried to disable everything and output the result of the normal maps and its textured and sampled correctly, the same for specular, and for the diffuse map.
Here is the GLSL VS
/*
Environmental Cubic Reflection
NormalMapping
TetxureMapping Scaling
*/
#version 120
#define lowp
#define mediump
#define highp
attribute vec4 vertex;
attribute vec3 normal;
attribute vec4 uv0;
attribute vec4 uv1;
attribute vec4 tangent;
//attribute vec3 binormal;
uniform mat4 normalMatrix;
uniform mat4 modelViewProjectionMatrix;
uniform mat4 modelView;
uniform vec3 camera_world_position;
uniform mat4 textureMatrix0;
varying vec2 texCoord[2];
varying vec3 viewWorld;
varying mat3 world2Tangent;
void main()
{
gl_Position = modelViewProjectionMatrix * vertex;
// transform the uv coordinates
texCoord[0] = (textureMatrix0 * uv0).xy;
texCoord[1] = uv1.xy;
//world.
vec3 vertexWorld = vec3(modelView * vertex);
//transform world to tangent.
//world2Tangent = mat3(normalMatrix) * mat3(tangent, binormal, normal);
// no binormal in ogre?. must reconstruct. Ogre inverts?
vec3 binormal = cross ( normal, tangent.xyz ) * tangent.www;
world2Tangent = mat3(normalMatrix) * mat3(tangent.xyz, binormal, normal);
//Camera Position
//Use Light0 instead of camera position to match phong specular with environment reflection
viewWorld = normalize( - vertexWorld );
}
#version 120
#define lowp
#define mediump
#define highp
uniform sampler2D diffuseColorMap;
uniform sampler2D ambientOcclusionMap;
uniform sampler2D normalMap;
uniform sampler2D specularMap;
uniform samplerCube envMap;
uniform float diffuseFactor;
uniform float reflectionFactor;
uniform float opacity;
varying vec2 texCoord[2];
varying mat3 world2Tangent;
varying vec3 viewWorld;
void main()
{
//unpack current normal in tangent space
vec3 normal = 2.0 * texture2D (normalMap, texCoord[0].st).rgb - 1.0;
// environment reflection in world space
vec3 normalWorld = normalize(world2Tangent * normal);
vec3 refDir = viewWorld - 2.0 * dot(viewWorld,normalWorld) * normalWorld;
vec4 diffuseColor = texture2D( diffuseColorMap, texCoord[0] );
//mix ambient material with reflection
vec4 final = diffuseFactor * ( diffuseColor * texture2D(ambientOcclusionMap, texCoord[0]) ) +
reflectionFactor * ( textureCube(envMap,refDir) * texture2D(specularMap, texCoord[0]) );
final.a = diffuseColor.a * opacity;
gl_FragColor= final;
}

Errors on phong shading (over texture) implementation in my shaders

I am trying to learn webGL, tried to implemement phong shading following this sample code on the link http://voxelent.com/html/beginners-guide/chapter_3/ch3_Sphere_Phong.html
I get two errors on shader compilation, and consequently there is no moon displayed, which is supposed to be display as i am following Lesson11 of GitHUB where they make sphere from rectangles , the errors i got are :
ERROR: 0:49: '*' : wrong operand types no operation '*' exists that takes a left-hand operand of type 'mediump 3-component vector of float' and a right operand of type 'mediump 4-component vector of float' (or there is no acceptable conversion)
And my full code is :
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec2 vTextureCoord;
varying vec3 vLightWeighting;
uniform sampler2D uSampler;
uniform float uShininess; //shininess
uniform vec3 uLightDirection; //light direction
uniform vec4 uLightAmbient; //light ambient property
uniform vec4 uLightDiffuse; //light diffuse property
uniform vec4 uLightSpecular; //light specular property
uniform vec4 uMaterialAmbient; //object ambient property
uniform vec4 uMaterialDiffuse; //object diffuse property
uniform vec4 uMaterialSpecular; //object specular property
varying vec3 vNormal;
varying vec3 vEyeVec;
void main(void)
{
vec3 L = normalize(uLightDirection);
vec3 N = normalize(vNormal);
//Lambert's cosine law
float lambertTerm = dot(N,-L);
//Ambient Term
vec4 Ia = uLightAmbient * uMaterialAmbient;
//Diffuse Term
vec4 Id = vec4(0.0,0.0,0.0,1.0);
//Specular Term
vec4 Is = vec4(0.0,0.0,0.0,1.0);
if(lambertTerm > 0.0) //only if lambertTerm is positive
{
Id = uLightDiffuse * uMaterialDiffuse * lambertTerm; //add diffuse term
vec3 E = normalize(vEyeVec);
vec3 R = reflect(L, N);
float specular = pow( max(dot(R, E), 0.0), uShininess);
Is = uLightSpecular * uMaterialSpecular * specular; //add specular term
}
//Final color
vec4 finalColor =Ia + Id + Is;
finalColor.a = 1.0;
vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
gl_FragColor = vec4(textureColor.rgb * finalColor, textureColor.a);
}
</script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;
attribute vec2 aTextureCoord;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat3 uNMatrix;
uniform vec3 uAmbientColor;
uniform vec3 uLightingDirection;
uniform vec3 uDirectionalColor;
uniform bool uUseLighting;
varying vec2 vTextureCoord;
varying vec3 vLightWeighting;
varying vec3 vNormal;
varying vec3 vEyeVec;
void main(void)
{
//Transformed vertex position
vec4 vertex= uMVMatrix * vec4(aVertexPosition, 1.0);
//Transformed normal position
vNormal = vec3(uNMatrix * vec4(aVertexNormal, 1.0));
//Vector Eye
vEyeVec = -vec3(vertex.xyz);
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vTextureCoord = aTextureCoord;
}
</script>
EDIT2:
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec2 vTextureCoord;
varying vec3 vLightWeighting;
uniform sampler2D uSampler;
uniform float uShininess; //shininess
uniform vec3 uLightDirection; //light direction
uniform vec4 uLightAmbient; //light ambient property
uniform vec4 uLightDiffuse; //light diffuse property
uniform vec4 uLightSpecular; //light specular property
uniform vec4 uMaterialAmbient; //object ambient property
uniform vec4 uMaterialDiffuse; //object diffuse property
uniform vec4 uMaterialSpecular; //object specular property
varying vec3 vNormal;
varying vec3 vEyeVec;
void main(void)
{
vec3 L = normalize(uLightDirection);
vec3 N = normalize(vNormal);
//Lambert's cosine law
float lambertTerm = dot(N,-L);
//Ambient Term
vec4 Ia = uLightAmbient * uMaterialAmbient;
//Diffuse Term
vec4 Id = vec4(0.0,0.0,0.0,1.0);
//Specular Term
vec4 Is = vec4(0.0,0.0,0.0,1.0);
if(lambertTerm > 0.0) //only if lambertTerm is positive
{
Id = uLightDiffuse * uMaterialDiffuse * lambertTerm; //add diffuse term
vec3 E = normalize(vEyeVec);
vec3 R = reflect(L, N);
float specular = pow( max(dot(R, E), 0.0), uShininess);
Is = uLightSpecular * uMaterialSpecular * specular; //add specular term
}
//Final color
vec4 finalColor =Ia + Id + Is;
finalColor.a = 1.0;
vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
gl_FragColor = vec4(textureColor.rgb, textureColor.a)+finalColor;
}
</script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;
attribute vec2 aTextureCoord;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat3 uNMatrix;
uniform vec3 uAmbientColor;
uniform vec3 uLightingDirection;
uniform vec3 uDirectionalColor;
uniform bool uUseLighting;
varying vec2 vTextureCoord;
varying vec3 vLightWeighting;
varying vec3 vNormal;
varying vec3 vEyeVec;
void main(void)
{
//Transformed vertex position
vec4 vertex= uMVMatrix * vec4(aVertexPosition, 1.0);
//Transformed normal position
vNormal = vec3(uNMatrix * vec3(aVertexNormal));
//Vector Eye
vEyeVec = -vec3(vertex.xyz);
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vTextureCoord = aTextureCoord;
}
</script>
How to display moon with phong shading effects. Could someone please help me ?
The error message is unambiguous: You try to multiply a vec3 by a vec4, which obvoiusly does not make sense at all. It also tells you that the error is in line 49 of the shader:
gl_FragColor = vec4(textureColor.rgb * finalColor, textureColor.a);
// ^ finalColor is a vec4!
You probably meant to tuse finalColor.rgb here.

Modern GLSL ( opengl 3+ ) : Implementing phong effect correctly;

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