我理解Lambert和Phong在一般计算机图形学中的区别。我也理解如何使用three.js更改和创建自己的材料。但我无法弄清楚MeshLambertMaterial和MeshPhongMaterial在默认状态下的区别。
我尝试在一个带有单向光源和125个球体的场景上切换它们,我看不出任何差异。 Three.js正在我书的一章中使用,因此我需要确保所有信息的准确性和准确性。
谢谢, 沙恩
答案 0 :(得分:23)
Lambert是一种照射模型(具有物理基础),用于从表面反射的光,以入射照明相对于入射点处表面法线的方向表示。
Phong是一个更加细致入微的阴影模型(尽管它更像一个hacky),它说光是由环境+漫反射+镜面反射分量组成的。它将环境分量视为常量(hack!),使用上述Lambertian模型的漫反射分量,以及使用幂律衰减的镜面反射分量(这是一个聪明的黑客,大致接近实际的BRDF)。
“Phong”这个词也是一种插值方法(当在现代三角形渲染管道的上下文中使用时)。计算三角形内部像素的照度时,您有两种选择:
Gouraud着色:使用重心坐标计算三个顶点的颜色并在内部进行插值,或
Phong着色:使用三个顶点处的法线,在内部插入法线,并在每个像素处使用此插值法线计算着色。
这就是为什么(正如@RayToal指出的那样),如果你的镜面反射“高光”落在三角形的内部,没有一个顶点是明亮的,但是Phong阴影会插入法线并且会有一个亮点在渲染三角形的内部。
答案 1 :(得分:21)
我假设你想要在three.js中实现MeshLambertMaterial
和MeshPhongMaterial
之间的确切差异。
您必须区分着色模型和照明模型。 Three.js没有实现'纯'Phong或Lambert模型。
对于MeshLambertMaterial
,在每个顶点处执行照明计算,并且在多边形的面上插入所得到的颜色。 (Gouraud阴影;(广义)Lambert照明模型)
对于MeshPhongMaterial
,顶点法线在多边形的表面上进行插值,并且在每个纹素处执行照明计算。 (Phong着色;(广义)Phong照明模型)
当你有一个靠近脸部的pointLight时,你会看到一个明显的区别 - 尤其是当光线的衰减距离小于到脸部顶点的距离时。
对于这两种材质,在FlatShading
的情况下,面法线取代每个顶点法线。
three.js.r.66
答案 2 :(得分:3)
在计算机图形学中,将 Phong反射模型与 Phong着色混淆是很常见的。虽然前者是像兰伯特这样的点的局部照明模型,但后者是像Gouraud阴影那样的插值方法。如果您发现难以区分它们,请参阅以下每个主题的详细文章列表。 http://en.wikipedia.org/wiki/List_of_common_shading_algorithms
答案 3 :(得分:2)
如果您了解一点GLSL,我认为您最好的办法是查看两种情况下生成的顶点/片段着色器并查找差异。您可以使用http://benvanik.github.com/WebGL-Inspector/获取程序代码,或者将console.log()
放在三个js源中的正确位置(查找buildProgram,您应该输出prefix_fragment + fragmentShader
和{{1}看程序代码)。
此外,您还可以查看用于创建两个着色器的构建块:
兰伯特:https://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLShaders.js#L2036 Phong:https://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLShaders.js#L2157
它可能比查看源程序代码更具可读性。