Fakultas Ilmu Komputer UI

Commit fd203cf0 authored by Rachmat Ridwan's avatar Rachmat Ridwan
Browse files

Quickfix: compute normal matrix and fix light shading

parent 32988202
/*
Transpose and inverse matrix function are copyright Gregg Tavares
* Copyright 2014, Gregg Tavares.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Gregg Tavares. nor the names of his
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var m4 = {
// Setup 3x3 transformation matrix object
identity: function () {
......@@ -222,4 +256,127 @@ var m4 = {
scale: function (m, sx, sy, sz) {
return m4.multiply(m, m4.scaling(sx, sy, sz));
},
/**
* Computes the inverse of a matrix.
* @param {Matrix4} m matrix to compute inverse of
* @param {Matrix4} [dst] optional matrix to store result
* @return {Matrix4} dst or a new matrix if none provided
* @memberOf module:webgl-3d-math
*/
inverse: function(m, dst) {
dst = dst || new Float32Array(16);
var m00 = m[0 * 4 + 0];
var m01 = m[0 * 4 + 1];
var m02 = m[0 * 4 + 2];
var m03 = m[0 * 4 + 3];
var m10 = m[1 * 4 + 0];
var m11 = m[1 * 4 + 1];
var m12 = m[1 * 4 + 2];
var m13 = m[1 * 4 + 3];
var m20 = m[2 * 4 + 0];
var m21 = m[2 * 4 + 1];
var m22 = m[2 * 4 + 2];
var m23 = m[2 * 4 + 3];
var m30 = m[3 * 4 + 0];
var m31 = m[3 * 4 + 1];
var m32 = m[3 * 4 + 2];
var m33 = m[3 * 4 + 3];
var tmp_0 = m22 * m33;
var tmp_1 = m32 * m23;
var tmp_2 = m12 * m33;
var tmp_3 = m32 * m13;
var tmp_4 = m12 * m23;
var tmp_5 = m22 * m13;
var tmp_6 = m02 * m33;
var tmp_7 = m32 * m03;
var tmp_8 = m02 * m23;
var tmp_9 = m22 * m03;
var tmp_10 = m02 * m13;
var tmp_11 = m12 * m03;
var tmp_12 = m20 * m31;
var tmp_13 = m30 * m21;
var tmp_14 = m10 * m31;
var tmp_15 = m30 * m11;
var tmp_16 = m10 * m21;
var tmp_17 = m20 * m11;
var tmp_18 = m00 * m31;
var tmp_19 = m30 * m01;
var tmp_20 = m00 * m21;
var tmp_21 = m20 * m01;
var tmp_22 = m00 * m11;
var tmp_23 = m10 * m01;
var t0 = (tmp_0 * m11 + tmp_3 * m21 + tmp_4 * m31) -
(tmp_1 * m11 + tmp_2 * m21 + tmp_5 * m31);
var t1 = (tmp_1 * m01 + tmp_6 * m21 + tmp_9 * m31) -
(tmp_0 * m01 + tmp_7 * m21 + tmp_8 * m31);
var t2 = (tmp_2 * m01 + tmp_7 * m11 + tmp_10 * m31) -
(tmp_3 * m01 + tmp_6 * m11 + tmp_11 * m31);
var t3 = (tmp_5 * m01 + tmp_8 * m11 + tmp_11 * m21) -
(tmp_4 * m01 + tmp_9 * m11 + tmp_10 * m21);
var d = 1.0 / (m00 * t0 + m10 * t1 + m20 * t2 + m30 * t3);
dst[0] = d * t0;
dst[1] = d * t1;
dst[2] = d * t2;
dst[3] = d * t3;
dst[4] = d * ((tmp_1 * m10 + tmp_2 * m20 + tmp_5 * m30) -
(tmp_0 * m10 + tmp_3 * m20 + tmp_4 * m30));
dst[5] = d * ((tmp_0 * m00 + tmp_7 * m20 + tmp_8 * m30) -
(tmp_1 * m00 + tmp_6 * m20 + tmp_9 * m30));
dst[6] = d * ((tmp_3 * m00 + tmp_6 * m10 + tmp_11 * m30) -
(tmp_2 * m00 + tmp_7 * m10 + tmp_10 * m30));
dst[7] = d * ((tmp_4 * m00 + tmp_9 * m10 + tmp_10 * m20) -
(tmp_5 * m00 + tmp_8 * m10 + tmp_11 * m20));
dst[8] = d * ((tmp_12 * m13 + tmp_15 * m23 + tmp_16 * m33) -
(tmp_13 * m13 + tmp_14 * m23 + tmp_17 * m33));
dst[9] = d * ((tmp_13 * m03 + tmp_18 * m23 + tmp_21 * m33) -
(tmp_12 * m03 + tmp_19 * m23 + tmp_20 * m33));
dst[10] = d * ((tmp_14 * m03 + tmp_19 * m13 + tmp_22 * m33) -
(tmp_15 * m03 + tmp_18 * m13 + tmp_23 * m33));
dst[11] = d * ((tmp_17 * m03 + tmp_20 * m13 + tmp_23 * m23) -
(tmp_16 * m03 + tmp_21 * m13 + tmp_22 * m23));
dst[12] = d * ((tmp_14 * m22 + tmp_17 * m32 + tmp_13 * m12) -
(tmp_16 * m32 + tmp_12 * m12 + tmp_15 * m22));
dst[13] = d * ((tmp_20 * m32 + tmp_12 * m02 + tmp_19 * m22) -
(tmp_18 * m22 + tmp_21 * m32 + tmp_13 * m02));
dst[14] = d * ((tmp_18 * m12 + tmp_23 * m32 + tmp_15 * m02) -
(tmp_22 * m32 + tmp_14 * m02 + tmp_19 * m12));
dst[15] = d * ((tmp_22 * m22 + tmp_16 * m02 + tmp_21 * m12) -
(tmp_20 * m12 + tmp_23 * m22 + tmp_17 * m02));
return dst;
},
/**
* Transposes a matrix.
* @param {Matrix4} m matrix to transpose.
* @param {Matrix4} [dst] optional matrix to store result
* @return {Matrix4} dst or a new matrix if none provided
* @memberOf module:webgl-3d-math
*/
transpose: function(m, dst) {
dst = dst || new Float32Array(16);
dst[ 0] = m[0];
dst[ 1] = m[4];
dst[ 2] = m[8];
dst[ 3] = m[12];
dst[ 4] = m[1];
dst[ 5] = m[5];
dst[ 6] = m[9];
dst[ 7] = m[13];
dst[ 8] = m[2];
dst[ 9] = m[6];
dst[10] = m[10];
dst[11] = m[14];
dst[12] = m[3];
dst[13] = m[7];
dst[14] = m[11];
dst[15] = m[15];
return dst;
}
};
\ No newline at end of file
......@@ -6,20 +6,27 @@
<link rel="stylesheet" href="no-2.css">
<link rel="stylesheet" href="no-2-mobile.css">
<script id="vertex-shader" type="x-shader/x-vertex">
precision mediump float;
attribute vec4 vPosition;
attribute vec3 vNormal;
uniform mat4 modelMatrix, viewMatrix, projectionMatrix;
uniform mat4 modelMatrix, viewMatrix, projectionMatrix, normalMatrix;
uniform vec4 lightPosition;
varying vec3 normalInterp;
varying vec4 vertPos4;
varying vec3 vertPos;
varying vec3 lightPos;
void main()
{
vertPos4 = viewMatrix * modelMatrix * vPosition;
// Multiply normal to model matrix view.
normalInterp = (modelMatrix * vec4(vNormal.xyz, 0.0)).xyz;
vec4 vertPos4 = viewMatrix * modelMatrix * vPosition;
vec3 worldPos = vertPos4.xyz;
lightPos = (viewMatrix * vec4(lightPosition.xyz, 1.0)).xyz;
vertPos = vertPos4.xyz;
normalInterp = vec3(normalMatrix * vec4(vNormal, 0.0));
gl_Position = projectionMatrix * vertPos4;
}
</script>
......@@ -27,52 +34,43 @@ void main()
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
// Percentage of mix between normal material shader
// and material shader
uniform float selectingFactor;
uniform mat4 viewMatrix;
varying vec3 normalInterp; // Surface normal
varying vec4 vertPos4; // Vertex position
uniform vec4 lightPosition;
varying vec3 vertPos; // Vertex position
varying vec3 lightPos; // Light position, interpolated
uniform vec4 ambientProduct, diffuseProduct, specularProduct;
uniform float shininess;
void main()
{
// vector from vertex position to light source
vec3 L = normalize( (viewMatrix * lightPosition - vertPos4).xyz );
vec3 E = normalize( -(vertPos4).xyz );
vec3 H = normalize( L + E );
// Percentage of mix between normal material shader
// and material shader
// Transform vertex normal into eye coordinates
uniform float selectingFactor;
vec3 N = normalize(normalInterp.xyz);
void main()
{
vec3 N = normalize(normalInterp);
// Compute diffuse reflection term (see p. 286 Angel 7th ed)
vec3 L = normalize(lightPos - vertPos);
vec3 E = normalize(-vertPos);
vec3 R = normalize(-reflect(L, N));
float Kd = max( dot(L, N), 0.0 );
vec4 diffuse = Kd * diffuseProduct;
// Lambert's cosine law
// Compute specular reflection term (see p. 287 Angel 7th ed)
float lambertian = max(dot(N, L), 0.0);
float specular = 0.0;
float Ks = pow( max(dot(N, H), 0.0), shininess );
vec4 specular = Ks * specularProduct;
if (lambertian > 0.0) {
vec3 R = -reflect(L, N);
vec3 V = normalize(-vertPos);
if( dot(L, N) < 0.0 ) {
specular = vec4(0.0, 0.0, 0.0, 1.0);
float specAngle = max(dot(R, V), 0.0);
specular = pow(specAngle, shininess);
}
// Use ambient
vec4 ambient = ambientProduct;
vec4 fColor = (ambientProduct + lambertian * diffuseProduct + specular * specularProduct);
vec4 selectedColor = vec4(0.0/255.0, 123.0/255.0, 255.0/255.0, 1.0);
vec4 fColor = (ambient + diffuse + specular) * (1.0 - selectingFactor) + selectedColor * selectingFactor;
fColor = fColor * (1.0 - selectingFactor) + selectedColor * selectingFactor;
fColor.a = 1.0;
gl_FragColor = fColor;
......@@ -111,13 +109,18 @@ void main()
<body>
<div class="canvas-wrapper">
<canvas tabindex="1" id="gl-canvas">
<canvas id="gl-canvas">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
<div id="screen-info">
<p id="canvas-status">Canvas aktif dipilih</p>
<div>Objek dipilih: <span id="selobj-hierarchy"><span>body</span><span>black-body</span></span></div>
</div>
<div tabindex="1" id="scroll-detector">
<div>
<div></div>
</div>
</div>
</div>
<div id="menu-toggler-wrapper" class="show-menu">
<button type="button" class="btn btn-primary" id="menu-toggler-button">
......
......@@ -76,9 +76,9 @@ function initializeCameraPosition() {
}
function initializeProjectionMatrix() {
let projectionMatrix = perspective(camera.fovy, camera.aspect, camera.near, camera.far)
camera.projectionMatrix = perspective(camera.fovy, camera.aspect, camera.near, camera.far)
let matrixGlLocation = sceneGraph.glLocations.projectionMatrix
gl.uniformMatrix4fv(matrixGlLocation, false, flatten(projectionMatrix))
gl.uniformMatrix4fv(matrixGlLocation, false, flatten(camera.projectionMatrix))
}
function toggleAnimation() {
......@@ -189,8 +189,8 @@ function updateViewMatrix() {
usedUp = [0, 1, 0]
}
let lookAtMatrix = flatten(lookAt(eye, at, usedUp));
gl.uniformMatrix4fv(sceneGraph.glLocations.viewMatrix, false, flatten(lookAtMatrix));
camera.viewMatrix = flatten(lookAt(eye, at, usedUp));
gl.uniformMatrix4fv(sceneGraph.glLocations.viewMatrix, false, flatten(camera.viewMatrix));
}
let isSpaceKeyPressed = false
......
......@@ -46,6 +46,12 @@ class Renderer {
false,
flatten(model.fullTransformMatrix)
);
gl.uniformMatrix4fv(
glLocations.normalMatrix,
false,
flatten(m4.transpose(m4.inverse(m4.multiply(flatten(camera.viewMatrix), model.fullTransformMatrix))))
);
if (selected) {
gl.uniform1f(glLocations.selectingFactor, 1.0);
......
......@@ -218,6 +218,7 @@ class SceneGraph {
locations.modelMatrix = gl.getUniformLocation(program, "modelMatrix")
locations.viewMatrix = gl.getUniformLocation(program, "viewMatrix")
locations.projectionMatrix = gl.getUniformLocation(program, "projectionMatrix")
locations.normalMatrix = gl.getUniformLocation(program, "normalMatrix")
locations.selectingFactor = gl.getUniformLocation(program, "selectingFactor")
gl.uniform1f(locations.selectingFactor, 0.0)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment