2.把地板变成红色

  1 <template>
  2   <div class="badylon-canvas2">
  3     <canvas ref="renderCanvas2" id="render-canvas2"></canvas>
  4   </div>
  5 </template>
  6 
  7 <script setup lang="ts">
  8 import * as BABYLON from "babylonjs";
  9 import type { Engine, Scene } from "babylonjs";
 10 import { ref, onMounted } from "vue";
 11 import { diffusionProfile } from "babylonjs/Shaders/ShadersInclude/diffusionProfile";
 12 
 13 type EngineType = Engine | null;
 14 type SceneType = Scene | null;
 15 
 16 const renderCanvas2 = ref<HTMLCanvasElement | null>(null);
 17 let engine: EngineType = null;
 18 let scene: SceneType = null;
 19 let sceneToRender: SceneType = null;
 20 
 21 // 渲染循环
 22 function startRenderLoop(engine: Engine) {
 23   /**
 24    * runRenderLoop(renderFunction: (() => void)): void
 25    * 注册并执行一个渲染循环。引擎可以有多个渲染函数
 26    * renderFunction: (() => void) --- 定义要持续执行的函数(不停的执行)
 27    */
 28   engine.runRenderLoop(() => {
 29     console.log("runRenderLoop...");
 30     // 如果没有runRenderLoop函数,就无法在移动图像时更新“相机”的数据,简单来说就是图像不会动了。
 31     if (sceneToRender && sceneToRender.activeCamera) {
 32       /**
 33        * render(updateCameras?: boolean, ignoreAnimations?: boolean): void
 34        * updateCameras: 定义一个布尔值,指示摄像机是否必须根据其输入进行更新(默认为true)
 35        *  ignoreAnimations: 定义一个布尔值,指示动画是否不应该执行(默认为false)
 36        */
 37       sceneToRender.render(); // 如果没有这个不会出现图像;渲染scene
 38     }
 39   });
 40 }
 41 
 42 // 创建场景
 43 function createScene() {
 44   if (engine === null) return null;
 45 
 46   /**
 47    * new Scene(engine: Engine, options?: SceneOptions): Scene
 48    * 表示要由引擎渲染的场景。
 49    * engine: Engine --- 定义用于渲染此场景的引擎
 50    * options: 可选; https://doc.babylonjs.com/typedoc/interfaces/BABYLON.SceneOptions
 51    *
 52    */
 53   const scene = new BABYLON.Scene(engine);
 54 
 55   /**
 56    *  这代表了一种自由类型的相机。它可以在第一人称射击游戏中发挥作用。
 57    * 请考虑使用新的万能相机(new UniversalCamera),因为它增加了更多的功能,如手柄。
 58    * new FreeCamera(name: string, position: Vector3, scene?: Scene, setActiveOnSceneIfNoneActive?: boolean): FreeCamera
 59    * name: 在场景中定义摄像机的名称
 60    * position: 定义摄像机在场景中的起始位置
 61    * scene: 定义相机所属的场景
 62    * setActiveOnSceneIfNoneActive: 定义如果未定义其他活动相机,则是否应将该相机标记为活动的
 63    */
 64   const camera = new BABYLON.FreeCamera(
 65     "camera1",
 66     new BABYLON.Vector3(0, 5, -10),
 67     scene
 68   );
 69 
 70   /**
 71    * Vector3.Zero
 72    * 返回一个新的Vector3,设为(0.0,0.0,0.0)
 73    */
 74   camera.setTarget(BABYLON.Vector3.Zero());
 75 
 76   camera.attachControl(renderCanvas2.value, true);
 77 
 78   /**
 79    * new HemisphericLight(name: string, direction: Vector3, scene: Scene): HemisphericLight
 80    * 根据传递的方向(Vector3)在场景中创建一个半球光对象。
 81     半球光模拟周围环境光,所以通过的方向是光的反射方向,而不是入射方向。
 82     半球光不能投射阴影。
 83    */
 84 
 85   /**
 86    * name: 灯光的名字
 87    * direction: 光反射的方向
 88    * scene: 灯光所属的场景
 89    */
 90   const light = new BABYLON.HemisphericLight(
 91     "light",
 92     /**
 93      * new Vector3(x?: number, y?: number, z?: number): Vector3
 94      * 从给定的x, y, z (float)坐标创建一个新的Vector3对象。三维向量
 95      * x: number; 定义第一个坐标(在X轴上)
 96      * y: number
 97      * z: number
 98      */
 99     new BABYLON.Vector3(0, 1, 0),
100     scene
101   );
102 
103   /**
104    * 光的强度。
105     注意:默认情况下它是在框架自己的单元中定义的。
106     注:在PBR材料中,intensityMode可用于选择强度的定义单位。
107    */
108   light.intensity = 0.7;
109 
110   // 创建球
111   /**
112    * MeshBuilder 创建物体,CreateSphere中的sphere是可以替换成其他的
113    * sphere是球体
114    * CreateSphere(name: string, options?: { arc?: number; backUVs?: Vector4; diameter?: number; diameterX?: number; diameterY?: number; diameterZ?: number; frontUVs?: Vector4; segments?: number; sideOrientation?: number; slice?: number; updatable?: boolean }, scene?: Nullable<Scene>): Mesh
115    * CreateShape(name, options, scene);
116    * name: 表示这个物体的名称;
117    * options: 选项;https://doc.cnbabylon.com/4-0-discover-basic-elements/
118    * scene: 表示你加入的场景
119    */
120   // const sphere = BABYLON.MeshBuilder.CreateSphere(
121   //   "sphere",
122   //   {
123   //     diameter: 2,
124   //     segments: 32,
125   //   },
126   //   scene
127   // );
128 
129   /**
130    * sphere.position => Vector
131    * 获取或设置y坐标
132     返回数
133     获取或设置y坐标
134    */
135   // sphere.position.y = 1;
136 
137   // 创建地面
138   /**
139    * Ground: 地面
140   CreateGround(name: string, options?: { height?: number; subdivisions?: number; subdivisionsX?: number; subdivisionsY?: number; updatable?: boolean; width?: number }, scene?: Scene): GroundMesh
141    *
142    * 参数width和height(浮动,默认值1)设置了地面的宽度和高度大小
143     参数subpartitions(正整数)设置每条边的细分数量
144     网格可以设置为可更新的布尔参数updatable(默认为false),如果它的内部几何形状应该在创建后改变
145    *name: 定义网格的名称
146     options: https://doc.babylonjs.com/typedoc/modules/BABYLON#CreateGround-2
147     scene: Scene
148    */
149   const ground = BABYLON.MeshBuilder.CreateGround(
150     "ground",
151     {
152       width: 6,
153       height: 6,
154     },
155     scene
156   );
157 
158   /**
159    * 实例化一个新的标准材质。
160     这是在巴比伦使用的默认材料。这是质量之间最好的权衡和表演。
161    * new StandardMaterial(name: string, scene?: Scene): StandardMaterial
162    * name: 名字
163    * scene: 定义素材所属的场景
164    */
165   const groundMaterial = new BABYLON.StandardMaterial("Ground Material", scene);
166 
167   ground.material = groundMaterial;
168   ground.material.diffuseColor = BABYLON.Color3.Red(); // 让地面背景变色
169   return scene;
170 }
171 
172 function createDefaultEngine() {
173   /**
174    * new Engine(canvas, antialias, options, adaptToDeviceRatio) 创建一个引擎
175    * canvas: 现实容器,可以是Canvas标签...
176    * antialias: boolean, 默认是false,启动后可以防止图像出现“锯齿”
177    * optiosn: 选项,
178    *    adaptToDeviceRatio: false, // 定义是否适应设备的视口特征
179         audioEngine: false, // 定义是否也应该初始化webaudio
180         audioEngineOptions: {}, // 指定音频引擎的选项
181         autoEnableWebVR: false, // 定义是否应该自动启用webvr
182         deterministicLockstep: false, // 定义动画是否应该使用确定性锁定步骤运行
183    *    adaptoToDeviceRatio: boolean,默认false;定义是否适应视口
184         ....
185         https://doc.babylonjs.com/typedoc/interfaces/BABYLON.EngineOptions
186    */
187   return new BABYLON.Engine(renderCanvas2.value, true, {});
188 }
189 
190 async function initFunction() {
191   async function asyncEngineCreation() {
192     try {
193       return createDefaultEngine(); // 先创建容器
194     } catch (e) {
195       console.log(
196         "the available createEngine function failed. Creating the default engine instead"
197       );
198 
199       return createDefaultEngine();
200     }
201   }
202 
203   engine = await asyncEngineCreation(); // 先创建容器
204   if (!engine) throw "engine should not be null.";
205   startRenderLoop(engine); // 如果没有这个不会出现图像
206   scene = createScene(); // 再创建渲染场景
207   // 创建容器 ---> 再创建渲染场景放进容器 ---> 再创建"相机","灯光","球体","地面"放进场景
208   scene && scene.render();
209 }
210 
211 onMounted(() => {
212   if (renderCanvas2.value) {
213     console.log("ttttt");
214     initFunction().then(() => {
215       sceneToRender = scene;
216     });
217 
218     // Resize
219     window.addEventListener("resize", function () {
220       engine && engine.resize();
221     });
222   }
223 });
224 </script>
225 
226 <style lang="scss" scoped>
227 .badylon-canvas2 {
228   width: 100%;
229   height: 100%;
230 
231   #render-canvas2 {
232     width: 100%;
233     height: 100%;
234     // touch-action 用在触摸屏,缩放
235     touch-action: none;
236   }
237 }
238 </style>

 

posted @ 2022-10-17 14:03  sky-su  阅读(34)  评论(0)    收藏  举报