/glTF-Sample-Viewer

Physically-Based Rendering in glTF 2.0 using WebGL

Primary LanguageJavaScriptApache License 2.0Apache-2.0

glTF 2.0 Sample Viewer

This is the official Khronos glTF 2.0 sample viewer using WebGL: glTF 2.0 Sample Viewer

Table of Contents

Version

Pre-Release

Credits

Developed by UX3D and based on the former glTF-WebGL-PBR project. Supported by the Khronos Group and Facebook for animations, skinning and morphing.

Viewer

Link to the live glTF 2.0 Sample Viewer.

Usage

Controls

click + drag : Rotate model

scroll : Zoom camera

GUI : Use to change models and settings

Change glTF model

  • Choose one of the glTF models in the selction list

or

  • Drag and drop glTF files into viewer

Setup

For local usage and debugging, please follow these instructions:

(1) Checkout the master branch

(2) Install dependencies with npm install

(3) Pull the submodules for the required glTF sample models and environments git submodule update --init --recursive

(4a) Start a demo in the browser with npm run dev, and open http://localhost:8000.

(4b) Start a demo in Electron with npm run dev:electron.

When making changes, the project is automatically rebuilt and the dist/ folder is updated. Files in the dist/ folder should not be included in pull requests — they will be updated by project maintainers with each new release.

Offline / Headless Rendering

NOTE: The dimensions of the rendered image are limited by the (virtual) desktop size.

Requirements

Configure environment

  • npm install (also installs Electron)
  • npm run build (“compile” the code)

Run

  • npm run start-offscreen -- -- -h for a list of available options

Example

  • npm run start-offscreen -- -- assets/models/2.0/FlightHelmet/glTF/FlightHelmet.gltf

After execution, the screenshot is stored as output.png on the file system.

Debugging

  • Requirements
  • Install the Debugger for Firefox extension for Visual Studio Code
  • Open the project folder in Visual Studio Code and select Debug->Add Configuration->Firefox so the .vscode/launch.json file is created.
  • Debug->Start Debugging should now launch a Firefox window with the sample viewer and VS Code breakpoints should be hit.

Physically-Based Materials in glTF 2.0

With the change from glTF 1.0 to glTF 2.0, one of the largest changes included core support for materials that could be used for physically-based shading. Part of this process involved chosing technically accurate, yet user-friendly, parameters for which developers and artists could use intuitively. This resulted in the introduction of the Metallic-Roughness Material to glTF. If you would like to read more about glTF, you can find the content at its GitHub page.

A good reference about Physically-Based Materials and its workflow can be found on the THE PBR GUIDE - PART 1 and THE PBR GUIDE - PART 2 from allegorithmic.

For implementation details and further theory, please find more information in the Real Shading in Unreal Engine 4 presentation from the SIGGRAPH 2013 course.

Appendix

For further reference, please read the glTF 2.0: Appendix B: BRDF Implementation
The following sections do summarize the important shader code.

vec3 specularContribution = D * Vis * F;
vec3 diffuseContribution = (1.0 - F) * diffuse; 

Please note: Vis = G / (4 * NdotL * NdotV)

Specular Term

Microfaced Distribution (D)

Trowbridge-Reitz GGX

float microfacetDistribution(MaterialInfo materialInfo, AngularInfo angularInfo)
{
    float alphaRoughnessSq = materialInfo.alphaRoughness * materialInfo.alphaRoughness;
    float f = (angularInfo.NdotH * alphaRoughnessSq - angularInfo.NdotH) * angularInfo.NdotH + 1.0;
    return alphaRoughnessSq / (M_PI * f * f);
}

Surface Reflection Ratio (F)

Fresnel Schlick

vec3 specularReflection(MaterialInfo materialInfo, AngularInfo angularInfo)
{
    return materialInfo.reflectance0 + (materialInfo.reflectance90 - materialInfo.reflectance0) * pow(clamp(1.0 - angularInfo.VdotH, 0.0, 1.0), 5.0);
}

Please note, that the above shader code includes the optimization for "turning off" the Fresnel edge brightening (see "Real-Time Rendering" Fourth Edition on page 325).

Geometric Occlusion (G)

Smith Joint GGX

float visibilityOcclusion(MaterialInfo materialInfo, AngularInfo angularInfo)
{
    float NdotL = angularInfo.NdotL;
    float NdotV = angularInfo.NdotV;
    float alphaRoughnessSq = materialInfo.alphaRoughness * materialInfo.alphaRoughness;

    float GGXV = NdotL * sqrt(NdotV * NdotV * (1.0 - alphaRoughnessSq) + alphaRoughnessSq);
    float GGXL = NdotV * sqrt(NdotL * NdotL * (1.0 - alphaRoughnessSq) + alphaRoughnessSq);

    return 0.5 / (GGXV + GGXL);
}

Diffuse Term

Lambert

vec3 diffuse(MaterialInfo materialInfo)
{
    return materialInfo.diffuseColor / M_PI;
}

Features

  • glTF 2.0
  • KHR_lights_punctual extension
  • KHR_materials_pbrSpecularGlossiness
  • KHR_materials_unlit extension
  • KHR_texture_transform extension