我了解 Lambert 和 Phong 在一般计算机图形学中的区别。我也了解我们如何使用 three.js 更改和创建我们自己的材质。但我无法弄清楚 MeshLambertMaterial 和 MeshPhongMaterial 在默认状态下的区别。
我曾尝试在具有一个定向光源和 125 个球体的场景中切换它们,但我看不出任何差异。Three.js 正在我书中的一个章节中使用,因此我需要确保所有信息都准确无误。
谢谢,谢恩
Shane,你糊涂不是你的错。
Lambert 是从表面反射的光的照明模型(具有物理基础),以入射照明相对于入射点表面法线的方向表示。
Phong 是一种更细致入微的着色模型(尽管它更老套),它表示光由环境 + 漫反射 + 镜面反射分量组成。它将环境分量视为无处不在(hack!),漫反射分量使用上面的 Lambertian 模型,镜面反射分量使用幂律衰减(这是一个巧妙的 hack,大致接近实际的 BRDF)。
“Phong”这个词也是一种插值方法(在现代基于三角形的渲染管道中使用时)。在计算三角形内部像素的照明时,您有两种选择:
Gouraud 着色:计算三个顶点的颜色并在内部插值,使用重心坐标,或
Phong shading:使用三个顶点的法线,在内部插入法线,并在每个像素处使用这个插入的法线计算阴影。
这就是为什么(正如@RayToal 指出的那样),如果您的镜面反射“高光”落在三角形的内部,则没有一个顶点会变亮,但 Phong 着色会插入法线并且内部会有一个亮点你渲染的三角形。
我假设您想要MeshLambertMaterial
和MeshPhongMaterial
在three.js 中实现的确切区别。
您必须区分着色模型和照明模型。Three.js 没有实现“纯”Phong 或 Lambert 模型。
对于MeshLambertMaterial
,在每个顶点处执行照明计算,并将生成的颜色插值到多边形的整个面上。(Gouraud 着色;(广义)Lambert 光照模型)
对于MeshPhongMaterial
,顶点法线在多边形的表面上进行插值,并在每个纹素上进行光照计算。(Phong 着色;(广义)Phong 光照模型)
当您有一个靠近面部的点光源时,您会看到明显的差异——尤其是当灯光的衰减距离小于到面部顶点的距离时。
对于这两种材质,在 的情况下FlatShading
,面法线替换每个顶点法线。
三.js.r.66
在计算机图形学中,将Phong 反射模型与Phong 着色混淆是很常见的。前者是像Lambertian这样的点局部照明模型,后者是像Gouraud shading这样的插值方法。如果您发现很难区分它们,这里有一个关于每个主题的详细文章列表。 http://en.wikipedia.org/wiki/List_of_common_shading_algorithms
如果您了解一点 GLSL,我认为您最好的办法是查看两种情况下生成的顶点/片段着色器并寻找差异。可以使用http://benvanik.github.com/WebGL-Inspector/获取程序的代码,或者console.log()
在三个js源中的正确位置放一个(找buildProgram,你应该输出prefix_fragment + fragmentShader
并prefix_vertex + vertexShader
看到程序代码)。
此外,您可以查看用于创建两个着色器的构建块:
兰伯特: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
它可能比查看源程序代码更具可读性。