3D 渲染

SpriteJSNext提供了3D扩展,借助它可以加载并渲染3D模型,这样SpriteJS就可以不借助其他框架和库,独立完成3D渲染。

渲染3D模型

SpriteJSNext的3D扩展基于OGL

通过OGL底层,我们可以很方便地渲染出3D模型并与之交互。

  1. const {Scene} = spritejs;
  2. const {Mesh3d, 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. directionalLight: [0.5, 1.0, -0.3, 0.15],
  13. });
  14. layer.camera.attributes.pos = [8, 5, 15];
  15. layer.camera.lookAt([0, 1.5, 0]);
  16. const texture = layer.createTexture('https://p3.ssl.qhimg.com/t01d6c6c93fdddf1e42.jpg');
  17. const program = layer.createProgram({
  18. ...shaders.BASE_TEXTURE,
  19. texture,
  20. });
  21. const model = layer.loadModel('https://s5.ssl.qhres.com/static/1eb3e9b91a296abd.json');
  22. const fox = new Mesh3d(program, {model});
  23. layer.append(fox);
  24. layer.setOrbit();

使用几何图形类

我们也可以很方便地使用几何图形类创建几何元素。

目前支持的元素有:

  • Cube - 立方体
  • Cylinder - 圆柱体
  • Plane - 平面
  • Sphere - 球体
  1. const {Scene} = spritejs;
  2. const {Cylinder, Sphere, Cube, 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. directionalLight: [1, 0, 0, 0.5],
  10. pointLightColor: `hsl(${Math.floor(360 * Math.random())}, 50%, 50%)`,
  11. pointLightPosition: [5, 3, 6],
  12. camera: {
  13. fov: 35,
  14. },
  15. });
  16. layer.camera.attributes.pos = [5, 3, 6];
  17. layer.camera.lookAt([0, 0, 0]);
  18. const program = layer.createProgram({
  19. ...shaders.BASE_GEOMETRY,
  20. cullFace: null,
  21. uniforms: {
  22. lighting: {value: [0.3, 0.8, 0.6, 0.1]},
  23. },
  24. });
  25. const cylinder = new Cylinder(program);
  26. cylinder.attributes.pos = [0, 1.3, 0];
  27. layer.append(cylinder);
  28. cylinder.animate([
  29. {rotateY: 0},
  30. {rotateY: -360},
  31. ], {
  32. duration: 10000,
  33. iterations: Infinity,
  34. });
  35. const sphere = new Sphere(program);
  36. sphere.attr({
  37. phiLength: Math.PI,
  38. });
  39. layer.append(sphere);
  40. sphere.animate([
  41. {rotateY: 0},
  42. {rotateY: -360},
  43. ], {
  44. duration: 7500,
  45. iterations: Infinity,
  46. });
  47. const cube = new Cube(program);
  48. cube.attributes.pos = [0, -1.3, 0];
  49. layer.append(cube);
  50. cube.animate([
  51. {rotateY: 0},
  52. {rotateY: -360},
  53. ], {
  54. duration: 5000,
  55. iterations: Infinity,
  56. });
  57. layer.setRaycast();
  58. layer.addEventListener('click', (evt) => {
  59. if(evt.target === cube) {
  60. const colors = [];
  61. for(let i = 0; i < 3; i++) {
  62. const randomColor = `hsl(${Math.floor(360 * Math.random())}, 50%, 50%)`;
  63. colors.push(randomColor, randomColor);
  64. }
  65. evt.target.attributes.colors = colors;
  66. } else if(evt.target !== layer) {
  67. evt.target.attributes.colors = `hsl(${Math.floor(360 * Math.random())}, 50%, 50%)`;
  68. }
  69. });

试试用鼠标点击这些几何体:

更多内容详见3D扩展