three实现三维海阔天空全景场景效果代码
代码语言:html
所属分类:三维
代码描述: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 > <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 SkyBox { constructor() { this.uniforms = { time: { type: 'f', value: 0 }, cubeTex: { type: 't', value: null } }; this.obj = null; } init(texture) { this.uniforms.cubeTex.value = texture; this.obj = this.createObj(); } createObj() { return new THREE.Mesh( new THREE.BoxBufferGeometry(30000, 30000, 30000, 1, 1, 1), new THREE.RawShaderMaterial({ uniforms: this.uniforms, vertexShader: `attribute vec3 position; attribute vec3 normal; attribute vec2 uv; uniform mat4 projectionMatrix; uniform mat4 modelViewMatrix; uniform float time; varying vec3 vPosition; void main(void) { vPosition = position; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); }`, fragmentShader: `precision highp float; uniform samplerCube cubeTex; varying vec3 vPosition; void main() { vec3 normal = normalize(vPosition); vec4 color = textureCube(cubeTex, normal); gl_FragColor = color; }`, side: THREE.BackSide })); } render(time) { this.uniforms.time.value += time; }} class PostEffect { constructor(texture) { this.uniforms = { time: { type: 'f', value: 0 }, resolution: { type: 'v2', value: new THREE.Vector2(window.innerWidth, window.innerHeight) }, texture: { type: 't', value: texture }, strengthZoom: { type: 'f', value: 0 }, strengthGlitch: { type: 'f', value: 0 } }; this.obj = this.createObj(); } createObj() { return new THREE.Mesh( new THREE.PlaneBufferGeometry(2, 2), new THREE.RawShaderMaterial({ uniforms: this.uniforms, vertexShader: `attribute vec3 position; attribute vec2 uv; varying vec2 vUv; void main() { vUv = uv; gl_Position = vec4(position, 1.0); }`, fragmentShader: `precision highp float; uniform float time; uniform vec2 resolution; uniform sampler2D texture; uniform float strengthZoom; uniform float strengthGlitch; varying vec2 vUv; float random(vec2 c){ return fract(sin(dot(c.xy ,vec2(12.9898,78.233))) * 43758.5453); } // // GLSL textureless classic 3D noise "cnoise", // with an RSL-style periodic variant "pnoise". // Author: Stefan Gustavson (stefan.gustavson@liu.se) // Version: 2011-10-11 // // Many thanks to Ian McEwan of Ashima Arts for the // ideas for permutation and gradient selection. // // Copyright (c) 2011 Stefan Gustavson. All rights reserved. // Distributed under the MIT license. See LICENSE file. // https://github.com/ashima/webgl-noise // vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); } vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; } vec3 fade(vec3 t) { return t*t*t*(t*(t*6.0-15.0)+10.0); } // Classic Perlin noise float cnoise(vec3 P) { vec3 Pi0 = floor(P); // Integer part for indexing vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1 Pi0 = mod289(Pi0); Pi1 = mod289(Pi1); vec3 Pf0 = fract(P); // Fractional part for interpolation vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0 vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); vec4 iy = vec4(Pi0.yy, Pi1.yy); vec4 iz0 = Pi0.zzzz; vec4 iz.........完整代码请登录后点击上方下载按钮下载查看
网友评论0