我在ThreeJS中创建具有金属外观的表面时遇到了一些麻烦。我知道我需要使用MeshPhongMaterial材质类型,但是似乎无法正确设置它。

到目前为止,这就是我所得到的,但是它只会产生黑色表面。

var material = new THREE.MeshPhongMaterial({
    color: 0xBCC6CC,
    shininess: 30,
    metal: true,
    wrapAround: true,
    shading: THREE.FlatShading
});


对于MeshPhongMaterial的不同参数对不熟悉3d图形领域的人实际上意味着什么的任何见解,将不胜感激。

最佳答案

“ Phong着色”将基于在矢量图形的顶点(点)上插入法向矢量来创建着色效果。然后,每个角都有一个方向向量,该向量指向表面面对的方向。即使由四边形或三角形组成,此方向的插值也会产生假的表面“平滑”效果。

https://en.wikipedia.org/wiki/Phong_shading

如果要手动构建几何,则应记住使用以下方法计算“电话”阴影的“面法线”:

geometry.computeFaceNormals();


诸如THREE.CylinderGeometry之类的内置Three.js几何体会在of their constructor末尾自动设置法线。检查它们如何构建几何体很有用。

如果手动构建网格,则还可以在面构造器中提供法线

var face = new THREE.Face3( 0, 1, 2, normal, color, 0 );


normal可以是面的法线或顶点法线的数组,并且可以指示Phong着色器将这些顶点法线与THREE.SmoothShading而不是THREE.FlatShading一起使用-后者将仅使用面法线。

shininess定义从点光源反射的光量-如果增加该值,镜面反射部分将变得更清晰,零表示没有镜面反射分量。反射模型在这里说明:

https://en.wikipedia.org/wiki/Phong_reflection_model

由于金属质感来自点光源,这些点光源会产生镜面反射的错觉,因此您必须在表面附近添加一些光源:

http://threejs.org/docs/#Reference/Lights/PointLight
http://threejs.org/docs/#Reference/Lights/SpotLight
http://threejs.org/docs/#Reference/Lights/DirectionalLight

全部在文档中


  使用MeshLambertMaterial或MeshPhongMaterial影响对象。


metal将表面颜色与镜面反射光相乘,这会使表面颜色变暗-例如,如果的表面颜色分量为,而镜面反射高光的颜色值为,则结果为,创建较暗的高光分量。


  如果设置为true,则着色器将镜面高光乘以
  对象的基础颜色,使其看起来更像金属
  和更暗。如果设置为false,则镜面反射高光将添加到
  基础颜色。


文档中的wraparound


  定义漫射照明是否环绕模型。
  此选项将更多(可着色)的光线添加到
  与光有关的物体。


但这只是理论,如果您有兴趣了解它的实际工作原理,则可以从Three.js源代码中检查如何实现由WebGL馈入GPU的Fragment Shader:

https://github.com/mrdoob/three.js/blob/master/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl

真正的东西在那里,即使文档仅提到影响MeshPhongMaterial的PointLight,SpotLight和DirectionalLight,您也可以看到它们,而Diffuse和Ambient灯光也会影响表面的闪电和颜色,就像它们应该那样。

关于javascript - 具有ThreeJS的金属表面,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31093447/

10-12 12:39
查看更多