如何确定渲染网格的最终颜色?

时间:2013-12-23 04:59:00

标签: three.js

我们在初始化材料时给出颜色。我们还在初始化环境光和定向光源时指定颜色。如何确定网格的最终颜色。

当我改变材料的颜色时,我看到网格的最终颜色没有变化。但是,当我改变光源的颜色(环境或方向)时,网格的渲染颜色会发生变化。

所以

1)在初始化材质时使用指定颜色是什么?和

2)如何确定网格的最终颜色

darkMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
darkMaterialL = new THREE.MeshLambertMaterial( { color: 0xffff00 } );
darkMaterialP = new THREE.MeshPhongMaterial( { color: 0xffff00 } );

var ambientLight = new THREE.AmbientLight(0x00ff00);
var light = new THREE.PointLight(0x000000);
light.position.set(0,150,100);

scene.add(ambientLight);
scene.add(light);

以上是我使用的灯光和材料。

1 个答案:

答案 0 :(得分:2)

我写了一篇jsfiddle给你看看:http://jsfiddle.net/fnR4E/

var camera, scene, renderer;
var geometry    = new Array();
var material    = new Array();
var mesh        = new Array();
var light;
var angle = 0.1;

init();
render();

function init() {
    camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000);
    camera.position.z = 5;
    camera.position.y = 5;

    scene = new THREE.Scene();

    geometry[0] = new THREE.SphereGeometry(1, 8, 6, 0, Math.PI * 2, 0, Math.PI);
    geometry[1] = new THREE.SphereGeometry(1, 8, 6, 0, Math.PI * 2, 0, Math.PI);
    geometry[2] = new THREE.SphereGeometry(1, 8, 6, 0, Math.PI * 2, 0, Math.PI);

    material[0] = new THREE.MeshBasicMaterial({ color: 0xff0000 });
    material[1] = new THREE.MeshLambertMaterial({ ambient: 0xffffff, color: 0x00FF00 });
    material[2] = new THREE.MeshPhongMaterial({ ambient: 0xffffff, color: 0xdddddd, specular: 0xFFFFFF, shininess: 15 });

    mesh[0] = new THREE.Mesh(geometry[0], material[0]);
    mesh[1] = new THREE.Mesh(geometry[1], material[1]);
    mesh[2] = new THREE.Mesh(geometry[2], material[2]);

    var ambientLight = new THREE.AmbientLight(0x007700);
    var light = new THREE.PointLight(0xFFFFFF);
    light.position.set(0, 2, 0);

    scene.add(ambientLight);
    scene.add(light);

    mesh[0].position.set(-2, 0, 0);
    mesh[2].position.set(2, 0, 0);

    scene.add(mesh[0]);
    scene.add(mesh[1]);
    scene.add(mesh[2]);

    renderer = new THREE.CanvasRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);

    document.body.appendChild(renderer.domElement);
}

function render() {
    requestAnimationFrame(render);

    camera.position.x = 5 * Math.cos(angle);
    camera.position.z = 5 * Math.sin(angle);

    camera.lookAt(new THREE.Vector3(0, 0, 0));

    angle += 0.01;

    renderer.render(scene, camera);
}

第一个网格使用MeshBasicMaterial,这实际上意味着它仅由材质颜色点亮,为了证明您可以将ambientLight和light的值更改为您想要的任何值,它不会影响此网格的渲染颜色。

以下两个网格(第一个是MeshLambertMaterial,第二个是MeshPhongMaterial)使用两个光源。有关每个着色模型(Lambertian和Phong)背后的理论的更多阅读,请查看这些优秀的维基百科文章:

http://en.wikipedia.org/wiki/Lambertian_reflectance http://en.wikipedia.org/wiki/Phong_reflection_model

这是对正在发生的事情的一个更“实际”的解释(但你可能至少想参考维基文章中讨论的方程式):

ambientLight乘以材质'ambient'值以产生网格环境颜色。此颜色仅用于材料的漫反射颜色指定的量。例如,如果材质环境值为0xFFFFFF且AmbientLight为0x00FF00,则网格具有完全绿色环境光 - 但是,如果材质的漫反射颜色('颜色')包含无绿色通道(例如0xFF00FF),则表示没有环境光应用于网格。或者,如果漫反射颜色为0x007700(整个绿色通道的一半),那么您将在颜色0x007700的对象上看到环境光。

漫反射颜色由材质“颜色”值表示。这是网格的感知颜色。在Lambert和BlinnPhong着色模型中,该颜色乘以顶点或片段法线与光矢量的点积。从本质上讲,这意味着顶点或碎片越直接点亮 - 它就越接近完整的漫反射颜色。根本没有被光源直接点亮的顶点或片段是黑色的。此点积计算中不包含AmbientLight源。

注意:在此点积计算中,会占用遮挡网格。仅考虑光源与顶点或片段之间的角度。

最后,MeshPhongMaterial使用一个名为specular的附加属性。这是在网格上产生“闪亮”光斑的反射光。这来自于计算来自光源的法线的反射角。材质属性“镜面反射”决定了该反射点的颜色。再次,AmbientLight源不包含在此照明计算中。

注意:在此计算中再次考虑遮挡网格而不是

解决了问题。