2017-12-07 17 views
-2

Ich versuche, eine Beleuchtung auf eine erdbasierte Szene mit Phong Shading zu beleuchten. Ich verwende derzeit Gouraud-Schattierungen, die nicht zu dem beabsichtigten Realismus der Sphäre führen. Zusätzlich werde ich mit einem Highlight angezeigt, das an einem Scheitelpunkt passiert, wie man sieht here.Wie benutze ich den Phong Shader in WebGL?

Hier sind die relevanten Codes für meine Szene.

Beleuchtungsberechnungen;

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

Was beste Weg, um dies zu realisieren ist? Welche Art von Beleuchtungsberechnungen müsste ich implementieren?

Welche Schattierung eignet sich am besten für den Realismus einer Kugel?

+0

Wenn ich die Frage zu beantworten, werden Sie die Frage noch einmal, statt ac löschen die Antwort annehmen? – Rabbid76

+0

Bei Phong Shading handelt es sich um eine Interpolation der Oberflächennormalen und um die Berechnung des Lichts pro Pixel. Die Stücke, die du zeigst, scheinen das zu tun, die Stücke, die du nicht zeigst, sind schwer zu kommentieren, und das Testen von halbem Code ist überhaupt nicht möglich. Wenn Sie nur verschiedene Shader sehen und/oder mit eigenen experimentieren wollen, ist http://shadertoy.com eine Seite, die Sie interessant finden können – tevemadar

+0

Dies ist ** nicht ** [Gouraud Shading] (https: // en. wikipedia.org/wiki/Gouraud_shading), bei Gaudoud wird Licht pro Knoten berechnet und für die Fragmente interpoliert. Dies ist [Phong-Schattierung] (https://en.wikipedia.org/wiki/Phong_shading), da das Licht pro Fragment berechnet wird. Das Lichtmodell ist ein [Phong Reflektionsmodell] (https://en.wikipedia.org/wiki/Phong_reflection_model), da das sepkuläre Highlight im Vergleich zum [Blinn-Phong Shading Modell] durch 'reflect' berechnet wird (https: //en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model) wo der Halbwegvektor verwendet wird – Rabbid76

Antwort

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 = 
 
\t \t \t uAmbientLightColor + 
 
\t \t \t uDiffuseLightColor * diffuseLightWeighting + 
 
\t \t \t 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, 
 
\t \t \t \t texelColor.a); 
 
}

Vertex-Shader

void main() { 
 
// Get vertex position in eye coordinates and send to the fragment shader 
 
vec4 vertexPositionEye4 = uMVMatrix * vec4(aVertexPosition, 
 
\t \t \t \t \t 1.0); 
 
vPositionEye3 = vertexPositionEye4.xyz/
 
\t \t \t \t \t 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, 
 
\t \t \t \t \t 1.0); 
 
vTextureCoordinates = aTextureCoordinates; 
 
}

Verwandte Themen