【问题标题】:SpotLight not working in ThreeJSSpotLight 在 ThreeJS 中不起作用
【发布时间】:2017-04-20 17:01:56
【问题描述】:

我有一个显示一些缩略图的功能区。只是为了提供背景,将缩略图图像绘制在画布上,然后将其添加到纹理中。

var texture = new THREE.Texture(textureCanvas);

网格创建如下

    loader.load('mesh_blender.js', function(geom) {
      var mesh = new THREE.Mesh(geom, new THREE.MeshLambertMaterial({
        color: 0xffffffff,
        opacity: 0.7,
        overdraw: 0.21,
        side: THREE.DoubleSide,
        transparent: true,
        //shading: THREE.SmoothShading,
        map: texture
      }));

到这里为止一切都很好。功能区创建如下

我对此没有任何抱怨。但我需要你在下图中看到的这种额外效果。可以看出,位于中心(焦点)的缩略图需要具有较暗的效果才能显示它被突出显示/可选择。所有剩余的缩略图都具有透明效果,表示它们不可选择。

我正在尝试使用 Threejs 中的 Lights 来解决这个问题,但不是很成功。我想使用 AmbientLight 将光投射到整个色带上,然后仅在中心图像上使用额外的 SpotLight(可能颜色更深)以达到所需的效果。但这没有用。我有类似的东西

但是中心聚焦的图像没有效果。正如您在图像中看到的,我使用了一个助手来显示光的方向,但我真的看不到图像上的任何光。这是我用来开发 SpotLight 的代码

var spotLight = new THREE.SpotLight( 0xffeedd );
spotLight.position.set( 0, -50, 50 );
spotLight.castShadow = true;
    //spotLight.penumbra = 0.2;
spotLight.decay = 2;
spotLight.distance = 300;
spotLight.angle = 0.5;
var helper = new THREE.SpotLightHelper( spotLight, 2.5 );
scene.add(helper);

scene.add( spotLight );

我对 Threejs 和 3d 图形非常陌生。任何帮助将不胜感激。谢谢。如果不使用 Lights 来实现最终结果,我也愿意接受任何其他建议。

【问题讨论】:

  • 已经给出答案的另一种方法可能是创建自己的 ShaderMaterial

标签: javascript three.js


【解决方案1】:

您已将材质的不透明度设置为 0.7,因此添加另一个灯光不会完全为您提供预期的结果。我建议使用光线投射器来识别中心的对象,并将该对象的不透明度设为 1,其余设为 0.7。

var intersects = raycaster.intersectObjects( objects );

使用它来获取数组中相交的对象。并且在渲染器函数中将数组中作为中间对象的第一个元素的不透明度设置为 1。这仅适用于缩略图都是单独的对象时。

//set as the center of you vision
var mouse = new THREE.Vector2();
mouse.x = 0;
mouse.y = 0;

function highlightObject() {

// update the picking ray with the camera and mouse position    
raycaster.setFromCamera( mouse, camera );   

// calculate objects intersecting the picking ray
var intersects = raycaster.intersectObjects( scene.children );

//sets the object in the center opacity = 0.2
if(intersects.length > 0) {
    intersects[0].object.material.opacity = 0.2;
}

//sets the opacity of the rest of the objects in scene to opacity = 1.0
for (var i = scene.children.length - 1; i >= 0; i--) {
    var obj = scene.children[i];
    obj.material.opacity = 1.0;

}
 }

【讨论】:

  • 我确实使用 raycaster 获得了有趣的对象数组。但问题是当我尝试改变第 0 位置的对象的不透明度时,整个功能区的不透明度会发生变化。我只想更改正面/中间缩略图的不透明度。
  • 我不太明白你什么时候分开对象。每个缩略图都是使用 ctx.drawImage() 在画布上绘制的不同图像
  • 另外,如果我们采用 Light 方法并将不透明度从 0.7 更改为 1,并结合使用 AmbientLight 和 SpotLight,它仍然不起作用。
  • 如果我使用 raycaster 以某种方式更改不透明度,当色带移动时,我需要更改前一个缩略图的不透明度并更改新缩略图的不透明度.. 不是这样吗贵吗?
  • 那是因为当您将对象放在第零位时,它是整个功能区,而不是单独的图像...将您需要的图像制作成单独的对象,以便您获得该对象而不是整条丝带
猜你喜欢
  • 2023-02-03
  • 2021-12-18
  • 2021-10-02
  • 1970-01-01
  • 2013-05-30
  • 2015-09-28
  • 1970-01-01
  • 2021-03-21
  • 1970-01-01
相关资源
最近更新 更多