Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .vs/Project5/v14/.suo
Binary file not shown.
104 changes: 104 additions & 0 deletions Project5.njsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{4826d22a-8ce2-4b91-809d-fb0b26dceaed}</ProjectGuid>
<ProjectHome />
<ProjectView>ShowAllFiles</ProjectView>
<StartupFile>src\main.js</StartupFile>
<WorkingDirectory>.</WorkingDirectory>
<OutputPath>.</OutputPath>
<ProjectTypeGuids>{3AF33F2E-1136-4D97-BBB7-1795711AC8B8};{349c5851-65df-11da-9384-00065b846f21};{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">11.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Debug'" />
<PropertyGroup Condition="'$(Configuration)' == 'Release'" />
<ItemGroup>
<Content Include="index.html" />
<Content Include="package.json" />
<Content Include="INSTRUCTION.md" />
<Content Include="README.md" />
<Compile Include="webpack.config.js" />
<Compile Include="lib\minimal-gltf-loader.js" />
<Compile Include="src\init.js" />
<Compile Include="src\main.js" />
<Compile Include="src\scene.js" />
<Compile Include="src\utils.js" />
<Content Include="models\sponza\normal.png" />
<Compile Include="src\renderers\clustered.js" />
<Compile Include="src\renderers\clusteredDeferred.js" />
<Compile Include="src\renderers\clusteredForwardPlus.js" />
<Compile Include="src\renderers\forward.js" />
<Compile Include="src\renderers\textureBuffer.js" />
<Compile Include="src\shaders\clusteredForward.frag.glsl.js" />
<Compile Include="src\shaders\deferred.frag.glsl.js" />
<Compile Include="src\shaders\forward.frag.glsl.js" />
</ItemGroup>
<ItemGroup>
<Folder Include="lib" />
<Folder Include="models" />
<Folder Include="models\sponza" />
<Folder Include="src" />
<Folder Include="src\renderers" />
<Folder Include="src\shaders" />
<Folder Include="typings\" />
<Folder Include="typings\globals\" />
<Folder Include="typings\globals\gl-matrix\" />
<Folder Include="typings\globals\node\" />
<Folder Include="typings\globals\three-orbitcontrols\" />
<Folder Include="typings\globals\three\" />
<Folder Include="typings\globals\webpack-dev-server\" />
</ItemGroup>
<ItemGroup>
<TypeScriptCompile Include="typings\globals\gl-matrix\index.d.ts" />
<TypeScriptCompile Include="typings\globals\node\index.d.ts" />
<TypeScriptCompile Include="typings\globals\three-orbitcontrols\index.d.ts" />
<TypeScriptCompile Include="typings\globals\three\index.d.ts" />
<TypeScriptCompile Include="typings\globals\webpack-dev-server\index.d.ts" />
<TypeScriptCompile Include="typings\index.d.ts" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.Common.targets" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<!--Do not delete the following Import Project. While this appears to do nothing it is a marker for setting TypeScript properties before our import that depends on them.-->
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets" Condition="False" />
<Import Project="$(VSToolsPath)\Node.js Tools\Microsoft.NodejsTools.targets" />
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>False</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>0</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:48022/</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>True</UseCustomServer>
<CustomServerUrl>http://localhost:1337</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}" User="">
<WebProjectProperties>
<StartPageUrl>
</StartPageUrl>
<StartAction>CurrentPage</StartAction>
<AspNetDebugging>True</AspNetDebugging>
<SilverlightDebugging>False</SilverlightDebugging>
<NativeDebugging>False</NativeDebugging>
<SQLDebugging>False</SQLDebugging>
<ExternalProgram>
</ExternalProgram>
<StartExternalURL>
</StartExternalURL>
<StartCmdLineArguments>
</StartCmdLineArguments>
<StartWorkingDirectory>
</StartWorkingDirectory>
<EnableENC>False</EnableENC>
<AlwaysStartWebServerOnDebug>False</AlwaysStartWebServerOnDebug>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
</Project>
137 changes: 104 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,104 @@
WebGL Clustered Deferred and Forward+ Shading
======================

**University of Pennsylvania, CIS 565: GPU Programming and Architecture, Project 5**

* (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)

### Live Online

[![](img/thumb.png)](http://TODO.github.io/Project5B-WebGL-Deferred-Shading)

### Demo Video/GIF

[![](img/video.png)](TODO)

### (TODO: Your README)

*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.

This assignment has a considerable amount of performance analysis compared
to implementation work. Complete the implementation early to leave time!


### Credits

* [Three.js](https://github.com/mrdoob/three.js) by [@mrdoob](https://github.com/mrdoob) and contributors
* [stats.js](https://github.com/mrdoob/stats.js) by [@mrdoob](https://github.com/mrdoob) and contributors
* [webgl-debug](https://github.com/KhronosGroup/WebGLDeveloperTools) by Khronos Group Inc.
* [glMatrix](https://github.com/toji/gl-matrix) by [@toji](https://github.com/toji) and contributors
* [minimal-gltf-loader](https://github.com/shrekshao/minimal-gltf-loader) by [@shrekshao](https://github.com/shrekshao)
# **University of Pennsylvania, CIS 565: GPU Programming and Architecture, Project 5:**

# **Clustered Forward Plus and Deferred Shaders**

Tested on: Windows 10, Intel Core i7-7700HQ CPU @ 2.80 GHz, 8GB RAM, NVidia GeForce GTX 1050

![Built](https://img.shields.io/appveyor/ci/gruntjs/grunt.svg) ![Issues](https://img.shields.io/github/issues-raw/badges/shields/website.svg) ![CUDA 8.0](https://img.shields.io/badge/CUDA-8.0-green.svg?style=flat) ![Platform](https://img.shields.io/badge/platform-Desktop-bcbcbc.svg) ![Developer](https://img.shields.io/badge/Developer-Youssef%20Victor-0f97ff.svg?style=flat)




- [Things Done](#things-done)

- [In-Depth](#in-depth)

- [Time Analysis](#time-analysis)

- [Final Thoughts](#final-thougts)



____________________________________________________



The goal of this project was to create two shaders: - Clustered Forward Plus and Clusterred Deferred. Clustering is when you divide the entire scene into three-dimensional blocks called clusters. For a more in-depth explanation of clustering see [this post](http://www.humus.name/Articles/PracticalClusteredShading.pdf).

Deferred Shading is when you simply store the fragment data in a separate g-buffer, and then perform computations at the end. Therefore the scene's shading is no longer dependent upon the number of lights. So combining both makes for a very efficient shader!

### [LIVE DEMO](https://youssefv.github.io/Project5-WebGL-Clustered-Deferred-Forward-Plus/)


### Things Done

#### Core Features

- [x] Clustered Forward Plus Shader
- [x] Clustered Deferred Shader

#### Optimizations

- [x] Two-Component Normals
- [x] Pack the values into two vec4's
- [x] Blinn-Phong Shading
- [ ] Recreate world_position using nothing but depth and camera matrices (the code currently supports this being added, I just haven't had the time to do the math)

![lights](img/lights.gif)

Sponza Scene with 1500 Lights (sped up 3x for demo purposes)


### In-Depth:

#### Clustering:

Clustering took me forever to get right. I initially started with Avalanche's reference implementation. It was practically verbatim. It didn't work. I tried everything and it was still patchy. See `clustered.js` for more. So just did the plane-point distance check that Austin briefly explained in class. I pulled the formula for the caluclation from [this Stack Overflow post](http://bit.ly/GPU-HW5-Ref1). For the z-checking, because the planes are axis aligned, I just get the starting tip of the sphere and the end tip by offseting the sphere's center's z by the radius.

###### Debug Views!

Albedo (with absolute normal view to compare):

![albedo](img/albedo.gif)

Just Absolute Normal View:

![normals](img/normals.gif)

Depth (Gradient Quantization due to GIF Recording software):

![deep](img/depth.gif)

#### Deferred Shading:

I'm skipping over Forward+ because there is essentially nothing more to it than the clustering. The deferred shading was actually more fun because I had already done the clustering part which is not fun at all.

###### G-Buffer Optimizationd:

My g-buffer for deferred shading basically looks like this:

![gbuffer](img/gbuffer.PNG)

As you can see, that is almost as packed as it gets (more on that later). For the g-buffer I basically just have the position and the color, and then I sneak in the normal as part of both of them. I only have the x and the y component as I can compute the z later. The problem I had though was that my z was sometimes negative. This is normal if you're dealing with World Space coordinates. So I work with the absolute value of the z coordinate as all we really need the normal for in my implementation is shading and in my case it we need the absolute value any way. This however threw my Blinn-Phong calculations off and I had to adjust my code accordingly. It still works beautifully though!

###### Blinn-Phong Shading:

Blinn-Phong shading was fairly straightforward. I took the formulas straight from the 560 Slides. I had to do slight modifications to deal with the stuff in view space but other than that, it took like 4-5 hours to do, which considering how long it took to do any other feature is nothing. Here is what the highlights look. Quick note though, this is in pure white and not the *exact* same as how it contribute in the final image because I change a lot from this view to the final shading calculation. It is still very cool though!!

![blinn](img/blinn-phong.gif)

### Time Analysis

For the timing analysis I first compare the different shading techniques. We first have the Forward Shader. That's just normal shading. It's also very slow (comparitively). It also breaks my timing measurer so it's omitted from these results. We then have the clusterred forward plus. This is basically Forward shading but the lights in the scene are distributed into clusters. Then we finally have Clustered Deferred Shading. That's where you have lights that are split into clustered but instead of doing the shading per light and fragment, you just store the fragment's values in a g-buffer and read from that at the end. This makes your code scale linearly with respect to light count. As opposed to forward where it scales exponentially. Here is a timing graph comparing all three types with diffrerent light counts (in ms).

![timing for different shaders](img/ms_frame.PNG)

Then I made the g-buffer optimization. Since I sorta built my code to be two vec4's from the start I actually had to make my code less optimized to measure it and compare. Below are the measurements:

![timing for different shaders](img/deferred.PNG)

Overall, you can see a consistent gain for each light count, but as expected since this is essentially a "constant" change, that amount gradually becomes less and less relevant as the light count increases.

### Final Thoughts

I did not enjoy this project. It was less enjoyable than the rest as I felt that it was too niche of a field. Real time rasterization is one of the fields in graphics which I am settled on not liking. I'm sure people who are into gaming may have enjoyed this. But I did not.
Binary file added img/albedo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/blinn-phong-comp.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/blinn-phong.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/deferred.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/depth.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/gbuffer.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/lights.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/ms_frame.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/normals.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/init.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// TODO: Change this to enable / disable debug mode
export const DEBUG = true && process.env.NODE_ENV === 'development';
export const DEBUG = false && process.env.NODE_ENV === 'development';

import DAT from 'dat-gui';
import WebGLDebug from 'webgl-debug';
Expand Down
2 changes: 1 addition & 1 deletion src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const CLUSTERED_FORWARD_PLUS = 'Clustered Forward+';
const CLUSTERED_DEFFERED = 'Clustered Deferred';

const params = {
renderer: CLUSTERED_FORWARD_PLUS,
renderer: CLUSTERED_DEFFERED,
_renderer: null,
};

Expand Down
Loading