WebAR在透明平面投射阴影(shadow-material)

在A-FRAME要添加阴影,需要有一个实体来接收,但是实体并不透明,因此要让被投影的平面透明需要用到three.js的一些内容.


可以参考glith的一个样例

https://glitch.com/~shadow-material


首先需要引入aframe-orbit-controls.min.js 这个js

灯光和正常添加阴影一样,需要至少一个灯开启castshadow

<script src="https://ar.blowhail.cn/AR_js/aframe-orbit-controls.min.js"></script>

然后写上一个阴影材质的组件

<script>
	AFRAME.registerComponent('shadow-material', {
		init: function(){
			console.log('shadow-material');
			let el = this.el;
			let self = this;
			let mesh = el.getObject3D('mesh');
			console.log(mesh);
			if (!mesh){return;}
			mesh.material = new THREE.ShadowMaterial();
			mesh.material.opacity = 1.0;
		}
	    });
    </script>

在需要设置为透明材质的平面上添加shadow-material这个组件即可

<a-plane id="ground" rotation="-90 0 0" width="20" height="20" shadow="receive: true" shadow-material></a-plane>

最终即可实现这样的效果:

完整的代码:

<script src = "https://ar.blowhail.cn/AR_js/aframe-master.min.js" ></script>
<script src = "https://ar.blowhail.cn/AR_js/aframe-extras.min.js" ></script>
<script src = "https://ar.blowhail.cn/AR_js/xrextras.js" ></script>
<script src="https://ar.blowhail.cn/AR_js/aframe-orbit-controls.min.js"></script>
	<script>
		AFRAME.registerComponent('shadow-material', {
			init: function(){
				console.log('shadow-material');
				let el = this.el;
				let self = this;
				let mesh = el.getObject3D('mesh');
				console.log(mesh);
				if (!mesh){return;}
				mesh.material = new THREE.ShadowMaterial();
				mesh.material.opacity = 1.0;
			

			}
		});
	</script>

<body style="margin : 0px; overflow: hidden;">
  <!-- minimal loader shown until image descriptors are loaded -->
  
  <a-scene
    vr-mode-ui="enabled: false;"
    renderer="colorManagement:true;"
    xrextras-gesture-detector
    xrextras-almost-there
    xrextras-runtime-error
    xrweb

  >
    <a-camera
    id="camera"
    position="0 8 20"
    >
    </a-camera>
  
    <a-entity light="type: directional;
         intensity: 0.8;
         castShadow: true;
         shadowMapHeight:2048;
         shadowMapWidth:2048;
         shadowCameraTop: 10;
         target:#model;"
         position="5.5 5.1 3.2"
         xrextras-attach="target: model; offset: 12 15 3;"
         shadow
         ></a-entity>
    <a-light type="ambient" intensity="0.5"></a-light>
  
    <!-- we use cors proxy to avoid cross-origin problems -->
  
      <a-entity
        id="model"
        gltf-model="fox.gltf"
        scale="0.1 0.1 0.1"
        position="0 0 0"
        rotation="0 0 0"
        animation-mixer="repetitions: Infinity"
        xrextras-hold-drag 
        xrextras-two-finger-rotate
        xrextras-pinch-scale
        shadow
        >
      </a-entity>
    <a-plane id="ground" position="0 0 0" rotation="-90 0 0" width="20" height="20" shadow="receive: true" shadow-material></a-plane>
   
  </a-scene>
</body>