如何控制儿童实体阴影?

时间:2018-04-26 02:37:08

标签: aframe

我遇到的问题是我父实体并在父项及其子项(不同的值)上设置某些属性,例如阴影。看起来,object3Dset事件会出现气泡,而子(或任何其他子触发object3dset事件时)的任何内容都会被父项覆盖(因为它会自动将所有子项设置为其值:https://github.com/aframevr/aframe/blob/master/src/components/shadow.js)。是否有一种标准化的方法来处理这种行为?

这是简化的“hello aframe”示例:

<!DOCTYPE html>
<html>
  <head>
    <title>Hello, WebVR! - A-Frame</title>
    <meta name="description" content="Hello, WebVR! - A-Frame">
    <script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script>
  </head>
  <body>
    <a-scene>

      <a-entity light="type:directional; castShadow:true;" position="1 1 1"></a-entity>

      <!-- parent that shadows -->
      <a-entity shadow="cast:true; receive:true">

        <!-- children that avoid shadows -->
        <a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9" shadow="cast:false; receive:false"></a-box>
        <a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E" shadow="cast:false; receive:false"></a-sphere>
        <a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D" shadow="cast:false; receive:false"></a-cylinder>
        <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4" shadow="cast:false; receive:false"></a-plane>
      </a-entity>

      <a-sky color="#ECECEC"></a-sky>
    </a-scene>
  </body>
</html>

阴影:( enter image description here

1 个答案:

答案 0 :(得分:0)

要解决此问题,我必须重新制作阴影组件,以便控制子项是否也受到影响。很想知道是否有更好的方法来做到这一点。

AFRAME.registerComponent('custom-shadow', {
    schema: {
        cast:               {type: 'boolean',    default: true},
        receive:            {type: 'boolean',    default: true},
        applyToChildren:    {type: 'boolean',    default: true}

    },
    multiple: false, //do not allow multiple instances of this component on this entity
    init: function() {
        this.applyShadow();
        this.el.addEventListener('object3dset', this.applyShadow.bind(this));
    },
    applyShadow : function () {
        const data    = this.data;
        const mesh    = this.el.getObject3D('mesh');

        if (!mesh) return;

            mesh.traverse(function (node) {
                node.castShadow     = data.cast;
                node.receiveShadow  = data.receive;

                if (data.applyToChildren) {
                    return;
                }
            });
    },
    update: function (oldData) {
        this.applyShadow.bind(this);
    }
});