summaryrefslogtreecommitdiffstats
path: root/o3d
diff options
context:
space:
mode:
authorluchen@google.com <luchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-03 21:04:19 +0000
committerluchen@google.com <luchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-03 21:04:19 +0000
commite3dbbb7ad8e5cec9563a6247750db1b7d7f692d1 (patch)
tree4426be3e9ef6c74ad459d24b455434959e07d6b5 /o3d
parent1ac6af94287a2f821a43003b2be2ba21f319a66d (diff)
downloadchromium_src-e3dbbb7ad8e5cec9563a6247750db1b7d7f692d1.zip
chromium_src-e3dbbb7ad8e5cec9563a6247750db1b7d7f692d1.tar.gz
chromium_src-e3dbbb7ad8e5cec9563a6247750db1b7d7f692d1.tar.bz2
Porting the Phong Shader demo to WebGL.
Review URL: http://codereview.chromium.org/2503001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@48868 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d')
-rw-r--r--o3d/samples/o3d-webgl-samples/phongshading.html345
1 files changed, 345 insertions, 0 deletions
diff --git a/o3d/samples/o3d-webgl-samples/phongshading.html b/o3d/samples/o3d-webgl-samples/phongshading.html
new file mode 100644
index 0000000..dffe27f
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/phongshading.html
@@ -0,0 +1,345 @@
+<!--
+Copyright 2009, Google Inc.
+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 Google Inc. nor the names of its
+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.
+-->
+
+<!--
+O3D Tutorial B5
+
+In this tutorial, we generate a simple spherical mesh using Javascript and
+shade it using Phong illumination.
+
+We calculate the various lighting components (ambient,diffuse,specular)
+and combine them in our vertex/pixel shaders to draw the correct color for each
+pixel in the scene.
+
+The scene is illuminated by a single red light and the sphere is white.
+(ie ambient, diffuse, and specular reflection constants of the material = 1)
+
+In this sample, we generate the projection matrix dynamically from the size
+of the o3d plugin.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>
+Tutorial B5: Phong Shading
+</title>
+<!-- Our javascript code -->
+<script type="text/javascript" src="../o3d-webgl/base.js"></script>
+<script type="text/javascript" src="../o3djs/base.js"></script>
+<script type="text/javascript" id="o3dscript">
+o3djs.base.o3d = o3d;
+o3djs.require('o3djs.webgl');
+o3djs.require('o3djs.math');
+o3djs.require('o3djs.rendergraph');
+o3djs.require('o3djs.primitives');
+
+// Events
+// Run the init() function once the page has finished loading.
+// unload() when the page is unloaded.
+window.onload = init;
+window.onunload = unload;
+
+// global variables
+var g_o3d;
+var g_math;
+var g_client;
+var g_o3dElement;
+var g_viewInfo;
+var g_pack;
+var g_o3dWidth = -1;
+var g_o3dHeight = -1;
+
+// Our view and projection matrices
+// The view matrix transforms objects from world space to view space.
+var g_view_matrix;
+// The projection matrix projects objects from view space to the screen.
+var g_proj_matrix;
+
+/**
+ * Creates the client area.
+ */
+function init() {
+ o3djs.webgl.makeClients(initStep2);
+}
+
+/**
+ * Initializes O3D, loads the effect, and draws the sphere.
+ * @param {Array} clientElements Array of o3d object elements.
+ */
+function initStep2(clientElements) {
+ // Initializes global variables and libraries.
+ g_o3dElement = clientElements[0];
+ g_o3d = g_o3dElement.o3d;
+ g_math = o3djs.math;
+ g_client = g_o3dElement.client;
+
+ // Create a g_pack to manage our resources/assets
+ g_pack = g_client.createPack();
+
+ // Create the render graph for a view.
+ g_viewInfo = o3djs.rendergraph.createBasicView(
+ g_pack,
+ g_client.root,
+ g_client.renderGraphRoot);
+
+ /* Load the effect for our sphere from our file.
+ Effects, stored in a hidden textarea for simplicity, contain the
+ functions that define the vertex and pixel shaders used by our shape.
+
+ Here, we calculate phong illumination in our vertex shader and pass the
+ resultant color to our pixel shader, which does nothing except output its
+ given (input) color.
+ */
+ var effect = g_pack.createObject('Effect');
+ effect.loadVertexShaderFromString(document.getElementById('vshader').value);
+ effect.loadPixelShaderFromString(document.getElementById('pshader').value);
+
+ // Create a Material for the effect.
+ var myMaterial = g_pack.createObject('Material');
+
+ // Apply our effect to this material.
+ myMaterial.effect = effect;
+
+ // Set the material's drawList
+ myMaterial.drawList = g_viewInfo.performanceDrawList;
+
+ // Create the params the effect needs on the material.
+ effect.createUniformParameters(myMaterial);
+
+ // Create a sphere at the origin with radius 1.
+ var myShape = o3djs.primitives.createSphere(g_pack,
+ myMaterial,
+ 1,
+ 70,
+ 70);
+
+ // Set up the individual parameters in our effect file.
+
+ // Light position
+ var light_pos_param = myMaterial.getParam('light_pos');
+ light_pos_param.value = [10, 10, 20];
+
+ // Phong components of the light source
+ var light_ambient_param = myMaterial.getParam('light_ambient');
+ var light_diffuse_param = myMaterial.getParam('light_diffuse');
+ var light_specular_param = myMaterial.getParam('light_specular');
+
+ // White ambient light
+ light_ambient_param.value = [0.04, 0.04, 0.04, 1];
+ // Reddish diffuse light
+ light_diffuse_param.value = [0.8, 0, 0, 1];
+ // White specular light
+ light_specular_param.value = [0.5, 0.5, 0.5, 1];
+
+ // Shininess of the material (for specular lighting)
+ var shininess_param = myMaterial.getParam('shininess');
+ shininess_param.value = 30.0;
+
+ // Position of the camera.
+ // (should be the same as the 'eye' position given below)
+ var camera_pos_param = myMaterial.getParam('camera_pos');
+ // Camera is at (0, 0, 3).
+ camera_pos_param.value = [0, 0, 3];
+
+ // Now create our view matrix by defining coordinates for the
+ // target, eye, and up vectors and using the g_math.matrix4.lookAt(..)
+ // helper function to create the matrix.
+
+ // Eye-position, this is where our camera is at.
+ var eye = [0, 0, 3];
+
+ // Target, this is where our camera is pointed at.
+ var target = [0, 0, 0];
+
+ // Up-vector, this tells the camera which direction is 'up'.
+ // We define the positive y-direction to be up in this example.
+ var up = [0, 1, 0];
+
+ g_view_matrix = g_math.matrix4.lookAt(eye, target, up);
+
+ // Generate the projection and viewProjection matrices based
+ // on the g_o3d plugin size by calling resize().
+ resize();
+
+ // Now attach the sphere to the root of the transform graph.
+ var root = g_client.root;
+ root.addShape(myShape);
+
+ // If we don't check the size of the client area every frame we don't get a
+ // chance to adjust the perspective matrix fast enough to keep up with the
+ // browser resizing us.
+ g_client.setRenderCallback(resize);
+}
+
+// Generates the projection matrix based on the size of the o3d plugin
+// and calculates the view-projection matrix.
+function resize() {
+ var newWidth = g_client.width;
+ var newHeight = g_client.height;
+
+ if (newWidth != g_o3dWidth || newHeight != g_o3dHeight) {
+ g_o3dWidth = newWidth;
+ g_o3dHeight = newHeight;
+
+ // Create our projection matrix, with a vertical field of view of 45 degrees
+ // a near clipping plane of 0.1 and far clipping plane of 100.
+ g_proj_matrix = g_math.matrix4.perspective(
+ g_math.degToRad(45),
+ g_o3dWidth / g_o3dHeight,
+ 0.1,
+ 100);
+
+ // Set the view and projection matrix
+ g_viewInfo.drawContext.view = g_view_matrix;
+ g_viewInfo.drawContext.projection = g_proj_matrix;
+ }
+}
+
+/**
+ * Removes any callbacks so they don't get called after the page has unloaded.
+ */
+function unload() {
+ if (g_client) {
+ g_client.cleanup();
+ }
+}
+</script>
+</head>
+<body>
+<table width="100%" style="height:100%;">
+ <tr><td>
+<h1>Phong shading</h1>
+<p>
+This tutorial shows how we generate a custom mesh and
+perform Phong illumination using a shader.
+</p>
+<p>
+This sample displays a Phong shaded white sphere lit by a single red light.
+</p>
+<table id="container" width="90%" style="height:60%;"><tr><td height="100%">
+<!-- Start of g_o3d plugin -->
+<div id="o3d" style="width: 600px; height: 600px;"></div>
+<!-- End of g_o3d plugin -->
+</td></tr></table>
+<!-- Define the vertex shader -->
+<textarea id="vshader" name="vshader" cols="80" rows="20"
+ style="display: none;">
+ // The 4x4 world view projection matrix.
+ uniform mat4 worldViewProjection;
+
+ // positions of the light and camera
+ uniform vec3 light_pos;
+ uniform vec3 camera_pos;
+
+ // input parameters for our vertex shader
+ attribute vec4 position;
+ attribute vec4 color;
+ attribute vec3 normal;
+
+ // pass to the fragment shader
+ varying vec4 pColor;
+ varying vec3 pViewPosition;
+ varying vec3 pLightVector;
+ varying vec3 pNormal;
+
+ void main() {
+
+ // NOTE: In this case we do not need to multiply by any matrices since the
+ // WORLD transformation matrix is the identity. If you were moving the
+ // object such that the WORLD transform matrix was not the identity, you
+ // would need to multiply the normal by the WORLDINVERSETTRANSFORM matrix
+ // since the normal is in object space. Other values (light_pos, camera_pos)
+ // are already in world space.
+
+ vec3 lightVector = light_pos - position.xyz;
+ vec3 viewPosition = camera_pos - position.xyz;
+
+ pLightVector = lightVector;
+ pNormal = normal;
+ pViewPosition = viewPosition;
+ pColor = color;
+
+ gl_Position = worldViewProjection * position;
+ }
+</textarea>
+<!-- Define the fragment shader -->
+<textarea id="pshader" name="pshader" cols="80" rows="20"
+ style="display: none;">
+ // phong lighting components of the light source
+ uniform vec4 light_ambient;
+ uniform vec4 light_diffuse;
+ uniform vec4 light_specular;
+
+ // shininess of the material. (for specular lighting)
+ uniform float shininess;
+
+ // passed from the vertex shader
+ varying vec4 pColor;
+ varying vec3 pViewPosition;
+ varying vec3 pLightVector;
+ varying vec3 pNormal;
+
+ /**
+ * We use the standard phong illumination equation here.
+ * We restrict (clamp) the dot products so that we
+ * don't get any negative values.
+ * All vectors are normalized for proper calculations.
+ *
+ * The output color is the summation of the
+ * ambient, diffuse, and specular contributions.
+ */
+ void main() {
+ vec3 lightVector = normalize(pLightVector);
+ vec3 normal = normalize(pNormal);
+ vec3 viewPosition = normalize(pViewPosition);
+ vec3 halfVector = normalize(pLightVector + pViewPosition);
+
+ // NOTE: This is actually Blinn-Phong shading, not Phong shading
+ // which would use the reflection vector instead of the half vector
+ float dotNormalHalf = dot(normal, halfVector);
+
+ float ambientComp = 1.0;
+ float diffuseComp = max(dot(normal, lightVector), 0.0);
+ float specularComp = dot(normal, lightVector) < 0.0 ||
+ dotNormalHalf < 0.0 ? 0.0 : pow(dotNormalHalf, shininess);
+
+ vec4 ambient = light_ambient * ambientComp * pColor;
+ vec4 diffuse = light_diffuse * diffuseComp * pColor;
+ vec4 specular = light_specular * specularComp * pColor;
+
+ gl_FragColor = ambient + diffuse + specular;
+ }
+</textarea>
+</td></tr></table>
+</body>
+</html>