阴影

3D扩展提供了绘制阴影的方法:

  1. const {Scene} = spritejs;
  2. const {Camera, Mesh3d, Plane, shaders} = spritejs.ext3d;
  3. const container = document.getElementById('container');
  4. const scene = new Scene({
  5. container,
  6. displayRatio: 2,
  7. });
  8. const layer = scene.layer3d('fglayer', {
  9. camera: {
  10. fov: 35,
  11. },
  12. });
  13. layer.camera.attributes.pos = [5, 4, 10];
  14. layer.setOrbit();
  15. const light = new Camera(layer.gl, {
  16. left: -3,
  17. right: 3,
  18. bottom: -3,
  19. top: 3,
  20. near: 1,
  21. far: 20,
  22. });
  23. light.attributes.pos = [3, 10, 3];
  24. light.lookAt([0, 0, 0]);
  25. const shadow = layer.createShadow({light});
  26. const texture = layer.createTexture('https://p2.ssl.qhimg.com/t01155feb9a795bdd05.jpg');
  27. const model = layer.loadModel('https://s0.ssl.qhres.com/static/0baccc5ad3cd5b8c.json');
  28. const program = layer.createProgram({
  29. ...shaders.TEXTURE_WITH_SHADOW,
  30. cullFace: null,
  31. texture,
  32. });
  33. const plane = new Mesh3d(program, {model});
  34. window.plane = plane;
  35. layer.append(plane);
  36. const waterTexture = layer.createTexture('https://p0.ssl.qhimg.com/t01db936e50ab52f10a.jpg');
  37. const program2 = layer.createProgram({
  38. ...shaders.TEXTURE_WITH_SHADOW,
  39. cullFace: null,
  40. texture: waterTexture,
  41. });
  42. const ground = new Plane(program2, {
  43. rotateX: 90,
  44. scale: 6,
  45. y: -3,
  46. });
  47. layer.append(ground);
  48. shadow.add(plane);
  49. shadow.add(ground);
  50. layer.setShadow(shadow);
  51. layer.tick((t) => {
  52. // A bit of plane animation
  53. if(plane) {
  54. plane.attributes.z = Math.sin(t * 0.001);
  55. plane.attributes.rotateX = Math.sin(t * 0.001 + 2) * 18;
  56. plane.attributes.rotateY = Math.sin(t * 0.001 - 4) * -18;
  57. }
  58. });

我们可以使用正交投影来将阴影投到平面上,具体做法是,通过layer.createShadow创建一个Shadow对象,将设置好的正交相机作为光源传给这个对象,然后把要生成投影的元素添加到这个对象中,再调用layer.setShadow方法绑定这个对象即可。