three+webgl实现可调节参数的墨水和水模拟鼠标跟随动画效果代码
代码语言:html
所属分类:三维
代码描述:three+webgl实现可调节参数的墨水和水模拟鼠标跟随动画效果代码,通过lil-gui调节参数实现更多酷炫效果。
代码标签: three webgl 调节 参数 墨水 水 模拟 鼠标 跟随 动画
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> @import url(https://fonts.googleapis.com/css?family=Open+Sans:600); .webgl { position: fixed; top: 0; left: 0; right: 0; bottom: 0; outline: none; background-color: #000000; cursor: move; /* fallback if grab cursor is unsupported */ cursor: grabbing; cursor: -moz-grabbing; cursor: -webkit-grabbing; } #credits { position: absolute; width: 100%; margin: auto; bottom: 0; margin-bottom: 20px; font-family: "Open Sans", sans-serif; color: #544027; font-size: 0.7em; text-transform: uppercase; text-align: center; } #credits a { color: #7beeff; } #credits a:hover { color: #ff3434; } </style> </head> <body > <canvas class="webgl"></canvas> <div id="credits"> <p><a href="" target="blank">copyright</a></p> </div> <script type="x-shader/x-vertex" id="floorVertexShader"> varying vec2 vUv; #include <common> #include <shadowmap_pars_vertex> #include <logdepthbuf_pars_vertex> void main() { #include <beginnormal_vertex> #include <defaultnormal_vertex> #include <begin_vertex> vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); #include <logdepthbuf_vertex> #include <worldpos_vertex> #include <shadowmap_vertex> } </script> <script type="x-shader/x-fragment" id="floorFragmentShader"> uniform vec3 color; uniform sampler2D tScratches; varying vec2 vUv; #include <common> #include <packing> #include <lights_pars_begin> #include <shadowmap_pars_fragment> #include <shadowmask_pars_fragment> #include <logdepthbuf_pars_fragment> void main() { #include <logdepthbuf_fragment> vec3 col = color; vec4 scratchesCol = texture2D( tScratches, vUv); float inkValue = max( max(scratchesCol.r, scratchesCol.g), scratchesCol.b); col = mix(col, scratchesCol.rgb, inkValue); col.r = min(col.r, 1.0); col.g = min(col.g, 1.0); col.b = min(col.b, 1.0); col.gb -= (1.0 - getShadowMask() ) * .1; gl_FragColor = vec4(col, 1.0); #include <tonemapping_fragment> #include <colorspace_fragment> } </script> <script type="x-shader/x-vertex" id="simulationVertexShader"> precision highp float; uniform float time; varying vec2 vUv; void main() { vUv = uv; vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0); gl_Position = projectionMatrix * modelViewPosition; } </script> <script type="x-shader/x-fragment" id="simulationFragmentShader"> // fragment shader uniform sampler2D inputTexture; uniform sampler2D noiseTexture; uniform vec2 tipPosOld; uniform vec2 tipPosNew; uniform float speed; uniform float persistence; uniform float thickness; uniform float time; uniform float waterQuantity; uniform float waterDiffusion; uniform float gravity; uniform vec3 inkColor; varying vec2 vUv; float lineSegment(vec2 p, vec2 a, vec2 b, float thickness) { vec2 pa = p - a; vec2 ba = b - a; float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); float idk = length(pa - ba*h); idk = smoothstep(thickness, thickness * .5, idk); return idk; } vec4 blur(sampler2D image, vec2 uv, vec2 resolution, vec2 direction){ vec4 color = vec4(0.0); vec2 off1 = vec2(.013846153846) * direction; vec2 off2 = vec2(.032307692308) * direction; color += texture2D(image, uv) * 0.2270270270; color += texture2D(image, uv + vec2(off1 * resolution)) * 0.3162162162; color += texture2D(image, uv - vec2(off1 * resolution)) * 0.3162162162; color += texture2D(image, uv + vec2(off2 * resolution)) * 0.0702702703; color += texture2D(image, uv - vec2(off2 * resolution)) * 0.0702702703; return color; } void main() { vec4 noise1 = texture2D(noiseTexture, vUv * 4.0 + vec2(time * .1, .0)); vec4 noise2 = texture2D(noiseTexture, vUv * 8.0 + vec2(.0, time * .1) + noise1.rg * .5); vec4 noise3 = texture2D(noiseTexture, vUv * 16.0 + vec2(-time*.05, 0.) + noise2.rg * .5); vec4 noise = (noise1 + noise2 * .5 + noise3 * .25 ) / 1.75; float dirX = (-.5 + noise.g) * noise.r * 10.; float dirY = (-.5 + noise.b) * noise.r * 10.; vec4 oldTexture = texture2D(inputTexture, vUv); float br = 1. - + (oldTexture.r + oldTexture.g + oldTexture.b)/3.0; vec4 col = oldTexture * (1.0 - waterDiffusion); float p2 = (waterDiffusion)/4.0; vec2 stretchUv = vUv * vec2(1.0, 1.0 + gravity); col += blur(inputTexture, stretchUv, vec2(waterQuantity * br), vec2(dirX, dirY) ) * p2; col += blur(inputTexture, stretchUv, vec2(waterQuantity * br), vec2(dirY, dirX) ) * p2; col += blur(inputTexture, stretchUv, vec2(waterQuantity * br), vec2(-dirX, -dirY) ) * p2; col += blur(inputTexture, stretchUv, vec2(waterQuantity * br), vec2(-dirY, -dirX) ) * p2; col.rgb *= persistence; if (speed>0.0){ float lineValue = 0.; float th = clamp( thickness + speed * .3, .0001, .1) ; lineValue = lineSegment(vUv , tipPosOld, tipPosNew, th); col.rgb = mix(col.rgb, inkColor, lineValue); col.rgb = clamp( col.rgb, vec3(0.), vec3(1.)); } gl_FragColor = vec4(col); } </script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.156.js"></script> <script type="module"> import GUI from "//repo.bfw.wiki/bfwrepo/js/lil-gui.esm.js"; document.addEventListener("DOMContentLoaded", () => new App()); class App { constructor() { this.winWidth = window.innerWidth; this.winHeight = window.innerHeight; this.loadTextures(); } loadTextures() { const tl = new THREE.TextureLoader(); tl.load('//repo.bfw.wiki/bfwrepo/image/6114547459a9c.png', texture => { this.noiseTexture = texture; this.noiseTexture.wrapS = THREE.RepeatWrapping; this.noiseTexture.wrapT = THREE.RepeatWrapping; this.setUpScene(); }); } setUpScene() { // Scene this.scene = new THREE.Scene(); this.bgrColor = 0x332e2e; this.inkColor = 0x7beeff; this.fog = new THREE.Fog(this.bgrColor, 13, 20); this.scene.fog = this.fog; this.camera = new THREE.PerspectiveCamera( 60, this.winWidth / this.winHeight, 1, 100); this.camera.position.set(0, 7, 8); this.camera.lookAt(new THREE.Vector3()); this.scene.add(this.camera); // Hero param this.targetHeroUVPos = new THREE.Vector2(0.5, 0.5); this.targetHeroAbsMousePos = new THREE.Vector2(); this.targetHeroRotation = new THREE.Vector2(); this.heroOldUVPos = new THREE.Vector2(0.5, 0.5); this.heroNewUVPos = new THREE.Vector2(0.5, 0.5); this.raycaster = new THREE.Raycaster(); this.mouse = new THREE.Vector2(); this.mouseDown = false; this.thickness = .004; this.pressure = 0; this.persistence = .98; this.gravity = 0.5; // Clock this.clock = new THREE.Clock(); this.time = 0; this.deltaTime = 0; // Core this.createRenderer(); this.createSim(); this.createListeners(); // Environment this.floorSize = 30; this.createHero(); this.createFloor(); this.createLight(); this.createGUI(); // Render loop this.draw(); } createHero() { const geom = new THREE.CylinderGeometry(.05, .2, 1, 16, 1); geom.applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI)); geom.applyMatrix4(new THREE.Matrix4().makeTranslation(0, .5, 0)); const mat = new THREE.MeshStandardMaterial({ color: this.inkColor, roughness: 1 }); this.hero = new THREE.Mesh(geom, mat); this.hero.position.y = .2; this.hero.castShadow = true; this.scene.add(this.hero); } createFloor() { const fragmentShader = document.getElementById('floorFragmentShader').textContent; const vertexShader = document.getElementById('floorVertexShader').textContent; const uniforms = THREE.UniformsUtils.merge([ THREE.UniformsLib['common'], THREE.UniformsLib['shadowmap.........完整代码请登录后点击上方下载按钮下载查看
网友评论0