diff --git a/README.md b/README.md
index 09e7f12..f51e43e 100644
--- a/README.md
+++ b/README.md
@@ -3,443 +3,60 @@ WebGL Deferred Shading
**University of Pennsylvania, CIS 565: GPU Programming and Architecture, Project 6**
-* (TODO) YOUR NAME HERE
-* Tested on: (TODO) **Google Chrome 222.2** on
- Windows 22, i7-2222 @ 2.22GHz 22GB, GTX 222 222MB (Moore 2222 Lab)
+* Sanchit Garg
+* Tested on: Safari Version 9.0.1 on
+ Mac OSX 10.10.4, i7 @ 2.4 GHz, GT 650M 1GB (Personal Computer)
### Live Online
-[](http://TODO.github.io/Project6-WebGL-Deferred-Shading)
+[](http://sanchitgarg.github.io/Project6-WebGL-Deferred-Shading/)
### Demo Video
-[](TODO)
+[](https://youtu.be/QB3VgeCDwlk)
-### (TODO: Your README)
+### Deferred Shader
-*DO NOT* leave the README to the last minute! It is a crucial part of the
-project, and we will not be able to grade you without a good README.
+Implemented the scissor test, toon shader, sphere proxy in WebGL.
-This assignment has a considerable amount of performance analysis compared
-to implementation work. Complete the implementation early to leave time!
+===============================================================
+### Toon Shader
-Instructions (delete me)
-========================
+I implemented a ramp based toon shader.
-This is due at midnight on the evening of Tuesday, October 27.
+
-**Summary:** In this project, you'll be introduced to the basics of deferred
-shading and WebGL. You'll use GLSL and WebGL to implement a deferred shading
-pipeline and various lighting and visual effects.
+This did not have any measurable performace impact.
-**Recommendations:**
-Take screenshots as you go. Use them to document your progress in your README!
+===============================================================
-Read (or at least skim) the full README before you begin, so that you know what
-to expect and what to prepare for.
+#### Debug Views
-### Running the code
+
+
-If you have Python, you should be able to run `server.py` to start a server.
-Then, open [`http://localhost:10565/`](http://localhost:10565/) in your browser.
+Depth view ............................. Points view
-This project requires a WebGL-capable web browser with support for
-`WEBGL_draw_buffers`. You can check for support on
-[WebGL Report](http://webglreport.com/).
+
+
-Google Chrome seems to work best on all platforms. If you have problems running
-the starter code, use Chrome or Chromium, and make sure you have updated your
-browser and video drivers.
+Color Map view .......................... Normal Map view
-In Moore 100C, both Chrome and Firefox work.
-See below for notes on profiling/debugging tools.
+
+
-Use the screenshot button to save a screenshot.
+Geometry Normals view ................... Surface Normals view
-## Requirements
+===============================================================
-**Ask on the mailing list for any clarifications.**
+###Performance Analysis
-In this project, you are given code for:
+I used the default scissor test. It gives a speed up of about 2x. This was tested with 20 lights. The time comparison (in ms) is as follows
-* Loading OBJ files and color/normal map textures
-* Camera control
-* Partial implementation of deferred shading including many helper functions
+
-### Required Tasks
+Looking at the impact of number of lights, we see that as we increse the number of lights, the FPS drops. A comparison of the FPS between with scissor test and without can be seen below.
-**Before doing performance analysis,** you must disable debug mode by changing
-`debugMode` to `false` in `framework.js`. Keep it enabled when developing - it
-helps find WebGL errors *much* more easily.
+
-You will need to perform the following tasks:
-
-* Complete the deferred shading pipeline so that the Blinn-Phong and Post1
- shaders recieve the correct input. Go through the Starter Code Tour **before
- continuing!**
-
-**Effects:**
-
-* Implement deferred Blinn-Phong shading (diffuse + specular) for point lights
- * With normal mapping (code provided)
- * For deferred shading, you want to use a lighting model for the point lights
- which has a limited radius - so that adding a scissor or proxy geometry
- will not cause parts of the lighting to disappear. It should look very
- similar both with and without scissor/proxy optimization. Here is a
- convenient lighting model, but you can also use others:
- * `float attenuation = max(0.0, u_lightRad - dist_from_surface_to_light);`
-
-* Implement one of the following effects:
- * Bloom using post-process blur (box or Gaussian) [1]
- * Toon shading (with ramp shading + simple depth-edge detection for outlines)
-
-**Optimizations:**
-
-* Scissor test optimization: when accumulating shading from each point
- light source, only render in a rectangle around the light.
- * Show a debug view for this (showing scissor masks clearly), e.g. by
- modifying and using `red.frag.glsl` with additive blending and alpha = 0.1.
- * Code is provided to compute this rectangle for you, and there are
- comments at the relevant place in `deferredRender.js` with more guidance.
- * **NOTE:** The provided scissor function is not very accurate - it is a
- quick hack which results in some errors (as can be seen in the live
- demo).
-
-* Optimized g-buffer format - reduce the number and size of g-buffers:
- * Ideas:
- * Pack values together into vec4s
- * Use 2-component normals
- * Quantize values by using smaller texture types instead of gl.FLOAT
- * Reduce number of properties passed via g-buffer, e.g. by:
- * Applying the normal map in the `copy` shader pass instead of
- copying both geometry normals and normal maps
- * Reconstructing world space position using camera matrices and X/Y/depth
- * For credit, you must show a good optimization effort and record the
- performance of each version you test, in a simple table.
- * It is expected that you won't need all 4 provided g-buffers for a basic
- pipeline - make sure you disable the unused ones.
- * See mainly: `copy.frag.glsl`, `deferred/*.glsl`, `deferredSetup.js`
-
-### Extra Tasks
-
-You must do at least **10 points** worth of extra features (effects or
-optimizations/analysis).
-
-**Effects:**
-
-* (3pts) The effect you didn't choose above (bloom or toon shading)
-
-* (3pts) Screen-space motion blur (blur along velocity direction) [3]
-
-* (2pts) Allow variability in additional material properties
- * Include other properties (e.g. specular coeff/exponent) in g-buffers
- * Use this to render objects with different material properties
- * These may be uniform across one model draw call, but you'll have to show
- multiple models
-
-**Optimizations/Analysis:**
-
-* (2pts) Improved screen-space AABB for scissor test
- (smaller/more accurate than provided - but beware of CPU/GPU tradeoffs)
-
-* (3pts) Two-pass **Gaussian** blur using separable convolution (using a second
- postprocess render pass) to improve bloom or other 2D blur performance
-
-* (4-6pts) Light proxies
- * (4pts) Instead of rendering a scissored full-screen quad for every light,
- render some proxy geometry which covers the part of the screen affected by
- the light (e.g. a sphere, for an attenuated point light).
- * A model called `sphereModel` is provided which can be drawn in the same
- way as the code in `drawScene`. (Must be drawn with a vertex shader which
- scales it to the light radius and translates it to the light position.)
- * (+2pts) To avoid lighting geometry far behind the light, render the proxy
- geometry (e.g. sphere) using an inverted depth test
- (`gl.depthFunc(gl.GREATER)`) with depth writing disabled (`gl.depthMask`).
- This test will pass only for parts of the screen for which the backside of
- the sphere appears behind parts of the scene.
- * Note that the copy pass's depth buffer must be bound to the FBO during
- this operation!
- * Show a debug view for this (showing light proxies)
- * Compare performance of this, naive, and scissoring.
-
-* (8pts) Tile-based deferred shading with detailed performance comparison
- * On the CPU, check which lights overlap which tiles. Then, render each tile
- just once for all lights (instead of once for each light), applying only
- the overlapping lights.
- * The method is described very well in
- [Yuqin & Sijie's README](https://github.com/YuqinShao/Tile_Based_WebGL_DeferredShader/blob/master/README.md#algorithm-details).
- * This feature requires allocating the global light list and tile light
- index lists as shown at this link. These can be implemented as textures.
- * Show a debug view for this (number of lights per tile)
-
-* (6pts) Deferred shading without multiple render targets
- (i.e. without WEBGL_draw_buffers).
- * Render the scene once for each target g-buffer, each time into a different
- framebuffer object.
- * Include a detailed performance analysis, comparing with/without
- WEBGL_draw_buffers (like in the
- [Mozilla blog article](https://hacks.mozilla.org/2014/01/webgl-deferred-shading/)).
-
-* (2-6pts) Compare performance to equivalently-lit forward-rendering:
- * (2pts) With no forward-rendering optimizations
- * (+2pts) Coarse, per-object back-to-front sorting of geometry for early-z
- * (Of course) must render many objects to test
- * (+2pts) Z-prepass for early-z
-
-This extra feature list is not comprehensive. If you have a particular idea
-that you would like to implement, please **contact us first** (preferably on
-the mailing list).
-
-**Where possible, all features should be switchable using the GUI panel in
-`ui.js`.**
-
-### Performance & Analysis
-
-**Before doing performance analysis,** you must disable debug mode by changing
-`debugMode` to `false` in `framework.js`. Keep it enabled when developing - it
-helps find WebGL errors *much* more easily.
-
-Optimize your JavaScript and/or GLSL code. Chrome/Firefox's profiling tools
-(see Resources section) will be useful for this. For each change
-that improves performance, show the before and after render times.
-
-For each new *effect* feature (required or extra), please
-provide the following analysis:
-
-* Concise overview write-up of the feature.
-* Performance change due to adding the feature.
- * If applicable, how do parameters (such as number of lights, etc.)
- affect performance? Show data with simple graphs.
- * Show timing in milliseconds, not FPS.
-* If you did something to accelerate the feature, what did you do and why?
-* How might this feature be optimized beyond your current implementation?
-
-For each *performance* feature (required or extra), please provide:
-
-* Concise overview write-up of the feature.
-* Detailed performance improvement analysis of adding the feature
- * What is the best case scenario for your performance improvement? What is
- the worst? Explain briefly.
- * Are there tradeoffs to this performance feature? Explain briefly.
- * How do parameters (such as number of lights, tile size, etc.) affect
- performance? Show data with graphs.
- * Show timing in milliseconds, not FPS.
- * Show debug views when possible.
- * If the debug view correlates with performance, explain how.
-
-### Starter Code Tour
-
-You'll be working mainly in `deferredRender.js` using raw WebGL. Three.js is
-included in the project for various reasons. You won't use it for much, but its
-matrix/vector types may come in handy.
-
-It's highly recommended that you use the browser debugger to inspect variables
-to get familiar with the code. At any point, you can also
-`console.log(some_var);` to show it in the console and inspect it.
-
-The setup in `deferredSetup` is already done for you, for many of the features.
-If you want to add uniforms (textures or values), you'll change them here.
-Therefore, it is recommended that you review the comments to understand the
-process, BEFORE starting work in `deferredRender`.
-
-In `deferredRender`, start at the **START HERE!** comment.
-Work through the appropriate `TODO`s as you go - most of them are very
-small. Test incrementally (after implementing each part, instead of testing
-all at once).
-* (The first thing you should be doing is implementing the fullscreen quad!)
-* See the note in the Debugging section on how to test the first part of the
- pipeline incrementally.
-
-Your _next_ first goal should be to get the debug views working.
-Add code in `debug.frag.glsl` to examine your g-buffers before trying to
-render them. (Set the debugView in the UI to show them.)
-
-For editing JavaScript, you can use a simple editor with syntax highlighting
-such as Sublime, Vim, Emacs, etc., or the editor built into Chrome.
-
-* `js/`: JavaScript files for this project.
- * `main.js`: Handles initialization of other parts of the program.
- * `framework.js`: Loads the scene, camera, etc., and calls your setup/render
- functions. Hopefully, you won't need to change anything here.
- * `deferredSetup.js`: Deferred shading pipeline setup code.
- * `createAndBind(Depth/Color)TargetTexture`: Creates empty textures for
- binding to frame buffer objects as render targets.
- * `deferredRender.js`: Your deferred shading pipeline execution code.
- * `renderFullScreenQuad`: Renders a full-screen quad with the given shader
- program.
- * `ui.js`: Defines the UI using
- [dat.GUI](https://workshop.chromeexperiments.com/examples/gui/).
- * The global variable `cfg` can be accessed anywhere in the code to read
- configuration values.
- * `utils.js`: Utilities for JavaScript and WebGL.
- * `abort`: Aborts the program and shows an error.
- * `loadTexture`: Loads a texture from a URL into WebGL.
- * `loadShaderProgram`: Loads shaders from URLs into a WebGL shader program.
- * `loadModel`: Loads a model into WebGL buffers.
- * `readyModelForDraw`: Configures the WebGL state to draw a model.
- * `drawReadyModel`: Draws a model which has been readied.
- * `getScissorForLight`: Computes an approximate scissor rectangle for a
- light in world space.
-* `glsl/`: GLSL code for each part of the pipeline:
- * `clear.*.glsl`: Clears each of the `NUM_GBUFFERS` g-buffers.
- * `copy.*.glsl`: Performs standard rendering without any fragment shading,
- storing all of the resulting values into the `NUM_GBUFFERS` g-buffers.
- * `quad.vert.glsl`: Minimal vertex shader for rendering a single quad.
- * `deferred.frag.glsl`: Deferred shading pass (for lighting calculations).
- Reads from each of the `NUM_GBUFFERS` g-buffers.
- * `post1.frag.glsl`: First post-processing pass.
-* `lib/`: JavaScript libraries.
-* `models/`: OBJ models for testing. Sponza is the default.
-* `index.html`: Main HTML page.
-* `server.bat` (Windows) or `server.py` (OS X/Linux):
- Runs a web server at `localhost:10565`.
-
-### The Deferred Shading Pipeline
-
-See the comments in `deferredSetup.js`/`deferredRender.js` for low-level guidance.
-
-In order to enable and disable effects using the GUI, upload a vec4 uniform
-where each component is an enable/disable flag. In JavaScript, the state of the
-UI is accessible anywhere as `cfg.enableEffect0`, etc.
-
-**Pass 1:** Renders the scene geometry and its properties to the g-buffers.
-* `copy.vert.glsl`, `copy.frag.glsl`
-* The framebuffer object `pass_copy.fbo` must be bound during this pass.
-* Renders into `pass_copy.depthTex` and `pass_copy.gbufs[i]`, which need to be
- attached to the framebuffer.
-
-**Pass 2:** Performs lighting and shading into the color buffer.
-* `quad.vert.glsl`, `deferred/blinnphong-pointlight.frag.glsl`
-* Takes the g-buffers `pass_copy.gbufs`/`depthTex` as texture inputs to the
- fragment shader, on uniforms `u_gbufs` and `u_depth`.
-* `pass_deferred.fbo` must be bound.
-* Renders into `pass_deferred.colorTex`.
-
-**Pass 3:** Performs post-processing.
-* `quad.vert.glsl`, `post/one.frag.glsl`
-* Takes `pass_BlinnPhong_PointLight.colorTex` as a texture input `u_color`.
-* Renders directly to the screen if there are no additional passes.
-
-More passes may be added for additional effects (e.g. combining bloom with
-motion blur) or optimizations (e.g. two-pass Gaussian blur for bloom)
-
-#### Debugging
-
-If there is a WebGL error, it will be displayed on the developer console and
-the renderer will be aborted. To find out where the error came from, look at
-the backtrace of the error (you may need to click the triangle to expand the
-message). The line right below `wrapper @ webgl-debug.js` will point to the
-WebGL call that failed.
-
-When working in the early pipeline (before you have a lit render), it can be
-useful to render WITHOUT post-processing. To do this, you have to make sure
-that there is NO framebuffer bound while rendering to the screen (that is, bind
-null) so that the output will display to the screen instead of saving into a
-texture. Writing to gl_FragData[0] is the same as writing to gl_FragColor, so
-you'll see whatever you were storing into the first g-buffer.
-
-#### Changing the number of g-buffers
-
-Note that the g-buffers are just `vec4`s - you can put any values you want into
-them. However, if you want to change the total number of g-buffers (add more
-for additional effects or remove some for performance), you will need to make
-changes in a number of places:
-
-* `deferredSetup.js`/`deferredRender.js`: search for `NUM_GBUFFERS`
-* `copy.frag.glsl`
-* `deferred.frag.glsl`
-* `clear.frag.glsl`
-
-
-## Resources
-
-* [1] Bloom:
- [GPU Gems, Ch. 21](http://http.developer.nvidia.com/GPUGems/gpugems_ch21.html)
-* [2] Screen-Space Ambient Occlusion:
- [Floored Article](http://floored.com/blog/2013/ssao-screen-space-ambient-occlusion.html)
-* [3] Post-Process Motion Blur:
- [GPU Gems 3, Ch. 27](http://http.developer.nvidia.com/GPUGems3/gpugems3_ch27.html)
-
-**Also see:** The articles linked in the course schedule.
-
-### Profiling and debugging tools
-
-Built into Firefox:
-* Canvas inspector
-* Shader Editor
-* JavaScript debugger and profiler
-
-Built into Chrome:
-* JavaScript debugger and profiler
-
-Plug-ins:
-* Web Tracing Framework
- **Does not currently work with multiple render targets**,
- which are used in the starter code.
-* (Chrome) [Shader Editor](https://chrome.google.com/webstore/detail/shader-editor/ggeaidddejpbakgafapihjbgdlbbbpob)
-
-Libraries:
-* Stats.js (already included)
-
-Firefox can also be useful - it has a canvas inspector, WebGL profiling and a
-shader editor built in.
-
-## README
-
-Replace 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 video of your project running showing all features.
- [Open Broadcaster Software](http://obsproject.com) is recommended.
- (Even though your demo can be seen online, using multiple render targets
- means it won't run on many computers. A video will work everywhere.)
-* A performance analysis (described below).
-
-### Performance Analysis
-
-See above.
-
-### GitHub Pages
-
-Since this assignment is in WebGL, you can make your project easily viewable by
-taking advantage of GitHub's project pages feature.
-
-Once you are done with the assignment, create a new branch:
-
-`git branch gh-pages`
-
-Push the branch to GitHub:
-
-`git push origin gh-pages`
-
-Now, you can go to `.github.io/` to see your
-renderer online from anywhere. Add this link to your README.
-
-## Submit
-
-1. Open a GitHub pull request so that we can see that you have finished.
- The title should be "Submission: YOUR NAME".
- * **ADDITIONALLY:**
- In the body of the pull request, include a link to your repository.
-2. Send an email to the TA (gmail: kainino1+cis565@) with:
- * **Subject**: in the form of `[CIS565] Project N: PENNKEY`.
- * Direct link to your pull request on GitHub.
- * Estimate the amount of time you spent on the project.
- * If there were any outstanding problems, briefly explain.
- * **List the extra features you did.**
- * Feedback on the project itself, if any.
-
-### Third-Party Code Policy
-
-* Use of any third-party code must be approved by asking on our mailing list.
-* 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 path 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, at minimum,
- result in you receiving an F for the semester.
diff --git a/analysis/ImpactOfNumLight.png b/analysis/ImpactOfNumLight.png
new file mode 100644
index 0000000..f210146
Binary files /dev/null and b/analysis/ImpactOfNumLight.png differ
diff --git a/analysis/analysisTable.numbers b/analysis/analysisTable.numbers
new file mode 100644
index 0000000..d633f50
Binary files /dev/null and b/analysis/analysisTable.numbers differ
diff --git a/analysis/scissorTest.png b/analysis/scissorTest.png
new file mode 100644
index 0000000..85d03db
Binary files /dev/null and b/analysis/scissorTest.png differ
diff --git a/glsl/copy.frag.glsl b/glsl/copy.frag.glsl
index 0f5f8f7..b48a5de 100644
--- a/glsl/copy.frag.glsl
+++ b/glsl/copy.frag.glsl
@@ -10,6 +10,28 @@ varying vec3 v_position;
varying vec3 v_normal;
varying vec2 v_uv;
+vec3 applyNormalMap(vec3 geomnor, vec3 normap) {
+ normap = normap * 2.0 - 1.0;
+ vec3 up = normalize(vec3(0.001, 1, 0.001));
+ vec3 surftan = normalize(cross(geomnor, up));
+ vec3 surfbinor = cross(geomnor, surftan);
+ return normap.y * surftan + normap.x * surfbinor + normap.z * geomnor;
+}
+
void main() {
- // TODO: copy values into gl_FragData[0], [1], etc.
+
+ gl_FragData[0] = vec4(v_position, 1.0);
+ gl_FragData[1] = vec4(normalize(v_normal), 0.0);
+ gl_FragData[2] = texture2D(u_colmap, v_uv);
+ gl_FragData[3] = texture2D(u_normap, v_uv);
+
+ /*
+ gl_FragData[0] = vec4(v_position, 1.0);
+
+ vec3 geomnor = normalize(gb1.xyz);
+ vec3 normap = texture2D(u_normap, v_uv);
+ gl_FragData[1] = applyNormalMap(geomnor, normap);
+
+ gl_FragData[2] = texture2D(u_colmap, v_uv);
+ */
}
diff --git a/glsl/deferred/ambient.frag.glsl b/glsl/deferred/ambient.frag.glsl
index 1fd4647..890fe77 100644
--- a/glsl/deferred/ambient.frag.glsl
+++ b/glsl/deferred/ambient.frag.glsl
@@ -16,12 +16,14 @@ void main() {
vec4 gb2 = texture2D(u_gbufs[2], v_uv);
vec4 gb3 = texture2D(u_gbufs[3], v_uv);
float depth = texture2D(u_depth, v_uv).x;
+
// TODO: Extract needed properties from the g-buffers into local variables
+ vec3 colmap = gb2.xyz;
if (depth == 1.0) {
gl_FragColor = vec4(0, 0, 0, 0); // set alpha to 0
return;
}
- gl_FragColor = vec4(0.1, 0.1, 0.1, 1); // TODO: replace this
+ gl_FragColor = vec4(0.15 * colmap, 1.0);
}
diff --git a/glsl/deferred/blinnphong-pointlight.frag.glsl b/glsl/deferred/blinnphong-pointlight.frag.glsl
index b24a54a..1d298bc 100644
--- a/glsl/deferred/blinnphong-pointlight.frag.glsl
+++ b/glsl/deferred/blinnphong-pointlight.frag.glsl
@@ -3,10 +3,16 @@ precision highp float;
precision highp int;
#define NUM_GBUFFERS 4
+#define WIDTH 600
+#define HEIGHT 800
uniform vec3 u_lightCol;
uniform vec3 u_lightPos;
uniform float u_lightRad;
+uniform vec3 u_camPos;
+
+uniform float u_mode;
+
uniform sampler2D u_gbufs[NUM_GBUFFERS];
uniform sampler2D u_depth;
@@ -26,14 +32,64 @@ void main() {
vec4 gb2 = texture2D(u_gbufs[2], v_uv);
vec4 gb3 = texture2D(u_gbufs[3], v_uv);
float depth = texture2D(u_depth, v_uv).x;
- // TODO: Extract needed properties from the g-buffers into local variables
-
- // If nothing was rendered to this pixel, set alpha to 0 so that the
- // postprocessing step can render the sky color.
+
+ vec3 pos = gb0.xyz;
+ vec3 geomnor = normalize(gb1.xyz);
+ vec3 colmap = gb2.xyz;
+ vec3 normap = gb3.xyz;
+ vec3 nor = applyNormalMap(geomnor, normap);
+
if (depth == 1.0) {
gl_FragColor = vec4(0, 0, 0, 0);
return;
}
+
+ vec3 lightVector = u_lightPos - pos;
+ float attenuation = max (0.0, u_lightRad- length(lightVector));
+ //float attenuation = clamp (0.0, u_lightRad - length(lightVector));
+
+ lightVector = normalize(lightVector);
+ vec3 lightReflectVector = reflect(-lightVector, nor);
+ vec3 camVector = normalize(u_camPos - pos);
+
+ if(u_mode == 1.0 && (dot(nor, camVector) < 0.1 && dot(nor, camVector) > -0.1))
+ {
+ //Make silhouettes pop
+ gl_FragColor = vec4(vec3(0.0), 1.0);
+ return;
+ }
- gl_FragColor = vec4(0, 0, 1, 1); // TODO: perform lighting calculations
+ vec3 H = normalize(lightVector + camVector);
+
+ //Assuming Kspec = 0.01 and shininess = 0.01
+ float spec = 0.001 * pow(clamp(dot(nor, H), 0.0, 1.0), 0.01);
+ float diff = max(0.0,dot(nor, lightVector));
+
+ if(u_mode == 1.0)
+ {
+ //toon shading
+
+ if(diff > 0.6)
+ diff = 1.0;
+ else if(diff > 0.58)
+ {
+ gl_FragColor = vec4(vec3(0.0), 1.0);
+ return;
+ }
+ else if(diff > 0.2)
+ diff = 0.2;
+ else if(diff > 0.18)
+ {
+ gl_FragColor = vec4(vec3(0.0), 1.0);
+ return;
+ }
+ else diff = 0.0;
+ }
+
+ else if(u_mode == 2.0)
+ {
+ //Bloom filtering
+ }
+
+ gl_FragColor = vec4(attenuation * colmap * u_lightCol * (diff + spec), 1.0);
}
diff --git a/glsl/deferred/debug.frag.glsl b/glsl/deferred/debug.frag.glsl
index 9cbfae4..be893af 100644
--- a/glsl/deferred/debug.frag.glsl
+++ b/glsl/deferred/debug.frag.glsl
@@ -26,13 +26,15 @@ void main() {
vec4 gb2 = texture2D(u_gbufs[2], v_uv);
vec4 gb3 = texture2D(u_gbufs[3], v_uv);
float depth = texture2D(u_depth, v_uv).x;
+
// TODO: Extract needed properties from the g-buffers into local variables
// These definitions are suggested for starting out, but you will probably want to change them.
- vec3 pos; // World-space position
- vec3 geomnor; // Normals of the geometry as defined, without normal mapping
- vec3 colmap; // The color map - unlit "albedo" (surface color)
- vec3 normap; // The raw normal map (normals relative to the surface they're on)
- vec3 nor; // The true normals as we want to light them - with the normal map applied to the geometry normals (applyNormalMap above)
+
+ vec3 pos = gb0.xyz;
+ vec3 geomnor = normalize(gb1.xyz); // Normals of the geometry as defined, without normal mapping
+ vec3 colmap = gb2.xyz; // The color map - unlit "albedo" (surface color)
+ vec3 normap = gb3.xyz; // The raw normal map (normals relative to the surface they're on)
+ vec3 nor = applyNormalMap(geomnor, normap); // The true normals as we want to light them - with the normal map applied to the geometry normals (applyNormalMap above)
if (u_debug == 0) {
gl_FragColor = vec4(vec3(depth), 1.0);
diff --git a/glsl/red.frag.glsl b/glsl/red.frag.glsl
index f8ef1ec..4014eb9 100644
--- a/glsl/red.frag.glsl
+++ b/glsl/red.frag.glsl
@@ -3,5 +3,5 @@ precision highp float;
precision highp int;
void main() {
- gl_FragColor = vec4(1, 0, 0, 1);
+ gl_FragColor = vec4(0.2, 0.2, 0.2, 1.0);
}
diff --git a/glsl/sphere.vert.glsl b/glsl/sphere.vert.glsl
new file mode 100644
index 0000000..2857813
--- /dev/null
+++ b/glsl/sphere.vert.glsl
@@ -0,0 +1,19 @@
+#version 100
+precision highp float;
+precision highp int;
+
+attribute vec3 a_position;
+
+uniform mat4 u_cameraMatrix;
+
+uniform float u_scale;
+uniform vec3 u_pos;
+
+varying vec2 v_uv;
+
+void main() {
+
+ gl_Position = u_cameraMatrix * vec4(a_position * u_scale + u_pos, 1.0);
+
+ v_uv = gl_Position.xy * 0.5 + 0.5;
+}
diff --git a/images/basicImage.png b/images/basicImage.png
new file mode 100644
index 0000000..2e32bfd
Binary files /dev/null and b/images/basicImage.png differ
diff --git a/images/blinnPhong.png b/images/blinnPhong.png
new file mode 100644
index 0000000..6872c6f
Binary files /dev/null and b/images/blinnPhong.png differ
diff --git a/images/blinnPhong2.png b/images/blinnPhong2.png
new file mode 100644
index 0000000..5c10e5f
Binary files /dev/null and b/images/blinnPhong2.png differ
diff --git a/images/colormap.png b/images/colormap.png
new file mode 100644
index 0000000..4f71d9e
Binary files /dev/null and b/images/colormap.png differ
diff --git a/images/depth.png b/images/depth.png
new file mode 100644
index 0000000..f439964
Binary files /dev/null and b/images/depth.png differ
diff --git a/images/geomNorm.png b/images/geomNorm.png
new file mode 100644
index 0000000..b664463
Binary files /dev/null and b/images/geomNorm.png differ
diff --git a/images/normalMap.png b/images/normalMap.png
new file mode 100644
index 0000000..06384c4
Binary files /dev/null and b/images/normalMap.png differ
diff --git a/images/points.png b/images/points.png
new file mode 100644
index 0000000..0374c60
Binary files /dev/null and b/images/points.png differ
diff --git a/images/scissorDebug.png b/images/scissorDebug.png
new file mode 100644
index 0000000..fc32b5b
Binary files /dev/null and b/images/scissorDebug.png differ
diff --git a/images/sphereDebug.png b/images/sphereDebug.png
new file mode 100644
index 0000000..916da4d
Binary files /dev/null and b/images/sphereDebug.png differ
diff --git a/images/surfaceNormals.png b/images/surfaceNormals.png
new file mode 100644
index 0000000..57f9b33
Binary files /dev/null and b/images/surfaceNormals.png differ
diff --git a/images/toonShader.png b/images/toonShader.png
new file mode 100644
index 0000000..2a7ae46
Binary files /dev/null and b/images/toonShader.png differ
diff --git a/js/deferredRender.js b/js/deferredRender.js
index b1f238b..7209e3a 100644
--- a/js/deferredRender.js
+++ b/js/deferredRender.js
@@ -1,3 +1,4 @@
+
(function() {
'use strict';
// deferredSetup.js must be loaded first
@@ -6,6 +7,7 @@
if (!aborted && (
!R.progCopy ||
!R.progRed ||
+ !R.progSphere ||
!R.progClear ||
!R.prog_Ambient ||
!R.prog_BlinnPhong_PointLight ||
@@ -26,14 +28,7 @@
// Execute deferred shading pipeline
// CHECKITOUT: START HERE! You can even uncomment this:
- //debugger;
-
- { // TODO: this block should be removed after testing renderFullScreenQuad
- gl.bindFramebuffer(gl.FRAMEBUFFER, null);
- // TODO: Implement/test renderFullScreenQuad first
- renderFullScreenQuad(R.progRed);
- return;
- }
+ // debugger;
R.pass_copy.render(state);
@@ -44,8 +39,8 @@
} else {
// * Deferred pass and postprocessing pass(es)
// TODO: uncomment these
- //R.pass_deferred.render(state);
- //R.pass_post1.render(state);
+ R.pass_deferred.render(state);
+ R.pass_post1.render(state);
// OPTIONAL TODO: call more postprocessing passes, if any
}
@@ -56,23 +51,24 @@
*/
R.pass_copy.render = function(state) {
// * Bind the framebuffer R.pass_copy.fbo
- // TODO: ^
+ gl.bindFramebuffer(gl.FRAMEBUFFER, R.pass_copy.fbo);
// * Clear screen using R.progClear
- TODO: renderFullScreenQuad(R.progClear);
+ renderFullScreenQuad(R.progClear);
+
// * Clear depth buffer to value 1.0 using gl.clearDepth and gl.clear
- // TODO: ^
- // TODO: ^
+ gl.clearDepth(1.0);
+ gl.clear(gl.DEPTH_BUFFER_BIT);
+
// * "Use" the program R.progCopy.prog
- // TODO: ^
- // TODO: Write glsl/copy.frag.glsl
+ gl.useProgram(R.progCopy.prog);
- var m = state.cameraMat.elements;
+ //var m = state.cameraMat.elements;
// * Upload the camera matrix m to the uniform R.progCopy.u_cameraMat
// using gl.uniformMatrix4fv
- // TODO: ^
-
+ gl.uniformMatrix4fv(R.progCopy.u_cameraMat, gl.FALSE, state.cameraMat.elements);
+
// * Draw the scene
drawScene(state);
};
@@ -118,7 +114,8 @@
// Enable blending and use gl.blendFunc to blend with:
// color = 1 * src_color + 1 * dst_color
- // TODO: ^
+ gl.enable(gl.BLEND);
+ gl.blendFunc(gl.ONE, gl.ONE);
// * Bind/setup the ambient pass, and render using fullscreen quad
bindTexturesForLightPass(R.prog_Ambient);
@@ -130,14 +127,113 @@
// TODO: add a loop here, over the values in R.lights, which sets the
// uniforms R.prog_BlinnPhong_PointLight.u_lightPos/Col/Rad etc.,
// then does renderFullScreenQuad(R.prog_BlinnPhong_PointLight).
-
- // TODO: In the lighting loop, use the scissor test optimization
+
+
+ for (var i = 0; i < R.NUM_LIGHTS; i++)
+ {
+ var l = R.lights[i];
+
+ if (cfg.debug)
+ {
+ if(cfg.primitive == 0)
+ {
+ // debugger;
+ gl.enable(gl.SCISSOR_TEST);
+ var scissor = getScissorForLight(state.viewMat, state.projMat, l);
+ if(scissor!=null)
+ {
+ gl.scissor(scissor[0],scissor[1],scissor[2],scissor[3]);
+ renderFullScreenQuad(R.progRed);
+ }
+ gl.disable(gl.SCISSOR_TEST);
+ }
+
+ else if(cfg.primitive == 1)
+ {
+ // debugger;
+ readyModelForDraw(R.progSphere, R.sphereModel);
+ gl.uniformMatrix4fv(R.progSphere.u_cameraMatrix, false, state.cameraMat.elements);
+ gl.uniform3fv(R.progSphere.u_pos, l.pos);
+ gl.uniform1f(R.progSphere.u_scale, l.rad);
+
+ drawReadyModel(R.sphereModel);
+ }
+ }
+
+
+ else
+ {
+ var mode;
+ if(cfg.toon)
+ {
+ mode = 1.0;
+ }
+
+ else if(cfg.bloom)
+ {
+ mode = 2.0;
+ }
+
+ else
+ {
+ mode = 0.0;
+ }
+
+ if(cfg.primitive == 0)
+ {
+ gl.enable(gl.SCISSOR_TEST);
+ var scissor = getScissorForLight(state.viewMat, state.projMat, l);
+
+ if(scissor!=null)
+ {
+ console.log(scissor);
+ gl.scissor(scissor[0],scissor[1],scissor[2],scissor[3]);
+
+ gl.uniform3fv(R.prog_BlinnPhong_PointLight.u_lightPos, l.pos);
+ gl.uniform3fv(R.prog_BlinnPhong_PointLight.u_lightCol, l.col);
+ gl.uniform1f(R.prog_BlinnPhong_PointLight.u_lightRad, l.rad);
+ gl.uniform1f(R.prog_BlinnPhong_PointLight.u_mode, mode);
+
+ gl.uniform3f(R.prog_BlinnPhong_PointLight.u_camPos, state.cameraPos.x, state.cameraPos.y, state.cameraPos.z);
+ renderFullScreenQuad(R.prog_BlinnPhong_PointLight);
+ }
+
+ gl.disable(gl.SCISSOR_TEST);
+ }
+ //
+ // else if(cfg.primitive == 1)
+ // {
+ // gl.uniform3fv(R.prog_BlinnPhong_PointLight.u_lightPos, l.pos);
+ // gl.uniform3fv(R.prog_BlinnPhong_PointLight.u_lightCol, l.col);
+ // gl.uniform1f(R.prog_BlinnPhong_PointLight.u_lightRad, l.rad);
+ // gl.uniform1f(R.prog_BlinnPhong_PointLight.u_mode, mode);
+ //
+ // gl.uniform3f(R.prog_BlinnPhong_PointLight.u_camPos, state.cameraPos.x, state.cameraPos.y, state.cameraPos.z);
+ // //renderFullScreenQuad(R.prog_BlinnPhong_PointLight);
+ // drawReadyModel(R.sphereModel);
+ // }
+
+ else
+ {
+ gl.uniform3fv(R.prog_BlinnPhong_PointLight.u_lightPos, l.pos);
+ gl.uniform3fv(R.prog_BlinnPhong_PointLight.u_lightCol, l.col);
+ gl.uniform1f(R.prog_BlinnPhong_PointLight.u_lightRad, l.rad);
+ gl.uniform1f(R.prog_BlinnPhong_PointLight.u_mode, mode);
+
+ gl.uniform3f(R.prog_BlinnPhong_PointLight.u_camPos, state.cameraPos.x, state.cameraPos.y, state.cameraPos.z);
+ renderFullScreenQuad(R.prog_BlinnPhong_PointLight);
+ }
+ }
+ }
+
+
+ // TODO: In the lighting loop, use the scissor test optimization
// Enable gl.SCISSOR_TEST, render all lights, then disable it.
//
// getScissorForLight returns null if the scissor is off the screen.
// Otherwise, it returns an array [xmin, ymin, width, height].
//
- // var sc = getScissorForLight(state.viewMat, state.projMat, light);
+ //var sc = getScissorForLight(state.viewMat, state.projMat, light);
// Disable blending so that it doesn't affect other code
gl.disable(gl.BLEND);
@@ -174,9 +270,10 @@
// * Bind the deferred pass's color output as a texture input
// Set gl.TEXTURE0 as the gl.activeTexture unit
- // TODO: ^
+ gl.activeTexture(gl.TEXTURE0);
+
// Bind the TEXTURE_2D, R.pass_deferred.colorTex to the active texture unit
- // TODO: ^
+ gl.bindTexture(gl.TEXTURE_2D, R.pass_deferred.colorTex);
// Configure the R.progPost1.u_color uniform to point at texture unit 0
gl.uniform1i(R.progPost1.u_color, 0);
@@ -204,13 +301,14 @@
var init = function() {
// Create a new buffer with gl.createBuffer, and save it as vbo.
- // TODO: ^
+ vbo = gl.createBuffer()
// Bind the VBO as the gl.ARRAY_BUFFER
- // TODO: ^
+ gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
+
// Upload the positions array to the currently-bound array buffer
// using gl.bufferData in static draw mode.
- // TODO: ^
+ gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
};
return function(prog) {
@@ -223,19 +321,22 @@
gl.useProgram(prog.prog);
// Bind the VBO as the gl.ARRAY_BUFFER
- // TODO: ^
+ gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
+
// Enable the bound buffer as the vertex attrib array for
// prog.a_position, using gl.enableVertexAttribArray
- // TODO: ^
+ gl.enableVertexAttribArray(prog.a_position);
+
// Use gl.vertexAttribPointer to tell WebGL the type/layout for
// prog.a_position's access pattern.
- // TODO: ^
+ gl.vertexAttribPointer(prog.a_position, 3, gl.FLOAT, gl.FALSE, 0, 0);
- // Use gl.drawArrays (or gl.drawElements) to draw your quad.
- // TODO: ^
+ // Use gl.drawArrays (or gl.drawElements) to draw your quad.
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
// Unbind the array buffer.
gl.bindBuffer(gl.ARRAY_BUFFER, null);
};
})();
+
})();
diff --git a/js/deferredSetup.js b/js/deferredSetup.js
index 65136e0..208cda6 100644
--- a/js/deferredSetup.js
+++ b/js/deferredSetup.js
@@ -124,6 +124,17 @@
// Create an object to hold info about this shader program
R.progRed = { prog: prog };
});
+
+ loadShaderProgram(gl, 'glsl/sphere.vert.glsl', 'glsl/red.frag.glsl',
+ function(prog) {
+ // debugger;
+ // Create an object to hold info about this shader program
+
+ R.progSphere = { prog: prog };
+ R.progSphere.u_cameraMatrix = gl.getUniformLocation(prog, 'u_cameraMatrix');
+ R.progSphere.u_pos = gl.getUniformLocation(prog, 'u_pos');
+ R.progSphere.u_scale = gl.getUniformLocation(prog, 'u_scale');
+ });
loadShaderProgram(gl, 'glsl/quad.vert.glsl', 'glsl/clear.frag.glsl',
function(prog) {
@@ -141,6 +152,8 @@
p.u_lightPos = gl.getUniformLocation(p.prog, 'u_lightPos');
p.u_lightCol = gl.getUniformLocation(p.prog, 'u_lightCol');
p.u_lightRad = gl.getUniformLocation(p.prog, 'u_lightRad');
+ p.u_camPos = gl.getUniformLocation(p.prog, 'u_camPos');
+ p.u_mode = gl.getUniformLocation(p.prog, 'u_mode');
R.prog_BlinnPhong_PointLight = p;
});
diff --git a/js/framework.js b/js/framework.js
index 7c008df..6b14fdf 100644
--- a/js/framework.js
+++ b/js/framework.js
@@ -67,7 +67,7 @@ var width, height;
var init = function() {
// TODO: For performance measurements, disable debug mode!
- var debugMode = true;
+ var debugMode = false;
canvas = document.getElementById('canvas');
renderer = new THREE.WebGLRenderer({
diff --git a/js/ui.js b/js/ui.js
index abd6119..63a6263 100644
--- a/js/ui.js
+++ b/js/ui.js
@@ -6,15 +6,20 @@ var cfg;
var Cfg = function() {
// TODO: Define config fields and defaults here
this.debugView = -1;
- this.debugScissor = false;
- this.enableEffect0 = false;
+ this.debug = false;
+ this.primitive = -1;
+
+// this.enableEffect0 = false;
+
+ this.toon = false;
+ this.bloom = false;
};
var init = function() {
cfg = new Cfg();
var gui = new dat.GUI();
- // TODO: Define any other possible config values
+
gui.add(cfg, 'debugView', {
'None': -1,
'0 Depth': 0,
@@ -24,11 +29,20 @@ var cfg;
'4 Normal map': 4,
'5 Surface normal': 5
});
- gui.add(cfg, 'debugScissor');
+
+ gui.add(cfg, 'debug');
- var eff0 = gui.addFolder('EFFECT NAME HERE');
+
+ gui.add(cfg, 'primitive', {
+ 'None': -1,
+ '0 Scissor': 0,
+ '1 Sphere': 1
+ });
+
+ var eff0 = gui.addFolder('Effects');
eff0.open();
- eff0.add(cfg, 'enableEffect0');
+ eff0.add(cfg, 'toon');
+ eff0.add(cfg, 'bloom');
// TODO: add more effects toggles and parameters here
};
diff --git a/js/util.js b/js/util.js
index 6e1adfe..b4601cd 100644
--- a/js/util.js
+++ b/js/util.js
@@ -175,8 +175,8 @@ window.getScissorForLight = (function() {
ret[0] = Math.round(width * minpt.x);
ret[1] = Math.round(height * minpt.y);
- ret[2] = Math.round(width * (maxpt.x - minpt.x));
- ret[3] = Math.round(height * (maxpt.y - minpt.y));
+ ret[2] = Math.abs(Math.round(width * (maxpt.x - minpt.x)));
+ ret[3] = Math.abs(Math.round(height * (maxpt.y - minpt.y)));
return ret;
};
})();