Game Development Community

Physically Based Rendering

by Pierre DragoFire Hay · in Torque 3D Professional · 03/05/2014 (4:39 pm) · 156 replies

I've been slowly reading up on this and wonder if anyone else has looked into this or done any work with it and T3D yet?

For those who don't know what Physically Base Rendering or as some call it Physically Based Shading is here's a topic over at RSI covering what is physically based rendering, this covers most aspects of PBR without getting to technical.

What is PBR or sometimes refered to as PBS or BRDF
The most trivial explanation of a PBR/PBS/BRDF (physical based renderer / physical based shader / bidirectional reflectance distribution function) is that it is the bit of shader code describing how a surface reacts to light. Generally, it is responsible for calculating the specular highlights and diffuse characteristics of the surface material. They are mathematical approximations of how surfaces react to light in the real world. In computer graphics, we try to model the physical world as accurately as possible, but we are constrained by computation. For this reason, the mathematical efficiency of BRDFs is very important. Some of the better known BRDFs - Blinn, Phong and Lambert, for instance - are well known for this reason: they are computationally inexpensive to calculate and intuitive to adjust. However they compromise efficiency for accuracy. If we concern ourselves with more expensive and more accurate models, we uncover a second layer of shading models: Oren-Nayar, Cook-Torrance, Askikhmin-Shirley, etc.
There is no single model that fits every situation, but there are some better than others. The Cook-Torrance model has been shown to be a top performer, when compared against actual acquired BRDF data. Of course, with the good comes the bad and Cook-Torrance is one of the most expensive models to compute. But for overall results, it is hard to beat. So this is our target; a nice implementation of the Cook-Torrance reflectance model. Now this maybe an issue when using Cook-Torrance model on mobiles and consoles due to hardware limitations, so it's a question of which module to use.
What's required?
Base PBR implementation consists of 3 things;
Gamma-correct rendering
  • Shading inputs (textures, light colors, vertex colors, etc.) naturally authored, previewed [li]and (often) stored with nonlinear (gamma) encoding
  • Final frame buffer also uses nonlinear encoding
  • This is done for good reasons
    [li]Perceptually uniform(ish) = efficient use of bits
  1. Legacy reasons (tools, file formats, hardware)
Support for HDR values
[ul]
  • Realistic rendering requires handling values much higher than display white (1.0)
  • Before shading: light intensities, lightmaps, environment maps
  • Shading produces highlights that affect bloom, fog, DoF, motion blur, etc.
  • Cheap solutions exist
  • Good tone mapping (ideally filmic)
    Difference between textures and materials.

    There are few fundamental distinctions between textures and materials. For example, you cannot apply a texture on a static mesh or BSP geometry. Textures have to be a part of a material. The material is what you would use to texture your environment and apply to Static Meshes.

    Here are the differences between a texture and a material:

    Textures is a single file, a 2d static image. It is usually a diffuse, specular or a normal map file that you would create in Photoshop or Gimp, as a tga, tiff, bmp, png file. These can be manipulated photographs, hand-painted textures or textures baked in an application such as xNormals.

    www.worldofleveldesign.com/categories/udk/images/013-texture-vs-material-04.jpg
    Materials are made up of various textures combined together inside a Material Editor(in-engine or 3rd party editor). Materials include various textures and material expressions that creates a network of nodes. The final result is a material you can use to apply on your BSP geometry and on Static Meshes. Materials are what you see rendered in-game.
    It should be noted that Specular[i] map on a texture, is connected to the [i]refractive index and as such describes a physical property. The shading model then varies this reflectance based on view angle and surface roughness. Thus the surface roughness is adjusted to create variety and specular not be varied for a given material.

    www.worldofleveldesign.com/categories/udk/images/013-texture-vs-material-06.jpg
    A video on PBR for Artist

    PBR in Substance by Allegorithmic

    Here's a few examples of PBR in action.

    tri-Ace Technical Demo Trailer 2011 "Physically-based Rendering"

    Star Citizen Avenger PBR
    Useful Links:
    Pixar writing a Cook-Torrance surface Shader
    Pixar writing a BRDF template
    Pixar writing a BRDF template part2
    Pixar CookTorrance Slim Template
    Shading course 2012
    Shading course 2013
    Physically Based Lighting in Black-Ops
    Shader code for physically based lighting
    Basic Theory of Physically-Based Rendering
    Paprika Render
    Mitsuba Render
    PBRT Org.
    Unreal PBR
    Houdini Shaders for physically based rendering (PBR)
    D3DBook:(Lighting) Cook-Torrance
    Specular BRDF Reference by Brian Karis from Epic game


    Books of Interest:
    Physically Based Rendering, From Theory to Implementation
    ShaderX7
    The RenderMan, Shading language Guide

    Edit: Updated with new information and links.
    #101
    06/11/2014 (1:49 am)
    It uses Big world client too. Actually wargaming bought BigWorld. Anyway World of tanks still uses a Direct3D9 pipeline and their material system barley changed with the changeover. They now use a metallic gloss map in place of their old specular map. The new metallic gloss map only contains metallic in one channel and the other contains roughness.

    It's not the best PBS results you will ever see but it's an improvement on their old system.
    #102
    06/11/2014 (2:00 am)
    @Timmy

    I thought I saw somewhere back in 2009 they were going down the path of using Havok engine as the client engine. I'm guessing they decide not too?!

    Yip, it also show you don't need to have DX11 to get PBR/PBS working with good results. Nice find on those images by the way! :)
    #103
    06/11/2014 (3:25 am)
    Here is my own PBS work in progress for my tank viewer i make for World of Tanks, unlike world of tanks it is OpenGL based (not that API matters for this). The PBS is incomplete at this stage but here are some early pics. The shadowing needs fixing now, it was ok before.

    Pic 1: i.imgur.com/iSipI5D.png
    Pic 2: i.imgur.com/dODqeLc.png
    Pic 3: i.imgur.com/HqS8SH0.png

    Before the change over i.imgur.com/xvm4115.png


    #104
    06/11/2014 (11:56 am)
    looks good. if you get a change get your hands on "Physically Based Rendering, From Theory to Implementation", the guys that wrote it have some 12 years of experience with PBR.

    just a note if you want to show images.

    Images
    Markup Lite can display images encased in the [image], [/image] tags. Note that the "http://" part of the image URL is completely optional. You can also use align (left & right), hspace, vspace and borders inside the [image] tag.

    [image]www.mysite.com/images/wow.jpg[/image]
    [image align=right hspace=10 vspace=5 border=0]www.mysite.com/images/wow.jpg[/image]
    #105
    06/11/2014 (12:10 pm)
    @pierre: Since it seems you've read the book a few times, wanna go ahead and cook up a comparison chart with what they list with an eye to what is already implemented (again, see: The list of already embedded and tracked variables), what they explicitly mention as being done different, and what they've decided can be either cut out or needs addition?
    #106
    06/11/2014 (12:59 pm)
    @Azaezel

    Sure I'll see what I can do.

    In the meantime here's PBR at github it's a good place to start for those who are interested.
    #107
    06/11/2014 (1:19 pm)
    If you're interested here's the api.cpp for pbr from github.

    It's too large to post the code here (1284 lines (1125 sloc))
    #108
    06/11/2014 (1:24 pm)
    material.ccp

    /*
        pbrt source code Copyright(c) 1998-2012 Matt Pharr and Greg Humphreys.
    
        This file is part of pbrt.
    
        Redistribution and use in source and binary forms, with or without
        modification, are permitted provided that the following conditions are
        met:
    
        - Redistributions of source code must retain the above copyright
          notice, this list of conditions and the following disclaimer.
    
        - Redistributions in binary form must reproduce the above copyright
          notice, this list of conditions and the following disclaimer in the
          documentation and/or other materials provided with the distribution.
    
        THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
        IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
        PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
        HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
        LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
     */
    
    
    // core/material.cpp*
    #include "stdafx.h"
    #include "material.h"
    #include "primitive.h"
    #include "texture.h"
    #include "spectrum.h"
    #include "reflection.h"
    
    // Material Method Definitions
    Material::~Material() {
    }
    
    
    void Material::Bump(const Reference<Texture<float> > &d,
                        const DifferentialGeometry &dgGeom,
                        const DifferentialGeometry &dgs,
                        DifferentialGeometry *dgBump) {
        // Compute offset positions and evaluate displacement texture
        DifferentialGeometry dgEval = dgs;
    
        // Shift _dgEval_ _du_ in the $u$ direction
        float du = .5f * (fabsf(dgs.dudx) + fabsf(dgs.dudy));
        if (du == 0.f) du = .01f;
        dgEval.p = dgs.p + du * dgs.dpdu;
        dgEval.u = dgs.u + du;
        dgEval.nn = Normalize((Normal)Cross(dgs.dpdu, dgs.dpdv) +
                              du * dgs.dndu);
        float uDisplace = d->Evaluate(dgEval);
    
        // Shift _dgEval_ _dv_ in the $v$ direction
        float dv = .5f * (fabsf(dgs.dvdx) + fabsf(dgs.dvdy));
        if (dv == 0.f) dv = .01f;
        dgEval.p = dgs.p + dv * dgs.dpdv;
        dgEval.u = dgs.u;
        dgEval.v = dgs.v + dv;
        dgEval.nn = Normalize((Normal)Cross(dgs.dpdu, dgs.dpdv) +
                              dv * dgs.dndv);
        float vDisplace = d->Evaluate(dgEval);
        float displace = d->Evaluate(dgs);
    
        // Compute bump-mapped differential geometry
        *dgBump = dgs;
        dgBump->dpdu = dgs.dpdu + (uDisplace - displace) / du * Vector(dgs.nn) +
                       displace * Vector(dgs.dndu);
        dgBump->dpdv = dgs.dpdv + (vDisplace - displace) / dv * Vector(dgs.nn) +
                       displace * Vector(dgs.dndv);
        dgBump->nn = Normal(Normalize(Cross(dgBump->dpdu, dgBump->dpdv)));
        if (dgs.shape->ReverseOrientation ^ dgs.shape->TransformSwapsHandedness)
            dgBump->nn *= -1.f;
    
        // Orient shading normal to match geometric normal
        dgBump->nn = Faceforward(dgBump->nn, dgGeom.nn);
    }
    #109
    06/11/2014 (1:25 pm)

    material.h

    /*
        pbrt source code Copyright(c) 1998-2012 Matt Pharr and Greg Humphreys.
    
        This file is part of pbrt.
    
        Redistribution and use in source and binary forms, with or without
        modification, are permitted provided that the following conditions are
        met:
    
        - Redistributions of source code must retain the above copyright
          notice, this list of conditions and the following disclaimer.
    
        - Redistributions in binary form must reproduce the above copyright
          notice, this list of conditions and the following disclaimer in the
          documentation and/or other materials provided with the distribution.
    
        THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
        IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
        PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
        HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
        LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
     */
    
    #if defined(_MSC_VER)
    #pragma once
    #endif
    
    #ifndef PBRT_CORE_MATERIAL_H
    #define PBRT_CORE_MATERIAL_H
    
    // core/material.h*
    #include "pbrt.h"
    #include "memory.h"
    
    // Material Declarations
    class Material : public ReferenceCounted {
    public:
        // Material Interface
        virtual BSDF *GetBSDF(const DifferentialGeometry &dgGeom,
                              const DifferentialGeometry &dgShading,
                              MemoryArena &arena) const = 0;
        virtual BSSRDF *GetBSSRDF(const DifferentialGeometry &dgGeom,
                                  const DifferentialGeometry &dgShading,
                                  MemoryArena &arena) const {
            return NULL;
        }
        virtual ~Material();
        static void Bump(const Reference<Texture<float> > &d, const DifferentialGeometry &dgGeom,
            const DifferentialGeometry &dgShading, DifferentialGeometry *dgBump);
    };
    
    
    
    #endif // PBRT_CORE_MATERIAL_H
    #110
    06/11/2014 (1:30 pm)
    Hopefully this provides an ideal of what maybe required to be added to Torque3D as PBR is developed for it.
    #111
    06/11/2014 (2:55 pm)
    I am quite aware how to post images, take a look at my many other posts. I prefer giving people a link and they CAN CHOOSE if they want to see them
    #112
    06/11/2014 (3:24 pm)
    @Pierre, i think pbrt-v2 are a raytracer. Not sure if it's a good example for a game engine.
    #113
    06/11/2014 (4:21 pm)
    Quote:Hopefully this provides an ideal of what maybe required to be added to Torque3D as PBR is developed for it.


    To be the blunt a-hole of the conversation: Without digging down into what is actually different between that implementation and what is already in place, no. It is actually actively counterproductive to analysis to just throw up functions whole-cloth.

    To be crystal clear: Answering the question "What needs changing" with "All of it." is not helpful in the slightest.
    #114
    06/12/2014 (1:26 am)
    @Azaezel

    I'm lost where did All of it come from in regards to what needs changing? I must be tired as I don't see it.

    If it relates to;

    Quote:we all know this is a big project as it'll involve a complete rewrite of the material system and shader pipeline to implement the basics.

    I've even spoken with Lorne McIntosh (SSOA and DoF kit developer) and been advised of this, I've asked if he can provide any help on that side of things.

    As some know Lorne did a lot of work on Real-Time Screen Space Ambient Occlusion Shaders and Real-Time Depth of Field Shader for Torque which made sense to ask him about the current shader within Torque and what PBR requires.

    Then I'm sorry if I hadn't written my post well enough.

    What was meant is that from what said in email between myself and Lorne, was there is a very likelihood that the T3D's material system and shader pipeline would require a rewrite to implement real-time PBR into T3D[/quote]

    I paraphrased what was in the email a bit. But the general thing was Lorne was very excited to see movement in this direction of getting PBR into T3D. But ATM he wasn't up to speed with PBR himself.

    So I'm sorry if I confused anyone with this.
    #115
    06/12/2014 (1:37 am)
    @Luis Anton Rebollo

    I know one of the authors Greg Humphreys was part of the OptiX raytracing team at NVIDIA.

    Anyhow I'm going to see what I can find to help bring an PBR system into Torque3D. There have been a few that have just said go use UE3, which is a fair comment, but after how long I've been within the GarageGames community I'd personally like to see something like this project done to compete with UE3 and other games out there, that are now competing with Torque3D in the indie area. But this is a personal view.
    #116
    06/12/2014 (2:02 pm)
    @Luis Anton Rebollo

    You are partly right, the book "Physically Based Rendering: From Theory to Implementation" By Matt Pharr and Greg Humphreys PBR system is based on ray-tracing algorithm's.
    #117
    06/16/2014 (3:05 pm)
    Hmm... What happened to this discussion, it is really interesting...
    #118
    06/16/2014 (3:37 pm)
    Short answer: We got to work on prototyping and practical R&D.

    I'll leave it at that for now.
    #119
    06/16/2014 (9:42 pm)
    Just heard back from one of the guys I emailed last week. Here's what he's said.

    Quote:
    Base PBR implementation consists of 3 things - Reflection Sampling module, Image Based Lighting and a Shader System that makes use of it.

    The core of PBR is having the ability to have full reflectivity on every material. No generic cubemaps per level but rather a set of sampling points in the world to draw reflection information from(Spherical Harmonics nodes for example). You reflection information is actually your lighting in the truest sense of it, so you have to have a lighting system that can marry the two effectively.
    Everything else would probably just be expanding on that: different BRDF models, realtime GI(octree based Light Propagation Volumes for example), Area Lights and Inverse Square Light Falloff etc...

    I would strongly advice you guys to get familiar with last years Siggraph PBS course:

    s2013 shading-course

    and unreal 4 implementation specifically as a good baseline:

    s2013 PBS EPIC notes v2 PDF

    Most of the math you might need you can probably find in the course notes to those talks.

    Also feel free to use my asset as a content example:

    #120
    06/17/2014 (3:12 am)
    Quote:
    and unreal 4 implementation specifically as a good baseline

    Gotta say i got a good chuckle out of this one.