Closed mrdoob closed 9 years ago
We actually implemented this two years ago, but it is coming to light now. We just made physically-based shading the default in three.js r.65.
The short answer to the referenced comment is the that cosine term is part of the reflectance equation.
Lo( x, ωo ) = ∫ fr( x, ωo, ωi ) Li( x, ωi ) cos( θi ) dωi
The specular normalization constant is required to normalize the integrand of the fr
term, which is the bi-directional reflectance distribution (BRDF).
There are many references for how to implement the lighting equation for point lights, but here are two excellent ones from the 2010 SIGRAPH: Hoffman_a, Hoffman_b.
It is especially important to use reasonable constants now that a physically-based model is the default in three.js.
Set the ambient
reflectance of the material to match the material's diffuse reflectance (three.js calls this color
).
Set the specular
reflectance for non-metals in the 0x050505
to 0x101010
range, or so. The shininess
parameter can range from 1 to 10000.
For metals, you will have to experiment. The specular term can be anything up to 0xffffff
. (For metals, the specular term is the color.) In theory at least, the diffuse and ambient terms should be zero for metals, but I have achieved better-looking results with non-zero diffuse.
OK, I can see that the shader now implements the physically based model given in the second linked paper and there is justification for the formula, but I'd argue that it has nothing to do with being a "Phong" material anymore, so using "usual" Phong material settings would result in strange looking output... I realize I can manually change material settings to get reasonable appearance again, but for the most part I don't control the materials of the models I am displaying... Anyway, thanks for the explanation, easy enough to work around on my side, but the regular Phong model should have at least been kept as an ifdef option for the "MeshPhongMaterial"...
I'd argue that it has nothing to do with being a "Phong" material anymore
You have to differentiate between the shading model and the illumination model.
For MeshLambertMaterial
, the illumination model is Lambertian, and the shading model is Gouraud.
For MeshPhongMaterial
, the illumination model is (modified) Blinn-Phong, and the shading model is Phong.
the regular Phong model should have at least been kept as an ifdef option for the "MeshPhongMaterial"
There are dozens of other models that could have been pre-packaged for the user, but these were the two that were selected.
Fortunately, using ShaderMaterial
, you can implement any illumination/shading model you like.
I wonder if it would make more sense if MeshLambertMaterial
got renamed to MeshGouraudMaterial
...
I wonder if it would make more sense if MeshLambertMaterial got renamed to MeshGouraudMaterial...
I think the names should be based on what is important about about the material's illlumination model, not the shading technique...
To review, MeshPhongMaterial
uses the phong
shader to implement a physically-based, microfacet BRDF illumination model.
The model has
The Distribution term is derived from the Blinn-Phong model.
The MeshPhongMaterial
shading model is Phong: vertex normals are interpolated across the surface of the polygon, and the illumination calculation is performed at each texel.
MeshLambertMaterial
uses the lambert
shader to implement a simple Lambertian illumination model.
The MeshLambertMaterial
shading model is Gouraud: the illumination calculation is performed at each vertex, and the resulting color is interpolated across the face of the polygon.
MeshPhongMaterial
and MeshLambertMaterial
and MeshBasicMaterial
support
In addition, MeshPhongMaterial
and MeshLambertMaterial
also support
And MeshPhongMaterial
adds
CanvasRender
uses Gouraud shading because it has to.
Do we really need to implement Gouraud shading with WebGLRenderer
?
Do we need MeshLambertMaterial
at all?
Usually those things are named after the lighting model, not after being per-vertex or per-pixel interpolated. Since the new lighting formula is decidedly not the Blinn-Phong model (Hoffman started with it, but changed pretty much all the terms), yet the material does all the usual things one expects to see in a gaming uber-material, I'd suggest renaming MeshPhongMaterial to MeshUberMaterial (or MeshStandardMaterial?).
While it's inconvenient that the change to the lighting computation regressed appearance of existing scenes, it was easy enough to track down, and if I'm the only one complaining, please ignore my shader patch.
@tstanev suggests here a tweaked code to calculate the specular component:
It goes a bit over my head at the moment so some comments would be very much appreciated.