Original Post
The Torrance-Sparrow model is a theoretical model.
Many game developers fail at getting their implementation to behave well because the model has some nasty
divisions by terms which tend toward zero. In the theoretical model this is not supposed to happen
but in computer graphics it does for various reasons. For instance the GPU will back-face cull a primitive
in a way which gives results similar to using the face normal for culling. However, we don't shade using the face normal.
This means v_dot_n in the denominator will in practice become zero when using normal maps (and even
interpolated vertex normals). Simply checking if the term is close to zero and then setting it to something else isn't
going to work either because this makes the lighting behave in a discontinuous fashion which is bad too.
So care must be taken to get the right limit value.
I have taken it upon myself to make a proposal for a reference implementation which according to my own tests
behaves extremely well.
http://jbit.net/~spa...cademic/illum.h
In case anyone is interested I derive the Torrance-Sparrow model from scratch in my academic paper:
http://jbit.net/~spa...mic/mm_brdf.pdf
I am hoping some people here might accept the task of
testing this and giving me some feedback on it.
There are 3 variants in the file:
normalized phong, Bechmann and normalized phong with a tilt.
For each of the 3 there are two versions. For instance for nphong:
1. BRDF_ts_nphong - default shading one normal
2. BRDF2_ts_nphong - optional modification (used in games)
The second one takes in addition to the shading normal also the normalized interpolated vertex normal.
This is used to disable the effect of bump mapping at the silhouette (self-shadowing).
I recommend testing these two normalized phong variants primarily.
The beckmann is mainly there as a reference since the beckmann distribution parameter can
be mapped to an nphong.
IMPORTANT! Do not multiply these by n_dot_l in your shader. This term is already built into all the implementations here
and so is the diffuse term.
Additionally, possibly experiment with disabling:
vN = FixNormal(vN, vV);
It appears it's not needed afterall. Please let me know what you think.
Thanks to all!
Morten.
Many game developers fail at getting their implementation to behave well because the model has some nasty
divisions by terms which tend toward zero. In the theoretical model this is not supposed to happen
but in computer graphics it does for various reasons. For instance the GPU will back-face cull a primitive
in a way which gives results similar to using the face normal for culling. However, we don't shade using the face normal.
This means v_dot_n in the denominator will in practice become zero when using normal maps (and even
interpolated vertex normals). Simply checking if the term is close to zero and then setting it to something else isn't
going to work either because this makes the lighting behave in a discontinuous fashion which is bad too.
So care must be taken to get the right limit value.
I have taken it upon myself to make a proposal for a reference implementation which according to my own tests
behaves extremely well.
http://jbit.net/~spa...cademic/illum.h
In case anyone is interested I derive the Torrance-Sparrow model from scratch in my academic paper:
http://jbit.net/~spa...mic/mm_brdf.pdf
I am hoping some people here might accept the task of
testing this and giving me some feedback on it.
There are 3 variants in the file:
normalized phong, Bechmann and normalized phong with a tilt.
For each of the 3 there are two versions. For instance for nphong:
1. BRDF_ts_nphong - default shading one normal
2. BRDF2_ts_nphong - optional modification (used in games)
The second one takes in addition to the shading normal also the normalized interpolated vertex normal.
This is used to disable the effect of bump mapping at the silhouette (self-shadowing).
I recommend testing these two normalized phong variants primarily.
The beckmann is mainly there as a reference since the beckmann distribution parameter can
be mapped to an nphong.
IMPORTANT! Do not multiply these by n_dot_l in your shader. This term is already built into all the implementations here
and so is the diffuse term.
Additionally, possibly experiment with disabling:
vN = FixNormal(vN, vV);
It appears it's not needed afterall. Please let me know what you think.
Thanks to all!
Morten.