diff --git a/Links.txt b/Links.txt
new file mode 100644
index 0000000..909f324
--- /dev/null
+++ b/Links.txt
@@ -0,0 +1,9 @@
+http://msdn.microsoft.com/en-us/library/ie/dn302449(v=vs.85).aspx
+http://workshop.chromeexperiments.com/examples/gui/#4--Color-Controllers
+http://jsfiddle.net/mortennobel/URvtx/
+http://bl.ocks.org/g-k/5847236
+http://jayconrod.com/posts/34/water-simulation-in-glsl
+https://glsleffects.codeplex.com/wikipage?title=Ripple
+http://www.dreamincode.net/forums/topic/66480-perlin-noise/
+https://github.com/mrdoob/stats.js
+http://gamedev.stackexchange.com/questions/60313/implementing-a-skybox-with-glsl-version-330
\ No newline at end of file
diff --git a/Pics/All Effects.bmp b/Pics/All Effects.bmp
new file mode 100644
index 0000000..b769eec
Binary files /dev/null and b/Pics/All Effects.bmp differ
diff --git a/Pics/HeightMap Shader.bmp b/Pics/HeightMap Shader.bmp
new file mode 100644
index 0000000..4344b7b
Binary files /dev/null and b/Pics/HeightMap Shader.bmp differ
diff --git a/Pics/Ripple.bmp b/Pics/Ripple.bmp
new file mode 100644
index 0000000..a84d395
Binary files /dev/null and b/Pics/Ripple.bmp differ
diff --git a/Pics/Vertex Wave.bmp b/Pics/Vertex Wave.bmp
new file mode 100644
index 0000000..ce6f5e7
Binary files /dev/null and b/Pics/Vertex Wave.bmp differ
diff --git a/Pics/Water.bmp b/Pics/Water.bmp
new file mode 100644
index 0000000..3d84df7
Binary files /dev/null and b/Pics/Water.bmp differ
diff --git a/README.md b/README.md
index 2d26873..701b3f9 100644
--- a/README.md
+++ b/README.md
@@ -1,123 +1,37 @@
--------------------------------------------------------------------------------
+=======================================
CIS565: Project 5: WebGL
--------------------------------------------------------------------------------
-Fall 2014
--------------------------------------------------------------------------------
-Due Monday 11/03/2014
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-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.
+======================================
+Fall 2014
+Bo Zhang
-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 Project5 root directory contains the following subdirectories:
-
-* js/ contains the javascript files, including external libraries, necessary.
-* assets/ contains the textures that will be used in the second half of the
- assignment.
-* resources/ contains the screenshots found in this readme file.
-
--------------------------------------------------------------------------------
-PART 1 REQUIREMENTS:
--------------------------------------------------------------------------------
-
-In Part 1, you are given code for:
+##Overview
-* 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:
-
-
-
-* One interesting vertex shader of your choice
+This is a WebGL project based on implementation of GLSL vertex shader and GLSL fragment shader.
-------------------------------------------------------------------------------
-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:
-
-
+* Sin-wave based vertex shader:
+
+* Ripple Shader:
+
-* 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`.
-
- * Using dat.gui, you will add color pickers to modify the max and min colors
- via GUI. You will do this by adding the proper uniforms to the fragment
- shader, and using the addColor function from dat.GUI.
-
-* 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()`.
-
-**Wave Of Your Choice**
-
-* 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.
+About ripple:
+I implement the ripple shader based on this link: https://glsleffects.codeplex.com/wikipage?title=Ripple, the main idea is as fllowing:
+```
+ float dist = distance(vec2(position.x,position.y),vec2(CenterPointX,CenterPointY));
+ float height = Amplitude*sin(dist/(Wavelength/10.0) + u_time)*pow(Attenuation,dist);
+```
+* "CenterPoint" is the source of ripple, all circles of a ripple should has the same center point.
+* "Amplitude" the amplitude defines how big the was is. The range of sin(x) is [-1,1], so, the height of ripple should be amplitude*sin(x). The x is the distance between current point and the center point, will be discussed next.
+* "Attenuation", the power of a wave will weak down as it travels, the attenuation factor defines how fast the wave will weak down.
+* "Wavelength" is how far the adjacent two points of the same height is.
+PART 2:
-------------------------------------------------------------------------------
-PART 2 REQUIREMENTS:
--------------------------------------------------------------------------------
-In Part 2, you are given code for:
-
+Given Features:
* Reading and loading textures
* Rendering a sphere with textures mapped on
* Basic passthrough fragment and vertex shaders
@@ -127,236 +41,45 @@ In Part 2, you are given code for:
* left-click and drag moves the camera around
* right-click and drag moves the camera in and out
-You are required to implement:
-
+Basic Features:
* 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:
-
+Extra Features:
* 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.
+#### Procedural water rendering and animation using noise
+To implement this feature, I make a perlin noise generator based on this link(http://www.dreamincode.net/forums/topic/66480-perlin-noise/):
+The only different thing is that we can't use bitwise operators in glsl, so I use a rand generator for the findnoise(). I adjust the parameters and here is the final effect (See the waves on ocean):
+
+
+
+#### Shade based on altitude using the height map
+To implement this feature, I mix the user-chosen colors with the original color on land according to the altitude of the land. And here is the result with heightmap based shader:
+
-Some examples of what your completed globe renderer will look like:
-
-
-
-Figure 0. Completed globe renderer, daylight side.
-
-
-
-Figure 1. Completed globe renderer, twilight border.
-
-
-
-Figure 2. Completed globe renderer, night side.
+Performance Evaluation
-------------------------------------------------------------------------------
-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.
-
-
-
-Figure 3. Initial globe with diffuse and specular lighting.
-
-**Night Lights**
+Currently, the frame rate counter always shows 60 FPS no matter I enable all the extra effects or not.
-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!
-
-
-
-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.
-
-
-
-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`.
-
-
-
-Figure 6. Clouds with day time shading.
-
-
-
-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.
-
-
-
-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/rim_effects/index.html.
-
--------------------------------------------------------------------------------
-GH-PAGES
+Third Party Code
-------------------------------------------------------------------------------
-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.
+* JavaScript Performance Monitor(https://github.com/mrdoob/stats.js)
+I use this to do the Performance Evaluation.
+Personal Link
-------------------------------------------------------------------------------
-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).
+http://youtu.be/tTX-V_cDxzY
+Web Page
-------------------------------------------------------------------------------
-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.
-
-In this homework, we do not expect crazy performance evaluation in terms of
-optimizations. However, it would be good to take performance benchmarks at
-every step in this assignment to see how complicated fragment shaders affect the
-overall speed. You can do this by using stats.js.
+http://wulinjiansheng.github.io/Project5-WebGL/
--------------------------------------------------------------------------------
-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 Harmony,
- harmoli+cis565@seas.upenn.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.
diff --git a/frag_globe.html b/frag_globe.html
index e074492..42f9b58 100644
--- a/frag_globe.html
+++ b/frag_globe.html
@@ -1,119 +1,263 @@
-
-Fragment Globe
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ normal = eastNorthUpToEyeCoordinates(v_positionMC,v_Normal) * normal;
+ normal = normalize(normal);
+
+ // normalized eye-to-position vector in camera coordinates
+ vec3 eyeToPosition = normalize(v_Position);
+
+ float diffuse = clamp(dot(u_CameraSpaceDirLight, normal), 0.0, 1.0);
+
+ vec3 toReflectedLight = reflect(-u_CameraSpaceDirLight, normal);
+ float specular = max(dot(toReflectedLight, -eyeToPosition), 0.0);
+ specular = pow(specular, 20.0);
+
+ float gammaCorrect = 1.0/1.2; //gamma correct by 1/1.2
+
+ vec3 dayColor = texture2D(u_DayDiffuse, v_Texcoord).rgb;
+ vec3 nightColor = texture2D(u_Night, v_Texcoord).rgb;
+ //apply gamma correction to nighttime texture
+ nightColor = pow(nightColor,vec3(gammaCorrect));
+
+ if(EarthSpec<0.5)
+ {
+ specpart = 0.0;
+ specular = 0.0;
+ diffpart = 1.0;
+ }
+
+ vec3 color;
+
+ float altitude = texture2D(u_Bump, v_Texcoord).r;
+ vec3 d_color = ((diffpart * diffuse) + (specpart * specular)) * dayColor;
+ vec3 n_color = nightColor;
+ if(EarthSpec<0.1 && u_heightmap==1)
+ {
+ vec3 hcolor;
+ if(altitude>=0.0 && altitude <= 0.3)
+ hcolor = u_hcolor1/255.0;
+ else if(altitude>0.3 && altitude <= 0.6)
+ {
+ float mixa = (altitude - 0.3) / 0.3;
+ hcolor = mix(u_hcolor1/255.0,u_hcolor2/255.0,mixa);
+ }
+ else if(altitude>0.6)
+ {
+ float mixa = (altitude - 0.6) / 0.4;
+ hcolor = mix(u_hcolor2/255.0,u_hcolor3/255.0,mixa);
+ }
+
+ d_color = mix(d_color,hcolor,altitude);
+ }
+
+
+
+ //Clouds
+ vec3 cloudsColor = texture2D(u_Cloud,vec2(v_Texcoord.s - 0.05 * u_time,v_Texcoord.t)).rgb;
+ float cloudMix = texture2D(u_CloudTrans,vec2(v_Texcoord.s - 0.05 * u_time,v_Texcoord.t)).r;
+ d_color = mix(cloudsColor,d_color,cloudMix);
+ n_color = 1.5 * mix(vec3(0.0,0.0,0.0),n_color,cloudMix);
+
+ //Night Lights
+ float rperiod = 0.1; //transition from day to night
+ float diffjudge = dot(u_CameraSpaceDirLight, normal);
+ if(diffjudge >= rperiod)
+ color = d_color;
+ else if(diffjudge <= -rperiod)
+ color = n_color;
+ else
+ {
+ float alpha = (diffjudge + rperiod)/(2.0*rperiod);
+ color = mix(n_color,d_color,alpha);
+ }
+
+ //Rim Lighting
+ float rim = dot(v_Normal,v_Position) + 1.0;
+ vec3 rimcolor = vec3(0.0,0.0,0.0);
+ if(rim>0.0)
+ rimcolor = vec3(rim/4.0, rim/2.0, rim/2.0);
+
+ rimcolor = clamp(rimcolor, vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0));
+ gl_FragColor = vec4(color + rimcolor, 1.0);
+}
+
+mat3 eastNorthUpToEyeCoordinates(vec3 positionMC, vec3 normalEC)
+{
+ // normalized surface tangent in model coordinates
+ vec3 tangentMC = normalize(vec3(-positionMC.z, positionMC.x, 0.0));
+ // normalized surface tangent in eye coordiantes
+ vec3 tangentEC = normalize(mat3(u_InvTrans) * tangentMC);
+ // normalized surface bitangent in eye coordinates
+ vec3 bitangentEC = normalize(cross(normalEC, tangentEC));
+
+ return mat3(
+ tangentEC.x, tangentEC.y, tangentEC.z,
+ bitangentEC.x, bitangentEC.y, bitangentEC.z,
+ normalEC.x, normalEC.y, normalEC.z);
+}
+
+
+
+
+
+
+
+
-