Threejs系列--11游戏开发--沙漠赛车游戏【初步加载地面】
序言
本章介绍地面的加载。
目录结构
资源目录里面的结构不变,点击传送门快速查看。
|__src
|__assets
|__js
| |__base 基础类文件夹
| |__Camera.js 相机类
| |__geometries 定制的物体类文件夹
| |__materials 材质类文件夹
| |__Floor.js 地面材质 【新增】
| |__passes 合成器通道文件夹
| |__utils 工具类文件夹
| |__Sizes.js 画布大小控制类
| |__EventEmitter.js 基础事件处理器
| |__Time.js 动画刷新
| |__world 精灵类文件夹
| |__index.js 精灵类 【新增--包含所有精灵的加载 控制】
| |__Floor.js 地面类 【新增--处理地面】
| |__Application.js 初始化游戏的文件 【新增了对setWorld的设置,加入场景】
|__index.js 入口
|__index.css 小项目,样式一丢丢
代码一览
新增了两个文件处理地面。
world/index.js代码
import * as THREE from "three";
import Floor from "./Floor.js";
export default class {
constructor(){
this.container = new THREE.Object3D();
this.container.matrixAutoUpdate = false;
//设置地面
this.setFloor();
}
setFloor(){
this.floor = new Floor();
this.container.add(this.floor.container)
}
}
world/Floor.js代码
import * as THREE from "three";
import FloorMaterial from "../materials/Floor.js";
export default class Floor {
constructor(){
this.container = new THREE.Object3D();
this.container.matrixAutoUpdate = false;
this.geometry = new THREE.PlaneBufferGeometry(2, 2, 10, 10);
this.material = new FloorMaterial();
this.mesh = new THREE.Mesh(this.geometry, this.material);
this.mesh.frustumCulled = false; //是否在渲染物体之前,检查每一帧的物体是否在摄像机的视锥体中
this.mesh.matrixAutoUpdate = false; //是否计算每一帧的位移、旋转(四元变换)和缩放矩阵,并重新计算matrixWorld属性
this.container.add(this.mesh);
}
updateMaterial(){
}
}
materials/Floor.js代码
import * as THREE from "three";
export default function () {
const uniforms = {
tBackground: { value: null },
};
const shaderVertex = `
#define GLSLIFY 1
varying vec2 vUv;
void main() {
vUv = uv;
vec3 newPosition = position;
newPosition.z = 1.0;
gl_Position = vec4(newPosition, 1.0);
}
`;
//这里片元着色器内直接上了测试颜色--灰色,方便当下看到效果。没问题后,可以移除gl_FragColor = vec4(0,0,0,0.1),打开上一行的注释。
const shaderFragment = `
#define GLSLIFY 1
uniform sampler2D tBackground;
varying vec2 vUv;
void main() {
vec4 backgroundColor = texture2D(tBackground, vUv);
//gl_FragColor = backgroundColor;
gl_FragColor = vec4(0,0,0,0.1);
}
`;
const material = new THREE.ShaderMaterial({
wireframe: false, //是否将几何体渲染为线框
transparent: false, //定义此材质是否透明
uniforms, //指定要传递给shader代码的uniforms
vertexShader: shaderVertex, //顶点着色器的GLSL代码
fragmentShader: shaderFragment, //片元着色器的GLSL代码
});
return material;
}
Application.js代码
import React from 'react';
...
import World from './world/index';
export default class Application extends React.Component {
componentDidMount(){
...
//设置精灵
this.setWorld();
...
this.test();
}
...
setWorld(){
this.world = new World();
this.scene.add(this.world.container);
}
test(){
this.time.on("tick", () => {
this.renderer.render(this.scene, this.camera.instance)
});
}
...
}
代码解读
world/index.js 是整个游戏中所有精灵的入口,这里将引入其它精灵。
world/Floor.js 是地面的实现,这里创建了一个3d容器,将平面放入。
而地面需要的材质引入了materials/Floor.js。
最终在Application.js中,引入world/index.js,实例化设置即可。
test方法中可以只保留渲染更新,其它都可以移除了。
运行结果
屏幕中被灰色区域占据。