javascript - 光动没有效果

标签 javascript html three.js light

我正在编写一个交互式程序,用户可以在其中更改 Material 、灯光和显示的对象。我编写所有 HTML 表和 javascript 事件来处理用户交互的部分,我认为效果很好,所以我在这里仅发布相关部分,我将添加整个文件的链接。

这里我创建了场景、对象、灯光和渲染函数:

var scene= new THREE.Scene();
var camera= new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);
var renderer= new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth,window.innerHeight);
document.body.appendChild(renderer.domElement);
camera.position.z=5;


var geometry= new THREE.SphereGeometry(1,15,15);
var material= new THREE.MeshLambertMaterial({color:0xffffff, ambient:0xffffff, emissive:0xffffff});
var object= new THREE.Mesh(geometry,material);
material.name= "lambert";
object.name= "sphere";
scene.add(object);

var light= new THREE.PointLight(0xffffff);
light.position.set(0,0,20);
light.name= "point";
scene.add(light);


var render= function() {
    requestAnimationFrame(render);
    renderer.render(scene,camera);
}
render();

然后每次用户通过按钮更改参数时,我都会使用这些函数来更改 Material 和灯光特性:

function changeLightParameters() {
    var lightParameters= getLightParameters();
    if(lightParameters== null) {
        alert("Invalid values");
        return;
    }
    if(light.name!= lightParameters.type) {
        scene.remove(light);
        if(lightParameters.type== "spot") {
            light= new THREE.SpotLight(lightParameters.color);
        }
        else if(lightParameters.type== "point") {
            light= new THREE.PointLight(lightParameters.color);
        }
        else if(lightParameters.type== "ambient") {
            light= new THREE.AmbientLight(lightParameters.color);
        }
        else if(lightParameters.type== "area") {
            light= new THREE.AreaLight(lightParameters.color);
        }
        else if(lightParameters.type== "directional") {
            light= new THREE.DirectionalLight(lightParameters.color);
        }
        light.position.set(lightParameters.position.x, lightParameters.position.y, lightParameters.position.z);
        light.name= lightParameters.name;
        scene.add(light);
    }
    else {
        light.position= lightParameters.position;
        light.color= new THREE.Color(lightParameters.color);
    }
}


function changeMaterialParameters() {
    var materialParameters= getMaterialParameters();
    if(materialParameters== null) {
        alert("Invalid values");
        return;
    }
    if(materialParameters.type!= material.name) {
        scene.remove(object);
        if(materialParameters.type== "lambert") {
            material= new THREE.MeshLambertMaterial({
        color:materialParameters.diffuse, 
                ambient:materialParameters.ambient,
                emissive:materialParameters.emissive });
        }
        else if(materialParameters.type== "normal") {
            material= new THREE.MeshNormalMaterial();
        }
        else if(materialParameters.type== "phong") {
            material= new THREE.MeshPhongMaterial({
                color:materialParameters.diffuse,
                ambient:materialParameters.ambient,
                emissive:materialParameters.emissive,
                specular:materialParameters.specular,
                shininess:materialParameters.shininess });
        }
        material.name= materialParameters.type;
        object= new THREE.Mesh(geometry,material);
        scene.add(object);
    }
    else {
        material.color= new THREE.Color(materialParameters.diffuse);
        material.ambient= new THREE.Color(materialParameters.ambient);
        material.emissive= new THREE.Color(materialParameters.emissive);
        material.specular= new THREE.Color(materialParameters.specular);
        material.shininess= new THREE.Color(materialParameters.shininess);
        material.needsUpdate= true;
    }
}

在这些函数中,我使用 getMaterialParameters()getLightParameters() 来获取在两个表中传递的所有参数,其中包含一些文本字段来处理值。我已经测试了这些函数并且它们可以工作,因此没有必要查看代码。这些函数返回具有以下结构的对象:

Light : color (number)
        position (THREE.Vector3)
        type (string, possibile values "ambient", "point", "spot", "point", "directional")

Material: diffuse (number)
          ambient (number)
          emissive (number)
          specular (number)
          shininess (number)
          type (string, possible values "phong", "normal", "lambert")

一旦获得 Material 属性,如果 Material 类型发生变化,我会从头开始创建新 Material ,如果只是它的属性发生变化,我会更新它。对于光来说也是如此。

问题是该物体似乎对光线变化没有反应:如果我改变光线位置/颜色,什么也不会发生。我还可以将灯光的 z 设置为 -1000,这样就不会发生任何变化。 Phong 模型对我来说似乎不正确,该物体没有像应有的那样发光。示例:

enter image description here

参数为:Phong Material ,光泽度 100,漫射光 0x00abb1,发射光 0x006063,镜面反射光 0xa9fcff,光泽度 100。白点光位置 (20,20,200)。如果我将光线移至 (0,0,0),球体看起来是一样的。这似乎不现实,我想我做错了什么。

请告诉我是否需要添加更多详细信息,完整代码在这里:http://pastebin.com/3uwgwvfE

更新

我发现问题在于当场景已经初始化时我无法添加新的灯光。我制作了一个新程序,它是如何重现问题的示例:我开始使用聚光灯,然后当用户单击 Canvas 时,我从场景中删除灯光并添加新灯光(定向)。但它不起作用:没有照明,我只看到环境成分。代码在这里:http://pastebin.com/BVU0dPi3

最佳答案

问题是当我改变灯光类型时,我必须更新 Material ;当我移动灯光时,同样无效。所以程序通过添加这一行来工作:

// Change type of light and add it to the scene
material.needsUpdate= true;

关于javascript - 光动没有效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19279025/

相关文章:

javascript - 检测用户是否从 Chrome 扩展程序登录

javascript - 使用 Javascript 播放 HTML5 视频

javascript - 突出显示文本的搜索栏

三.js OrbitControls。如何更新旋转相机?

javascript - THREEjs - 裁剪纹理而不是拉伸(stretch)以适应

javascript - MVC : Share Javascript file between projects in the same solution

javascript - 如何在angularjs中使用带有输入表单的md对话框?

html - 如何控制 flex 元素的子div高度

html - 如何设置此栏的背景

javascript - 如何在 Three.js 中检查两个凸多面体是否相交?