lambert brdf

https://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/
https://chenanbao.github.io/2018/11/26/PBR%E6%B5%85%E6%9E%90/
http://www.oceanopticsbook.info/view/surfaces/lambertian_brdfs

with physically based rendering current trend of photo-realistic game, i feel the need to do my lighting equation more physically correct. a good start for this is to try to understand how our currently game lighting equation behave. for a long time, the presence or not in my game lighting equation of term π or 1/π have been more based on trial and error than physics. the origin of these terms in game lighting equations have already been discussed by others [1][3][7][12].
but as i found this subject confusing i dedicated this post only to that topic. this post is not about code, it is about understanding what we do under the hood and why this is correct. i care about this because more correct game lighting euqations mean consistency under different lighting condition, so less artists time spend to tweak values. i would like to than Stepen Hill for all the help he provide me around this topic.

this post is written as a memo for myself and as a help to anyone which was confusing as i was. any feedback are welcomed.

i will begin this post by talking about Lambertian surface and the specificity of game light’s intensity then talk about diffuse shading and conclude by specular shading. i will not define common term found in lighting field like BRDF, Lambertian surface … see [1] for all these definitions and notation of this post.

Origin of π term confusion
the true origin of the confusing π term come from the Lambertian BRDF which is the most used BRDF in computer graphics. the Lembertian BRDF is a constant define as:

在这里插入图片描述
the notation f(lc,v) mean BRDF parameterized by light vector lc and view vector v. the view vector is not used in the case of Lambertian BRDF. Cdiff is what we commonly call diffuse color.

the first confusing 1/π term appear in this formula. it come from a constraint a BRDF should respect which is name conservation of energy. it mean that the outgoing energy can not be greater than the incoming energy. or in other word that u can not create light. the derivation of the 1/π can be found in [3].

as u may note, game Lambertian BRDF have not this 1/π term. let us see a light affecting a Lambertian surface in game:

FinalColor = c_diff * c_light * dot(n, l)

to understand where the 1/π disappeared, see how game light’s intensity is define. games do not ues radiometric measure as the light’s intensity but use a more artist friendly measure[1]:

for artist convenience, Clight does not correspond to a direct radiometric measure of the light’s itensity; it is specified as the color a white Lambertian surface would have when illuminated by the light from a direction parallel to the surface normal (lc = n) Clight 被定义为:一束平行于法线的光照射在白色的lambertian表面上的最终颜色。

which mean, if u setup a light in a game with color Clight and point it directly on a diffuse only quad mapped with a white diffuse texture u get the color of Clight.
也就是说,当光线的颜色为Clight,直接照射在只有漫反射的方块上,此方块是纯白色的,那么你将会得到和光线相同的颜色,即Clight.

another way to see this definition is by taking the definition of a diffuse texture[2]:
how bright a surface is when lit by a 100% bright white light

which mean, if u setup a white light in a game with brightness 1 and point it directly on a diffuse only quad mapped with a diffuse texture, u get the color of the diffuse texture.
this is very convenient for artists which do not need to care about physical meaning of light’s intensity unit.

theses defintions allows to define the punctual light equation use in game. a punctual light is an infinite small light like diretional, point or spot light common in games.
在这里插入图片描述
The derivation and the notation of this equation is given in [1]. Lo(v) is the resulting exit radiance in the direction of the view vector v which is what u will use as color of your screen pixel. v is not used for Lambertian BRDF.

using the punctual light equation with a Lambertian BRDF gives us:
在这里插入图片描述
Which I will rewrite more simply by switching to a monochrome light (⨂ is for RGB) :
在这里插入图片描述
this shading equation looks familiar except the \pi term. In fact after simplification we get :
在这里插入图片描述

which is our common game diffuse lighting equation.

this means that for artists convenience, the value they enter as brightness in light’s settings is in fact the result of the light brightness multiply 1/π (the energy conserving constant of Lambertian BRDF). when artists put 1 in brightness, in reality they set a brightness of π. this is represented in the punctual lighting equation by πClight. in this post, i will define as game light’s unit the fact of multiplying the light brightness by π and as game Lambert BRDF the Cdiff term which is linked.

In the following I will describe the consequence of the game light’s unit on common diffuse lighting technic use in game then on common specular lighting technic.

Diffuse lighting in game
Lambert lighting
the most common diffuse lighting equation use in game is the classic Lambert lighting describe in the introduction which is the origin of the multiply by π of the light itensity. so for this case we already describe the impact: it allow to remove the 1/π from the Lambertian BRDF.

Diffuse irradiance environment map
Lot of games choose to approximate diffuse distant lighting with irradiance environment map. For simplicity, I will use cubemap as mapping but other mapping like sphere, dual paraboloïd 抛物面… work as well.

To better understand the impact of game light’s unit intensity with diffuse irradiance cubemap lighting we need to understand how to calculate an irradiance cubemap and what is the relationship between radiance and irradiance.
I won’t go into the complex definition of these terms. Most of what I write here is from [7]. To stay simple, radiance is a measure of light in a single ray and irradiance is a measure of light incoming to a surface point from all directions. The irradiance E under mathematic form is:
在这里插入图片描述
Ω is the upper hemisphere of a surface so cosine is not clamped.

we will use a cubemap to represent the lighting environment (the function Li(l) of the equation which take a direction in parameter and return radiance for this direction).
texel of a cubemap represent radiance which are not in the game light’s unit we define in previous section:
——a “real” HDR light probe like the one provided by Paul Debevec[8] deal with real world unit.
——in-game engine generated HDR cubemap will contain only indirect lighting (in most common usage). the indirect lighting is the result of our game lighting bouncing on surface. consequence, we do not deal anymore with game light’s unit but with real world unit.

this result to :
在这里插入图片描述

dwi is the solid angle subtended (cover) by cubemap texel designed by direction l.
this formula translates simply in pseudo code:

void GetIrradiance(n)
{
    E = 0
    foreach direction l
        if (dot(n,l) > 0)
            E += cubemap(l) * dot(n, l) * texelSolidAngle(l)
}

cubemap(l) return the value of the texel in the direction l.
texelSolidAngle(l) return the solid angle for the texel in direction l
The number of direction l is defined by the cubemap resolution.

So if we want to generate an irradiance cubemap, we can use the pseudo code:

for each texel of the destination cubemap 
    Get the direction n for this texel
         GetIrradiance(n) // Use the formula above

if u are interested the C++ code for these calculation can be found in source code of AMD Cubemapgen [10].
An irradiance cubemap store irradiance E for all direction (limited by the cubemap resolution).

now that we know how to calculate irradiance cubemap, let us see how to use it. in case of Lambertian surface the exit radiance is proportional to the irradiance.
在这里插入图片描述

在这里插入图片描述 is the Lambertian BRDF. a derivation of this equation can be found in[7].
the irradiance cubemap need to be sampled by the Lambertian surface normal to retrieve irradiance E. tranlated into code we get:

L_o = (c_diff / PI) * texCube(IrradianceCubemap, normal)

however for game we use Cdiff for Lambertian BRDF due to our game light’s unit, so we would like to have:

L_o = c_diff * texCube(IrradianceCubemap, normal)

for this, we just have to turn irradiance into radiance at the irradiance cubemap generation time instead of inside the shader. turning irradiance into radiance for Lambertian surface just mean dividing by Π the irradiance E.

void GetIrradiance(n)
{
    E = 0
    foreach direction l
        if (dot(n,l) > 0)
            E += cubemap(l) * dot(n, l) * texelSolidAngle(l)
    E = E / PI
}

diffuse irradiance environment map takeaway
the takeaway here is to know what do your tool for generating irradiance cubemap. if the tools turn irradiance into radiance (divide irradiance cubemap by Π), nothing sepcial. if the tools do not do it, u must apply the divide yourself when sampling the irradiance cubemap.

AMD Cubemapgen [10] and HDRShop [11] turn the irradiance to radiance when generating irradiance cubemap. to test it, u can input a grey (constant 0.5) HDR cubemap into the tool, generate the irradiance cubemap and check it is grey (constant 0.5) in output. i suppose that most tools do this to support LDR cubemap format like ARGB8 (in this case u can not output a 0.5*Π irradiance cubemap, it will be clamped to 1.0).

specular lighting in game
for Lamberitan BRDF, all is fine. but as i said in my post about Adopting a physically based shading model https://seblagarde.wordpress.com/2011/08/17/hello-world/ care must be taken when using an energy conserving specular BRDF.

for sample, with the classical normalized phong term 在这里插入图片描述 the puntual light equation become:
在这里插入图片描述
Which simplify to
在这里插入图片描述
so when dealing with an energy conserving specular term, do not forget to divide the constant factor by Π.

Reference
[1] Hoffman, “Crafting Physically Motivated Shading Models for Game Development” and “Background: Physically-Based Shading” http://renderwonk.com/publications/s2010-shading-course/
[2] Epic game, “UDK documentation” http://udn.epicgames.com/Three/TexturingGuidelines.html
[3] “Energy conservation in game” http://www.rorydriscoll.com/2009/01/25/energy-conservation-in-games/
[4] Hill, “Righting wrap” http://blog.selfshadow.com/2011/12/31/righting-wrap-part-1/
[5] Sloan, “Efficient Evaluation of Irradiance Environment Maps” http://tog.acm.org/resources/shaderx/
[6] King, “Real-Time Computation of Dynamic Irradiance Environment Maps” http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter10.html
[7] Akenine-Möller, Haines, Hoffman, “Real-Time Rendering 3rd Edition” http://www.realtimerendering.com
[8] http://www.pauldebevec.com/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值