-1

I am trying to illuminate a lighting to a earth based scene using Phong shading. I am currently using Gouraud shading, which doesn't result in the realism of the sphere as intended. In addition to this I am displayed with a highlight which happens at a vertex as seen

here

Here are the relevant codes to my scene.

Lighting calculations;

<script id="shader-vs" type="x-shader/x-vertex">

attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;
attribute vec2 aTextureCoordinates;

uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat3 uNMatrix;

varying vec2 vTextureCoordinates;
varying vec3 vNormalEye;
varying vec4 vPosition;

void main() {
  vNormalEye = normalize(uNMatrix * aVertexNormal);

  vPosition = uMVMatrix * vec4(aVertexPosition,1.0);
  gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition,1.0);
  vTextureCoordinates = aTextureCoordinates;
}

</script>

<script id="shader-fs" type="x-shader/x-fragment">

precision mediump float;

varying vec2 vTextureCoordinates;
varying vec3 vNormalEye;
varying vec4 vPosition;

uniform sampler2D uSampler;

uniform vec3 uAmbientLightColor;
uniform vec3 uLightPosition;
uniform vec3 uDiffuseLightColor;
uniform vec3 uSpecularLightColor;

const float shine = 32.0;

void main() {

  vec3 direction = normalize(-vPosition.xyz + uLightPosition);
  vec3 reflection = reflect(-direction,vNormalEye);

  float rdotv = max(dot(reflection,direction),0.0);
  float specularLightWeighting = pow(rdotv,shine);

  float directionalLightWeighting = max(dot(vNormalEye,uLightPosition),0.0);
  vec3 vLightWeighting = uAmbientLightColor + uDiffuseLightColor * directionalLightWeighting + uSpecularLightColor * specularLightWeighting;

  vec4 textureColor = texture2D(uSampler,vec2(vTextureCoordinates.s,vTextureCoordinates.t));
  gl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a);
}
</script>

Lighting config;

function setupLights() {

  var angleDegree = 60;
  var lightDistance = 3.5;//Light intensity
  var angleRadian = angleDegree * Math.PI / 180; //Work out 60 degrees from180 degress
  var xDir = Math.cos(angleRadian);
  var yDir = Math.sin(angleRadian);

  gl.uniform3fv(pwgl.uniformLightPositionLoc, [lightDistance * xDir, lightDistance * yDir, 0.0]);
  gl.uniform3fv(pwgl.uniformAmbientLightColorLoc, [0.4, 0.4, 0.4]);
  gl.uniform3fv(pwgl.uniformDiffuseLightColorLoc, [0.7, 0.7, 0.7]);
  gl.uniform3fv(pwgl.uniformSpecularLightColorLoc, [0.8, 0.8, 0.8]);
}

What is this best way to go about this? What sort of lighting calculations would I need to implement?

Also, what type of shading is best suited for a sphere's realism?

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
HeadsR'Us
  • 1
  • 4
  • Phong shading in a nutshell is about interpolating the surface normal and calculating the light on a per-pixel basis. The pieces you show seem to do that, the pieces you do not show are hard to comment, and testing half code is not possible at all. If you just want to see various shaders and/or experiment with own ones, http://shadertoy.com is a site which you may find interesting – tevemadar Dec 07 '17 at 10:11

1 Answers1

0

Fragment shader

void main() {

// Calculate the vector (L) to the light source
vec3 vectorToLightSource = normalize(uLightPosition - vPositionEye3);
// Calculate N dot L for diffuse lighting
float diffuseLightWeighting = max(dot(vNormalEye,
         vectorToLightSource), 0.0);
// Calculate the reflection vector (R) that is needed for specular light
vec3 reflectionVector = normalize(reflect(
       -vectorToLightSource, vNormalEye));
// Calculate viewVector (v) in eye coordinates as
// (0.0, 0.0, 0.0) - vPositionEye3
vec3 viewVectorEye = -normalize(vPositionEye3);
float rdotv = max(dot(reflectionVector, viewVectorEye), 0.0);
float specularLightWeighting = pow(rdotv, shininess);

// Sum up all three reflection components
vec3 lightWeighting =
   uAmbientLightColor +
   uDiffuseLightColor * diffuseLightWeighting +
   uSpecularLightColor * specularLightWeighting;

// Sample the texture
vec4 texelColor = texture2D(uSampler, vTextureCoordinates);
// modulate texel color with lightweigthing and write as final color
gl_FragColor = vec4(lightWeighting.rgb * texelColor.rgb,
    texelColor.a);
}

Vertex shader

void main() {
// Get vertex position in eye coordinates and send to the fragment shader
vec4 vertexPositionEye4 = uMVMatrix * vec4(aVertexPosition,
     1.0);
vPositionEye3 = vertexPositionEye4.xyz /
     vertexPositionEye4.w;
// Transform the normal to eye coordinates and send to fragment shader
vNormalEye = normalize(uNMatrix * aVertexNormal);

// Transform the geometry
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition,
     1.0);
vTextureCoordinates = aTextureCoordinates;
}
HeadsR'Us
  • 1
  • 4