three实现三维天空海面正方体粒子透明反射效果代码
代码语言:html
所属分类:三维
代码描述:three实现三维天空海面正方体粒子透明反射效果代码
代码标签: three 三维 天空 海面 正方体 粒子 透明 反射
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<style>
@import url("https://fonts.googleapis.com/css?family=Homenaje");
.p-canvas-webgl {
position: fixed;
z-index: 1;
top: 0;
left: 0;
}
.p-summary {
position: absolute;
top: 20px;
left: 20px;
z-index: 2;
color: #fff;
font-family: "Homenaje", sans-serif;
}
.p-summary h1 {
margin: 0 0 0.2em;
font-size: 42px;
font-weight: 400;
letter-spacing: 0.05em;
}
.p-summary p {
margin: 0;
font-size: 1.1rem;
letter-spacing: 0.1em;
}
.p-summary a {
color: #fff;
}
</style>
</head>
<body >
<div class="p-summary">
<h1>three.js Instancing & SkyBox</h1>
</div>
<canvas class="p-canvas-webgl" id="canvas-webgl"></canvas>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.84.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/gl-matrix-min.js"></script>
<script >
const debounce = (callback, duration) => {
var timer;
return function (event) {
clearTimeout(timer);
timer = setTimeout(function () {
callback(event);
}, duration);
};
};
const MathEx = {
degrees: function (radian) {
return radian / Math.PI * 180;
},
radians: function (degree) {
return degree * Math.PI / 180;
},
clamp: function (value, min, max) {
return Math.min(Math.max(value, min), max);
},
mix: function (x1, x2, a) {
return x1 * (1 - a) + x2 * a;
},
polar: function (radian1, radian2, radius) {
return [
Math.cos(radian1) * Math.cos(radian2) * radius,
Math.sin(radian1) * radius,
Math.cos(radian1) * Math.sin(radian2) * radius];
} };
const force3 = {
updateVelocity: (velocity, acceleration, mass) => {
vec3.scale(acceleration, acceleration, 1 / mass);
vec3.add(velocity, velocity, acceleration);
},
applyFriction: (acceleration, mu, n) => {
const friction = [0, 0, 0];
vec3.scale(friction, acceleration, -1);
const normal = n ? n : 1;
vec3.normalize(friction, friction);
vec3.scale(friction, friction, mu);
vec3.add(acceleration, acceleration, friction);
},
applyDrag: (acceleration, value) => {
const drag = [0, 0, 0];
vec3.scale(drag, acceleration, -1);
vec3.normalize(drag, drag);
vec3.scale(drag, drag, vec3.length(acceleration) * value);
vec3.add(acceleration, acceleration, drag);
},
applyHook: (velocity, acceleration, anchor, rest_length, k) => {
const hook = [0, 0, 0];
vec3.sub(hook, velocity, anchor);
const distance = vec3.length(hook) - rest_length;
vec3.normalize(hook, hook);
vec3.scale(hook, hook, -1 * k * distance);
vec3.add(acceleration, acceleration, hook);
} };
const normalizeVector2 = vector => {
vector.x = vector.x / window.innerWidth * 2 - 1;
vector.y = -(vector.y / window.innerHeight) * 2 + 1;
};
class ForcePerspectiveCamera extends THREE.PerspectiveCamera {
constructor(fov, aspect, near, far) {
super(fov, aspect, near, far);
this.k = 0.02;
this.d = 0.2;
this.velocity = [0, 0, 0];
this.acceleration = [0, 0, 0];
this.anchor = [0, 0, 0];
this.lookK = 0.02;
this.lookD = 0.2;
this.lookVelocity = [0, 0, 0];
this.lookAcceleration = [0, 0, 0];
this.lookAnchor = [0, 0, 0];
}
updatePosition() {
force3.applyHook(this.velocity, this.acceleration, this.anchor, 0, this.k);
force3.applyDrag(this.acceleration, this.d);
force3.updateVelocity(this.velocity, this.acceleration, 1);
}
updateLook() {
force3.applyHook(this.lookVelocity, this.lookAcceleration, this.lookAnchor, 0, this.lookK);
force3.applyDrag(this.lookAcceleration, this.lookD);
force3.updateVelocity(this.lookVelocity, this.lookAcceleration, 1);
}
render() {
this.updatePosition();
this.updateLook();
this.position.set(
this.velocity[0],
this.velocity[1],
this.velocity[2]);
this.lookAt({
x: this.lookVelocity[0],
y: this.lookVelocity[1],
z: this.lookVelocity[2] });
}}
class CameraController {
constructor(camera) {
this.camera = camera;
this.radian1 = 0;
this.radian1Base = 0;
this.radian2 = 0;
this.radian2Base = 0;
this.radius = 2500;
this.isZoom = false;
}
rotate(x, y) {
if (this.isZoom === true) this.isZoom = false;
this.radian1 = MathEx.clamp(this.radian1Base + y, MathEx.radians(-75), MathEx.radians(75));
this.radian2 = this.radian2Base - x * 2;
}
zoom(delta) {
if (!delta) return;
if (this.isZoom === false) this.isZoom = true;
const prevRadius = this.radius;
this.radius -= delta / Math.abs(delta) * 200;
this.radius = MathEx.clamp(this.radius, 700, 8000);
const diff = prevRadius - this.radius;
}
touchEnd() {
this.radian1Base = this.radian1;
this.radian2Base = this.radian2;
}
render() {
this.camera.anchor = MathEx.polar(this.radian1, this.radian2, this.radius);
this.camera.render();
}
computeZoomLength() {
if (this.isZoom) {
return vec3.length(this.camera.acceleration) * 0.05;
} else {
return 0;
}
}
computeAcceleration() {
return vec3.length(this.camera.acceleration) * 0.05;
}}
;
class Debris {
constructor() {
this.uniforms = {
time: {
type: 'f',
value: 0 },
cubeTex: {
type: 't',
value: null } };
this.instances = 1000;
this.obj = null;
}
init(texture) {
this.uniforms.cubeTex.value = texture;
this.obj = this.createObj();
}
createObj() {
const geometry = new THREE.InstancedBufferGeometry();
const baseGeometry = new THREE.BoxBufferGeometry(10, 10, 10);
geometry.addAttribute('position', baseGeometry.attributes.position);
geometry.addAttribute('normal', baseGeometry.attributes.normal);
geometry.setIndex(baseGeometry.index);
const translate = new THREE.InstancedBufferAttribute(new Float32Array(this.instances * 3), 3, 1);
const offsets = new THREE.InstancedBufferAttribute(new Float32Array(this.instances), 1, 1);
const rotates = new THREE.InstancedBufferAttribute(new Float32Array(this.instances * 3), 3, 1);
for (var i = 0, ul = offsets.count; i < ul; i++) {
const polar = MathEx.polar(Math.random() * 2 * Math.PI, Math.random() * 2 * Math.PI, Math.random() * 3000 + 100);
translate.setXYZ(i, polar[0], polar[1], polar[2]);
offsets.setXYZ(i, Math.random() * 100);
rotates.setXYZ(i, Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5);
}
geometry.addAttribute('translate', translate);
geometry.addAttribute('offset', offsets);
geometry.addAttribute('rotate', rotates);
return new THREE.Mesh(
geometry,
new THREE.RawShaderMaterial({
uniforms: this.uniforms,
vertexShader: `attribute vec3 position;
attribute vec3 normal;
attribute vec3 translate;
attribute float offset;
attribute vec3 rotate;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 modelMatrix;
uniform float time;
varying vec3 vPosition;
varying vec3 vNormal;
mat4 computeTranslateMat(vec3 v) {
return mat4(
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
v.x, v.y, v.z, 1.0
);
}
mat4 computeRotateMatX(float radian) {
return mat4(
1.0, 0.0, 0.0, 0.0,
0.0, cos(radian), -sin(radian), 0.0,
.........完整代码请登录后点击上方下载按钮下载查看
网友评论0