threejs+webgl打造一个三维噪点魔法球烟雾动画效果代码
代码语言:html
所属分类:三维
代码描述:threejs+webgl打造一个三维噪点魔法球烟雾动画效果代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link type="text/css" rel="stylesheet" href="//repo.bfw.wiki/bfwrepo/css/aqua-1.5.5.css">
<style>
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
}
:root {
--blue-grad-4: linear-gradient(45deg, #93a5cf 0%, #e4efe9 100%);
}
.bg-blue-grad-4 {
background: var(--blue-grad-4);
}
</style>
</head>
<body >
<div class="relative w-screen h-screen">
<div class="noise-marble w-screen h-screen bg-blue-grad-4"></div>
</div>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.126.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/OrbitControls.126.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/GLTFLoader.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/Stats-16.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/dat.gui-min.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/RGBELoader.js"></script>
<script >
const noiseMarbleVertexTopShader = `
varying vec3 vPosition;
varying vec3 vDirection;
`;
const noiseMarbleVertexMainShader = `
vPosition=position;
vDirection=position-cameraPosition;
`;
const noiseMarbleFragmentTopShader = `
uniform sampler2D uHeightMap;
uniform vec3 uColor1;
uniform vec3 uColor2;
uniform float uDepth;
uniform float uSmooth;
uniform float uTime;
uniform float uSpeed;
uniform sampler2D uDisplacementMap;
uniform float uStrength;
uniform float uSlice;
varying vec3 vPosition;
varying vec3 vDirection;
`;
const noiseMarbleFragmentMainShader = `
float rayMarch(vec3 eye,vec3 ray){
float iter=64.;
float ratio=1./iter;
vec3 p=eye;
float depth=0.;
for(float i=0.;i<iter;i++){
p+=ray*ratio*uDepth;
vec2 uv=equirectUv(normalize(p));
// displacement point
vec2 xOffset=vec2(uTime*uSpeed,0.);
vec3 displacement1=texture2D(uDisplacementMap,uv+xOffset).rgb;
vec2 flipY=vec2(1.,-1.);
vec3 displacement2=texture2D(uDisplacementMap,uv*flipY-xOffset).rgb;
displacement1-=.5;
displacement2-=.5;
vec3 displacement=displacement1+displacement2;
vec3 displaced=p+displacement*uStrength;
uv=equirectUv(normalize(displaced));
float h=texture2D(uHeightMap,uv).r;
float cutoff=1.-i*ratio;
float slice=smoothstep(cutoff,cutoff+uSmooth,h);
float dist=slice*ratio*uSlice;
depth+=dist;
}
return depth;
}
`;
const noiseMarbleFragmentColorShader = `
vec3 ro=vPosition;
vec3 rd=normalize(vDirection);
float depth=rayMarch(ro,rd);
vec3 result=mix(uColor1,uColor2,depth);
vec4 diffuseColor=vec4(result,1.);
`;
const displacementMapUrl = "//repo.bfw.wiki/bfwrepo/image/6114547459a9c.png";
const hdrUrl = "//repo.bfw.wiki/bfwrepo/images/orbita_1k.hdr";
const heightMapUrl = "//repo.bfw.wiki/bfwrepo/image/6114545572f7e.png";
const calcAspect = (el) => el.clientWidth / el.clientHeight;
const getNormalizedMousePos = (e) => {
return {
x: (e.clientX / window.innerWidth) * 2 - 1,
y: -(e.clientY / window.innerHeight) * 2 + 1
};
};
class Base {
constructor(sel, debug = false) {
this.debug = debug;
this.container = document.querySelector(sel);
this.perspectiveCameraParams = {
fov: 75,
near: 0.1,
far: 100
};
this.orthographicCameraParams = {
zoom: 2,
near: -100,
far: 1000
};
this.cameraPosition = new THREE.Vector3(0, 3, 10);
this.lookAtPosition = new THREE.Vector3(0, 0, 0);
this.rendererParams = {
outputEncoding: THREE.LinearEncoding,
config: {
alpha: true,
antialias: true
}
};
this.mousePos = new THREE.Vector2(0, 0);
this.mouseSpeed = 0;
}
// 初始化
init() {
this.createScene();
this.createPerspectiveCamera();
this.createRenderer();
this.createMesh({});
this.createLight();
this.createOrbitControls();
this.addListeners();
this.setLoop();
}
// 创建场景
createScene() {
const scene = new THREE.Scene();
if (this.debug) {
scene.add(new THREE.AxesHelper());
const stats = Stats();
this.container.appendChild(stats.dom);
this.stats = stats;
}
this.scene = scene;
}
// 创建透视相机
createPerspectiveCamera() {
const { perspectiveCameraParams, cameraPosition, lookAtPosition } = this;
const { fov, near, far } = perspectiveCameraParams;
const aspect = calcAspect(this.container);
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.copy(cameraPosition);
camera.lookAt(lookAtPosition);
this.camera = camera;
}
// 创建正交相机
createOrthographicCamera() {
const { orthographicCameraParams, cameraPosition, lookAtPosition } = this;
const { left, right, top, bottom, near, far } = orthographicCameraParams;
const camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far);
camera.position.copy(cameraPosition);
camera.lookAt(lookAtPosition);
this.camera = camera;
}
// 更新正交相机参数
updateOrthographicCameraParams() {
const { container } = this;
const { zoom, near, far } = this.orthographicCameraParams;
const aspect = calcAspect(container);
this.orthographicCameraParams = {
left: -zoom * aspect,
right: zoom * aspect,
top: zoom,
bottom: -zoom,
near,
far,
zoom
};
}
// 创建渲染
createRenderer(useWebGL1 = false) {
var _a;
const { rendererParams } = this;
const { outputEncoding, config } = rendererParams;
const renderer = !useWebGL1
? new THREE.WebGLRenderer(config)
: new THREE.WebGL1Renderer(config);
renderer.setSize(this.container.clientWidth, this.container.clientHeight);
renderer.outputEncoding = outputEncoding;
this.resizeRendererToDisplaySize();
(_a = this.container) === null || _a === void 0 ? void 0 : _a.appendChild(renderer.domElement);
this.renderer = renderer;
this.renderer.setClearColor(0x000000, 0);
}
// 允许投影
enableShadow() {
this.renderer.shadowMap.enabled = true;
}
// 调整渲染器尺寸
resizeRendererToDisplaySize() {
const { renderer } = this;
if (!renderer) {
return;
}
const canvas = renderer.domElement;
const pixelRatio = window.devicePixelRatio;
const { clientWidth, clientHeight } = canvas;
const width = (clientWidth * pixelRatio) | 0;
const height = (clientHeight * pixelRatio) | 0;
.........完整代码请登录后点击上方下载按钮下载查看
网友评论0