diff --git a/README.md b/README.md index 06fcfd4..2f47d3f 100644 --- a/README.md +++ b/README.md @@ -2,372 +2,52 @@ CIS565: Project 5: WebGL ------------------------------------------------------------------------------- Fall 2013 -------------------------------------------------------------------------------- -Due Friday 11/08/2013 -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -NOTE: -------------------------------------------------------------------------------- -This project requires any graphics card with support for a modern OpenGL -pipeline. Any AMD, NVIDIA, or Intel card from the past few years should work -fine, and every machine in the SIG Lab and Moore 100 is capable of running -this project. - -This project also requires a WebGL capable browser. The project is known to -have issues with Chrome on windows, but Firefox seems to run it fine. - -------------------------------------------------------------------------------- -INTRODUCTION: -------------------------------------------------------------------------------- -In this project, you will get introduced to the world of GLSL in two parts: -vertex shading and fragment shading. The first part of this project is the -Image Processor, and the second part of this project is a Wave Vertex Shader. - -In the first part of this project, you will implement a GLSL vertex shader as -part of a WebGL demo. You will create a dynamic wave animation using code that -runs entirely on the GPU. - -In the second part of this project, you will implement a GLSL fragment shader -to render an interactive globe in WebGL. This will include texture blending, -bump mapping, specular masking, and adding a cloud layer to give your globe a -uniquie feel. - -------------------------------------------------------------------------------- -CONTENTS: -------------------------------------------------------------------------------- -The Project4 root directory contains the following subdirectories: - -* part1/ contains the base code for the Wave Vertex Shader. -* part2/ contains the base code for the Globe Fragment Shader. -* resources/ contains the screenshots found in this readme file. - -------------------------------------------------------------------------------- -PART 1 REQUIREMENTS: -------------------------------------------------------------------------------- - -In Part 1, you are given code for: - -* Drawing a VBO through WebGL -* Javascript code for interfacing with WebGL -* Functions for generating simplex noise - -You are required to implement the following: - -* A sin-wave based vertex shader: - -![Example sin wave grid](resources/sinWaveGrid.png) - -* A simplex noise based vertex shader: - -![Example simplex noise wave grid](resources/oceanWave.png) - -* One interesting vertex shader of your choice ------------------------------------------------------------------------------- -PART 1 WALKTHROUGH: +PART 1 ------------------------------------------------------------------------------- -**Sin Wave** - -* For this assignment, you will need the latest version of Firefox. -* Begin by opening index.html. You should see a flat grid of black and white - lines on the xy plane: - -![Example boring grid](resources/emptyGrid.png) - -* In this assignment, you will animate the grid in a wave-like pattern using a - vertex shader, and determine each vertex’s color based on its height, as seen - in the example in the requirements. -* The vertex and fragment shader are located in script tags in `index.html`. -* The JavaScript code that needs to be modified is located in `index.js`. -* Required shader code modifications: - * Add a float uniform named u_time. - * Modify the vertex’s height using the following code: - - ```glsl - float s_contrib = sin(position.x*2.0*3.14159 + u_time); - float t_contrib = cos(position.y*2.0*3.14159 + u_time); - float height = s_contrib*t_contrib; - ``` - - * Use the GLSL mix function to blend together two colors of your choice based - on the vertex’s height. The lowest possible height should be assigned one - color (for example, `vec3(1.0, 0.2, 0.0)`) and the maximum height should be - another (`vec3(0.0, 0.8, 1.0)`). Use a varying variable to pass the color to - the fragment shader, where you will assign it `gl_FragColor`. +**Sine Wave** -* Required JavaScript code modifications: - * A floating-point time value should be increased every animation step. - Hint: the delta should be less than one. - * To pass the time to the vertex shader as a uniform, first query the location - of `u_time` using `context.getUniformLocation` in `initializeShader()`. - Then, the uniform’s value can be set by calling `context.uniform1f` in - `animate()`. +![alt text](./part1/sineWave.png "sine") **Simplex Wave** -* Now that you have the sin wave working, create a new copy of `index.html`. - Call it `index_simplex.html`, or something similar. -* Open up `simplex.vert`, which contains a compact GLSL simplex noise - implementation, in a text editor. Copy and paste the functions included - inside into your `index_simplex.html`'s vertex shader. -* Try changing s_contrib and t_contrib to use simplex noise instead of sin/cos - functions with the following code: +![alt text](./part1/simplexWave.png "sine") -```glsl -vec2 simplexVec = vec2(u_time, position); -float s_contrib = snoise(simplexVec); -float t_contrib = snoise(vec2(s_contrib,u_time)); -``` +**Sin/cos wave using concentric circles** -**Wave Of Your Choice** +For this wave, I offset the vertices using sin/cos functions based on how fart +the vertex is from the center of the grid. The points furthest away have the most +displacement. -* Create another copy of `index.html`. Call it `index_custom.html`, or - something similar. -* Implement your own interesting vertex shader! In your README.md with your - submission, describe your custom vertex shader, what it does, and how it - works. +![alt text](./part1/waterWave.png "sin/cos") ------------------------------------------------------------------------------- -PART 2 REQUIREMENTS: +PART 2 ------------------------------------------------------------------------------- -In Part 2, you are given code for: - -* Reading and loading textures -* Rendering a sphere with textures mapped on -* Basic passthrough fragment and vertex shaders -* A basic globe with Earth terrain color mapping -* Gamma correcting textures -* javascript to interact with the mouse - * left-click and drag moves the camera around - * right-click and drag moves the camera in and out - -You are required to implement: - -* Bump mapped terrain -* Rim lighting to simulate atmosphere -* Night-time lights on the dark side of the globe -* Specular mapping -* Moving clouds - -You are also required to pick one open-ended effect to implement: - -* Procedural water rendering and animation using noise -* Shade based on altitude using the height map -* Cloud shadows via ray-tracing through the cloud map in the fragment shader -* Orbiting Moon with texture mapping and shadow casting onto Earth -* Draw a skybox around the entire scene for the stars. -* Your choice! Email Liam and Patrick to get approval first - -Finally in addition to your readme, you must also set up a gh-pages branch -(explained below) to expose your beautiful WebGL globe to the world. -Some examples of what your completed globe renderer will look like: +**Globe with procedurally animated water** -![Completed globe, day side](resources/globe_day.png) +![alt text](./part2/globe.png "globe") -Figure 0. Completed globe renderer, daylight side. +**Elevation map with bump mapping** -![Completed globe, twilight](resources/globe_twilight.png) +Press the 1 key to see the elevation map render. -Figure 1. Completed globe renderer, twilight border. +![alt text](./part2/elevation.png "elevation map") -![Completed globe, night side](resources/globe_night.png) +[Here](https://vimeo.com/78964561) is a video of the wave and the globe running +on Firefox. -Figure 2. Completed globe renderer, night side. - -------------------------------------------------------------------------------- -PART 2 WALKTHROUGH: -------------------------------------------------------------------------------- - -Open part2/frag_globe.html in Firefox to run it. You’ll see a globe -with Phong lighting like the one in Figure 3. All changes you need to make -will be in the fragment shader portion of this file. - -![Initial globe](resources/globe_initial.png) - -Figure 3. Initial globe with diffuse and specular lighting. - -**Night Lights** - -The backside of the globe not facing the sun is completely black in the -initial globe. Use the `diffuse` lighting component to detect if a fragment -is on this side of the globe, and, if so, shade it with the color from the -night light texture, `u_Night`. Do not abruptly switch from day to night; -instead use the `GLSL mix` function to smoothly transition from day to night -over a reasonable period. The resulting globe will look like Figure 4. -Consider brightening the night lights by multiplying the value by two. - -The base code shows an example of how to gamma correct the nighttime texture: - -```glsl -float gammaCorrect = 1/1.2; -vec4 nightColor = pow(texture2D(u_Night, v_Texcoord), vec4(gammaCorrect)); -``` - -Feel free to play with gamma correcting the night and day textures if you -wish. Find values that you think look nice! - -![Day/Night without specular mapping](resources/globe_nospecmap.png) - -Figure 4. Globe with night lights and day/night blending at dusk/dawn. - -**Specular Map** - -Our day/night color still shows specular highlights on landmasses, which -should only be diffuse lit. Only the ocean should receive specular highlights. -Use `u_EarthSpec` to determine if a fragment is on ocean or land, and only -include the specular component if it is in ocean. - -![Day/Night with specular mapping](resources/globe_specmap.png) - -Figure 5. Globe with specular map. Compare to Figure 4. Here, the specular -component is not used when shading the land. - -**Clouds** - -In day time, clouds should be diffuse lit. Use `u_Cloud` to determine the -cloud color, and `u_CloudTrans` and `mix` to determine how much a daytime -fragment is affected by the day diffuse map or cloud color. See Figure 6. - -In night time, clouds should obscure city lights. Use `u_CloudTrans` and `mix` -to blend between the city lights and solid black. See Figure 7. - -Animate the clouds by offseting the `s` component of `v_Texcoord` by `u_time` -when reading `u_Cloud` and `u_CloudTrans`. - -![Day with clouds](resources/globe_daycloud.png) - -Figure 6. Clouds with day time shading. - -![Night with clouds](resources/globe_nightcloud.png) - -Figure 7. Clouds observing city nights on the dark side of the globe. - -**Bump Mapping** - -Add the appearance of mountains by perturbing the normal used for diffuse -lighting the ground (not the clouds) by using the bump map texture, `u_Bump`. -This texture is 1024x512, and is zero when the fragment is at sea-level, and -one when the fragment is on the highest mountain. Read three texels from this -texture: once using `v_Texcoord`; once one texel to the right; and once one -texel above. Create a perturbed normal in tangent space: - -`normalize(vec3(center - right, center - top, 0.2))` - -Use `eastNorthUpToEyeCoordinates` to transform this normal to eye coordinates, -normalize it, then use it for diffuse lighting the ground instead of the -original normal. - -![Globe with bump mapping](resources/globe_bumpmap.png) - -Figure 8. Bump mapping brings attention to mountains. - -**Rim Lighting** - -Rim lighting is a simple post-processed lighting effect we can apply to make -the globe look as if it has an atmospheric layer catching light from the sun. -Implementing rim lighting is simple; we being by finding the dot product of -`v_Normal` and `v_Position`, and add 1 to the dot product. We call this value -our rim factor. If the rim factor is greater than 0, then we add a blue color -based on the rim factor to the current fragment color. You might use a color -something like `vec4(rim/4, rim/2, rim/2, 1)`. If our rim factor is not greater -than 0, then we leave the fragment color as is. Figures 0,1 and 2 show our -finished globe with rim lighting. - -For more information on rim lighting, -read http://www.fundza.com/rman_shaders/surface/fake_rim/fake_rim1.html. - -------------------------------------------------------------------------------- -GH-PAGES -------------------------------------------------------------------------------- -Since this assignment is in WebGL you will make your project easily viewable by -taking advantage of GitHub's project pages feature. - -Once you are done you will need to create a new branch named gh-pages: - -`git branch gh-pages` - -Switch to your new branch: - -`git checkout gh-pages` - -Create an index.html file that is either your renamed frag_globe.html or -contains a link to it, commit, and then push as usual. Now you can go to - -`.github.io/` - -to see your beautiful globe from anywhere. - -------------------------------------------------------------------------------- -README -------------------------------------------------------------------------------- -All students must replace or augment the contents of this Readme.md in a clear -manner with the following: - -* A brief description of the project and the specific features you implemented. -* At least one screenshot of your project running. -* A 30 second or longer video of your project running. To create the video you - can use http://www.microsoft.com/expression/products/Encoder4_Overview.aspx -* A performance evaluation (described in detail below). +You can see the globe [here] (http://zxyzhu.github.io/Project5-WebGL/) ------------------------------------------------------------------------------- PERFORMANCE EVALUATION ------------------------------------------------------------------------------- -The performance evaluation is where you will investigate how to make your -program more efficient using the skills you've learned in class. You must have -performed at least one experiment on your code to investigate the positive or -negative effects on performance. - -We encourage you to get creative with your tweaks. Consider places in your code -that could be considered bottlenecks and try to improve them. - -Each student should provide no more than a one page summary of their -optimizations along with tables and or graphs to visually explain any -performance differences. - -------------------------------------------------------------------------------- -THIRD PARTY CODE POLICY -------------------------------------------------------------------------------- -* Use of any third-party code must be approved by asking on the Google groups. - If it is approved, all students are welcome to use it. Generally, we approve - use of third-party code that is not a core part of the project. For example, - for the ray tracer, we would approve using a third-party library for loading - models, but would not approve copying and pasting a CUDA function for doing - refraction. -* Third-party code must be credited in README.md. -* Using third-party code without its approval, including using another - student's code, is an academic integrity violation, and will result in you - receiving an F for the semester. - -------------------------------------------------------------------------------- -SELF-GRADING -------------------------------------------------------------------------------- -* On the submission date, email your grade, on a scale of 0 to 100, to Liam, - liamboone@gmail.com, with a one paragraph explanation. Be concise and - realistic. Recall that we reserve 30 points as a sanity check to adjust your - grade. Your actual grade will be (0.7 * your grade) + (0.3 * our grade). We - hope to only use this in extreme cases when your grade does not realistically - reflect your work - it is either too high or too low. In most cases, we plan - to give you the exact grade you suggest. -* Projects are not weighted evenly, e.g., Project 0 doesn't count as much as - the path tracer. We will determine the weighting at the end of the semester - based on the size of each project. - - ---- -SUBMISSION ---- -As with the previous project, you should fork this project and work inside of -your fork. Upon completion, commit your finished project back to your fork, and -make a pull request to the master repository. You should include a README.md -file in the root directory detailing the following - -* A brief description of the project and specific features you implemented -* At least one screenshot of your project running. -* A link to a video of your project running. -* Instructions for building and running your project if they differ from the - base code. -* A performance writeup as detailed above. -* A list of all third-party code used. -* This Readme file edited as described above in the README section. +I used stats.js from https://github.com/mrdoob/stats.js/ to benchmark my WebGL +application. Both the wave and globe ran at 60 fps. +The elevation map ran slightly faster than the full render since there is no +specular calculation and no cloud animations. +For the wave, performace stayed steady at 60fps for small and medium sized grids. +Performance dropped to to about 55 fps when the grid is 1024*1024, and to 45 fps +at a grid size of 2048*2048. \ No newline at end of file diff --git a/part1/simplexWave.png b/part1/simplexWave.png new file mode 100644 index 0000000..87c75cc Binary files /dev/null and b/part1/simplexWave.png differ diff --git a/part1/sineWave.png b/part1/sineWave.png new file mode 100644 index 0000000..806c059 Binary files /dev/null and b/part1/sineWave.png differ diff --git a/part1/stats.min.js b/part1/stats.min.js new file mode 100644 index 0000000..73744ef --- /dev/null +++ b/part1/stats.min.js @@ -0,0 +1,6 @@ +// stats.js - http://github.com/mrdoob/stats.js +var Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement("div");f.id="stats";f.addEventListener("mousedown",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText="width:80px;opacity:0.9;cursor:pointer";var a=document.createElement("div");a.id="fps";a.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#002";f.appendChild(a);var i=document.createElement("div");i.id="fpsText";i.style.cssText="color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px"; +i.innerHTML="FPS";a.appendChild(i);var c=document.createElement("div");c.id="fpsGraph";c.style.cssText="position:relative;width:74px;height:30px;background-color:#0ff";for(a.appendChild(c);74>c.children.length;){var j=document.createElement("span");j.style.cssText="width:1px;height:30px;float:left;background-color:#113";c.appendChild(j)}var d=document.createElement("div");d.id="ms";d.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#020;display:none";f.appendChild(d);var k=document.createElement("div"); +k.id="msText";k.style.cssText="color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px";k.innerHTML="MS";d.appendChild(k);var e=document.createElement("div");e.id="msGraph";e.style.cssText="position:relative;width:74px;height:30px;background-color:#0f0";for(d.appendChild(e);74>e.children.length;)j=document.createElement("span"),j.style.cssText="width:1px;height:30px;float:left;background-color:#131",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display= +"block";d.style.display="none";break;case 1:a.style.display="none",d.style.display="block"}};return{REVISION:11,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+" MS ("+n+"-"+o+")";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+"px";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+" FPS ("+p+"-"+q+")",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height= +a+"px",m=b,r=0);return b},update:function(){l=this.end()}}}; diff --git a/part1/vert_wave.html b/part1/vert_wave.html index 57107ca..6c2fb2a 100644 --- a/part1/vert_wave.html +++ b/part1/vert_wave.html @@ -14,23 +14,37 @@ attribute vec2 position; uniform mat4 u_modelViewPerspective; + uniform float u_time; + varying vec3 color; + void main(void) { - float height = 0.0; + float s_contrib = sin(position.x*2.0*3.14159 + u_time); + float t_contrib = cos(position.y*2.0*3.14159 + u_time); + float height = s_contrib*t_contrib; + gl_Position = u_modelViewPerspective * vec4(vec3(position, height), 1.0); + + vec3 color1 = vec3(1.0, 215.0/255.0, 0.0); + vec3 color2 = vec3 (128.0/255.0, 0.0, 128.0/255.0); + + //blend them + color = height*color1 + (1.0 - height)*color2; } + diff --git a/part1/vert_wave.js b/part1/vert_wave.js index b90b9cf..ca88b9f 100644 --- a/part1/vert_wave.js +++ b/part1/vert_wave.js @@ -3,8 +3,8 @@ /*global window,document,Float32Array,Uint16Array,mat4,vec3,snoise*/ /*global getShaderSource,createWebGLContext,createProgram*/ - var NUM_WIDTH_PTS = 32; - var NUM_HEIGHT_PTS = 32; + var NUM_WIDTH_PTS = 64; + var NUM_HEIGHT_PTS = 64; var message = document.getElementById("message"); var canvas = document.getElementById("canvas"); @@ -31,6 +31,13 @@ var positionLocation = 0; var heightLocation = 1; var u_modelViewPerspectiveLocation; + var u_gridCenterLocation; + var u_gridCenter = [NUM_WIDTH_PTS / 2.0, NUM_HEIGHT_PTS / 2.0]; + + //time + var u_timeLocation; + var u_time = 0.02; + var add = true; (function initializeShader() { var program; @@ -40,6 +47,8 @@ var program = createProgram(context, vs, fs, message); context.bindAttribLocation(program, positionLocation, "position"); u_modelViewPerspectiveLocation = context.getUniformLocation(program,"u_modelViewPerspective"); + u_timeLocation = context.getUniformLocation(program, "u_time"); + u_gridCenterLocation = context.getUniformLocation(program, "u_gridCenter"); context.useProgram(program); })(); @@ -126,6 +135,16 @@ numberOfIndices = indices.length; })(); + var stats = new Stats(); + stats.setMode(1); // 0: fps, 1: ms + + // Align top-left + stats.domElement.style.position = 'absolute'; + stats.domElement.style.left = '0px'; + stats.domElement.style.top = '0px'; + + document.body.appendChild(stats.domElement); + (function animate(){ /////////////////////////////////////////////////////////////////////////// // Update @@ -142,10 +161,28 @@ // Render context.clear(context.COLOR_BUFFER_BIT | context.DEPTH_BUFFER_BIT); + //pass in uniforms context.uniformMatrix4fv(u_modelViewPerspectiveLocation, false, mvp); + context.uniform1f(u_timeLocation, u_time); + context.uniform2f(u_gridCenterLocation, u_gridCenter[0], u_gridCenter[1]); + + stats.begin(); context.drawElements(context.LINES, numberOfIndices, context.UNSIGNED_SHORT,0); + stats.end(); + + window.requestAnimFrame(animate); + + if (u_time < 50.0 && add) { + u_time += 0.05; + } + else { + u_time += -0.05; + add = false; + if (u_time < 0.0) { + add = true; + } + } - window.requestAnimFrame(animate); })(); }()); diff --git a/part1/vert_wave_custom.html b/part1/vert_wave_custom.html new file mode 100644 index 0000000..733e416 --- /dev/null +++ b/part1/vert_wave_custom.html @@ -0,0 +1,57 @@ + + + +Vertex Wave + + + + + +
+ + + + + + + + + + + + + diff --git a/part1/vert_wave_simplex.html b/part1/vert_wave_simplex.html new file mode 100644 index 0000000..78b8ff0 --- /dev/null +++ b/part1/vert_wave_simplex.html @@ -0,0 +1,94 @@ + + + +Vertex Wave + + + + + +
+ + + + + + + + + + + + + diff --git a/part1/waterWave.png b/part1/waterWave.png new file mode 100644 index 0000000..f1c21e7 Binary files /dev/null and b/part1/waterWave.png differ diff --git a/part2/earthheight1024.png b/part2/earthheight1024.png new file mode 100644 index 0000000..99bacc2 Binary files /dev/null and b/part2/earthheight1024.png differ diff --git a/part2/elevation.png b/part2/elevation.png new file mode 100644 index 0000000..f2696e4 Binary files /dev/null and b/part2/elevation.png differ diff --git a/part2/frag_globe.html b/part2/frag_globe.html index 6aa5609..4909b48 100644 --- a/part2/frag_globe.html +++ b/part2/frag_globe.html @@ -10,6 +10,7 @@
+ + diff --git a/part2/frag_globe.js b/part2/frag_globe.js index 1d8a877..81ff234 100644 --- a/part2/frag_globe.js +++ b/part2/frag_globe.js @@ -54,7 +54,9 @@ var u_CloudTransLocation; var u_EarthSpecLocation; var u_BumpLocation; - var u_timeLocation; + var u_HeightLocation; + var u_TimeLocation; + var u_RenderModeLocation; (function initializeShader() { var vs = getShaderSource(document.getElementById("vs")); @@ -73,9 +75,11 @@ u_CloudLocation = gl.getUniformLocation(program,"u_Cloud"); u_CloudTransLocation = gl.getUniformLocation(program,"u_CloudTrans"); u_EarthSpecLocation = gl.getUniformLocation(program,"u_EarthSpec"); - u_BumpLocation = gl.getUniformLocation(program,"u_Bump"); - u_timeLocation = gl.getUniformLocation(program,"u_time"); - u_CameraSpaceDirLightLocation = gl.getUniformLocation(program,"u_CameraSpaceDirLight"); + u_BumpLocation = gl.getUniformLocation(program, "u_Bump"); + u_HeightLocation = gl.getUniformLocation(program, "u_Height"); + u_TimeLocation = gl.getUniformLocation(program,"u_time"); + u_CameraSpaceDirLightLocation = gl.getUniformLocation(program, "u_CameraSpaceDirLight"); + u_RenderModeLocation = gl.getUniformLocation(program, "u_RenderMode"); gl.useProgram(program); })(); @@ -85,7 +89,8 @@ var cloudTex = gl.createTexture(); var transTex = gl.createTexture(); var lightTex = gl.createTexture(); - var specTex = gl.createTexture(); + var specTex = gl.createTexture(); + var heightTex = gl.createTexture(); function initLoadedTexture(texture){ gl.bindTexture(gl.TEXTURE_2D, texture); @@ -176,6 +181,8 @@ })(); var time = 0; + var renderMode = 1; //default tutorial mode + var mouseLeftDown = false; var mouseRightDown = false; var lastMouseX = null; @@ -228,11 +235,27 @@ lastMouseY = newY; } + function handleKeyPress(event) { + renderMode = event.keyCode; + } + canvas.onmousedown = handleMouseDown; canvas.oncontextmenu = function(ev) {return false;}; document.onmouseup = handleMouseUp; document.onmousemove = handleMouseMove; + document.onkeydown = handleKeyPress; + + //performance stuff + var stats = new Stats(); + stats.setMode(1); // 0: fps, 1: ms + + // Align top-left + stats.domElement.style.position = 'absolute'; + stats.domElement.style.left = '0px'; + stats.domElement.style.top = '0px'; + + document.body.appendChild(stats.domElement); function animate() { /////////////////////////////////////////////////////////////////////////// @@ -267,6 +290,12 @@ gl.uniformMatrix4fv(u_InvTransLocation, false, invTrans); gl.uniform3fv(u_CameraSpaceDirLightLocation, lightdir); + + //pass in time + gl.uniform1f(u_TimeLocation, time); + + //pass in key presses + gl.uniform1i(u_RenderModeLocation, renderMode); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, dayTex); @@ -286,9 +315,18 @@ gl.activeTexture(gl.TEXTURE5); gl.bindTexture(gl.TEXTURE_2D, specTex); gl.uniform1i(u_EarthSpecLocation, 5); - gl.drawElements(gl.TRIANGLES, numberOfIndices, gl.UNSIGNED_SHORT,0); - time += 0.001; + gl.activeTexture(gl.TEXTURE6); + gl.bindTexture(gl.TEXTURE_2D, heightTex); + gl.uniform1i(u_HeightLocation, 6); + + //for performace eval + + stats.begin(); + gl.drawElements(gl.TRIANGLES, numberOfIndices, gl.UNSIGNED_SHORT, 0); + stats.end(); + + time += 0.0002; window.requestAnimFrame(animate); } @@ -300,7 +338,7 @@ initLoadedTexture(texture); // Animate once textures load. - if (++textureCount === 6) { + if (++textureCount === 7) { animate(); } } @@ -313,4 +351,5 @@ initializeTexture(transTex, "earthtrans1024.png"); initializeTexture(lightTex, "earthlight1024.png"); initializeTexture(specTex, "earthspec1024.png"); + initializeTexture(heightTex, "earthheight1024.png"); }()); diff --git a/part2/globe.png b/part2/globe.png new file mode 100644 index 0000000..057b17c Binary files /dev/null and b/part2/globe.png differ diff --git a/part2/stats.min.js b/part2/stats.min.js new file mode 100644 index 0000000..73744ef --- /dev/null +++ b/part2/stats.min.js @@ -0,0 +1,6 @@ +// stats.js - http://github.com/mrdoob/stats.js +var Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement("div");f.id="stats";f.addEventListener("mousedown",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText="width:80px;opacity:0.9;cursor:pointer";var a=document.createElement("div");a.id="fps";a.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#002";f.appendChild(a);var i=document.createElement("div");i.id="fpsText";i.style.cssText="color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px"; +i.innerHTML="FPS";a.appendChild(i);var c=document.createElement("div");c.id="fpsGraph";c.style.cssText="position:relative;width:74px;height:30px;background-color:#0ff";for(a.appendChild(c);74>c.children.length;){var j=document.createElement("span");j.style.cssText="width:1px;height:30px;float:left;background-color:#113";c.appendChild(j)}var d=document.createElement("div");d.id="ms";d.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#020;display:none";f.appendChild(d);var k=document.createElement("div"); +k.id="msText";k.style.cssText="color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px";k.innerHTML="MS";d.appendChild(k);var e=document.createElement("div");e.id="msGraph";e.style.cssText="position:relative;width:74px;height:30px;background-color:#0f0";for(d.appendChild(e);74>e.children.length;)j=document.createElement("span"),j.style.cssText="width:1px;height:30px;float:left;background-color:#131",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display= +"block";d.style.display="none";break;case 1:a.style.display="none",d.style.display="block"}};return{REVISION:11,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+" MS ("+n+"-"+o+")";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+"px";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+" FPS ("+p+"-"+q+")",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height= +a+"px",m=b,r=0);return b},update:function(){l=this.end()}}};