webgl实现图片鼠标交互液态扭曲涟漪波纹动画效果代码

代码语言:html

所属分类:动画

代码描述:webgl实现图片鼠标交互液态扭曲涟漪波纹动画效果代码

代码标签: webgl 图片 鼠标 交互 液态 扭曲 涟漪 波纹 动画

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">

  
<style>
body, html {
    margin: 0;
    padding: 0;
}

canvas {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
}

.lil-gui {
    --width: 400px;
    --widget-height: 20px;
    font-size: 15px;
    --input-font-size: 15px;
    --padding: 10px;
    --spacing: 10px;
    --slider-knob-width: 5px;
    --background-color: rgba(5, 0, 15, .9);
    --widget-color: rgba(255, 255, 255, .3);
    --focus-color: rgba(255, 255, 255, .4);
    --hover-color: rgba(255, 255, 255, .5);
    --font-family: monospace;
    z-index: 1;
}
</style>


  
</head>

<body translate="no">

<input id="image-selector-input" style="visibility:hidden;" type="file">

<canvas></canvas>

<script type="x-shader/x-fragment" id="vertShader">
    precision highp float;

    varying vec2 vUv;
    attribute vec2 a_position;

    varying vec2 vL;
    varying vec2 vR;
    varying vec2 vT;
    varying vec2 vB;
    uniform vec2 u_texel;

    void main () {
        vUv = .5 * (a_position + 1.);
        vL = vUv - vec2(u_texel.x, 0.);
        vR = vUv + vec2(u_texel.x, 0.);
        vT = vUv + vec2(0., u_texel.y);
        vB = vUv - vec2(0., u_texel.y);
        gl_Position = vec4(a_position, 0., 1.);
    }
</script>

<script type="x-shader/x-fragment" id="fragShaderAdvection">
    precision highp float;
    precision highp sampler2D;

    varying vec2 vUv;
    uniform sampler2D u_velocity_texture;
    uniform sampler2D u_input_texture;
    uniform vec2 u_texel;
    uniform vec2 u_output_textel;
    uniform float u_dt;
    uniform float u_dissipation;

    vec4 bilerp (sampler2D sam, vec2 uv, vec2 tsize) {
        vec2 st = uv / tsize - 0.5;

        vec2 iuv = floor(st);
        vec2 fuv = fract(st);

        vec4 a = texture2D(sam, (iuv + vec2(0.5, 0.5)) * tsize);
        vec4 b = texture2D(sam, (iuv + vec2(1.5, 0.5)) * tsize);
        vec4 c = texture2D(sam, (iuv + vec2(0.5, 1.5)) * tsize);
        vec4 d = texture2D(sam, (iuv + vec2(1.5, 1.5)) * tsize);

        return mix(mix(a, b, fuv.x), mix(c, d, fuv.x), fuv.y);
    }

    void main () {
        vec2 coord = vUv - u_dt * bilerp(u_velocity_texture, vUv, u_texel).xy * u_texel;
        vec4 velocity = bilerp(u_input_texture, coord, u_output_textel);
        gl_FragColor = u_dissipation * velocity;
    }
</script>

<script type="x-shader/x-fragment" id="fragShaderDivergence">
    precision highp float;
    precision highp sampler2D;

    varying highp vec2 vUv;
    varying highp vec2 vL;
    varying highp vec2 vR;
    varying highp vec2 vT;
    varying highp vec2 vB;
    uniform sampler2D u_velocity_texture;

    void main () {
        float L = texture2D(u_velocity_texture, vL).x;
        float R = texture2D(u_velocity_texture, vR).x;
        float T = texture2D(u_velocity_texture, vT).y;
        float B = texture2D(u_velocity_texture, vB).y;

        float div = .25 * (R - L + T - B);
        gl_FragColor = vec4(div, 0., 0., 1.);
    }
</script>

<script type="x-shader/x-fragment" id="fragShaderPressure">
    precision highp float;
    precision highp sampler2D;

    varying highp vec2 vUv;
    varying highp vec2 vL;
    varying highp vec2 vR;
    varying highp vec2 vT;
    varying highp vec2 vB;
    uniform sampler2D u_pressure_texture;
    uniform sampler2D u_divergence_texture;

    void main () {

        float L = texture2D(u_pressure_texture, vL).x;
        float R = texture2D(u_pressure_texture, vR).x;
        float T = texture2D(u_pressure_texture, vT).x;
        float B = texture2D(u_pressure_texture, vB).x;
        float C = texture2D(u_pressure_texture, vUv).x;
        float divergence = texture2D(u_divergence_texture, vUv).x;
        float pressure = (L + R + B + T - divergence) * .25;

        gl_FragColor = vec4(pressure, 0., 0., 1.);
    }
</script>

<script type="x-shader/x-fragment" id="fragShaderGradientSubtract">
    precision highp float;
    precision highp sampler2D;

    varying highp vec2 vUv;
    varying highp vec2 vL;
    varying highp vec2 vR;
    varying highp vec2 vT;
    varying highp vec2 vB;
    uniform sampler2D u_pressure_texture;
    uniform sampler2D u_velocity_texture;

    void main () {
        float L = texture2D(u_pressure_texture, vL).x;
        float R = texture2D(u_pressure_texture, vR).x;
        float T = texture2D(u_pressure_texture, vT).x;
        float B = texture2D(u_pressure_texture, vB).x;
        vec2 velocity = texture2D(u_velocity_texture, vUv).xy;
        velocity.xy -= vec2(R - L, T - B);
        gl_FragColor = vec4(velocity, 0., 1.);
    }
</script>

<script type="x-shader/x-fragment" id="fragShaderPoint">
    precision highp float;
    precision highp sampler2D;

    varying vec2 vUv;
    uniform sampler2D u_input_texture;
    uniform float u_ratio;
    uniform float u_img_ratio;
    uniform vec3 u_point_value;
    uniform vec2 u_point;
    uniform float u_point_size;

    void main () {
        vec2 p = vUv - u_point.xy;
        p.x *= u_ratio;
        vec3 splat = .6 * pow(2., -dot(p, p) / u_point_size) * u_point_value;

        vec3 base = texture2D(u_input_texture, vUv).xyz;
        gl_FragColor = vec4(base + splat, 1.);
    }
</script>

<script type="x-shader/x-fragment" id="fragShaderOutputShader">
    precision highp float;
    precision highp sampler2D;

    varying vec2 vUv;
    uniform float u_ratio;
    uniform float u_img_ratio;
    uniform float u_disturb_power;
    uniform sampler2D u_output_texture;
    uniform sampler2D u_velocity_texture;
    uniform sampler2D u_text_texture;
    uniform vec2 u_point;

    vec2 get_img_uv() {
        vec2 img_uv = vUv;
        img_uv -= .5;
        if (u_ratio > u_img_ratio) {
            img_uv.x = img_uv.x * u_ratio / u_img_ratio;
        } else {
            img_uv.y = img_uv.y * u_img_ratio / u_ratio;
        }
        float scale_factor = 1.4;
        img_uv *= scale_factor;
        img_uv += .5;

        return img_uv;
    }

    float get_img_frame_alpha(vec2 uv, float img_frame_width) {
        float img_frame_alpha = smoothstep(0., img_frame_width, uv.x) * smoothstep(1., 1. - img_frame_width, uv.x);
        img_frame_alpha *= smoothstep(0., img_frame_width, uv.y) * smoothstep(1., 1. - img_frame_width, uv.y);
        return img_frame_alpha;
    }


    void main () {
        float offset = texture2D(u_output_texture, vUv).r;

        vec2 velocity = texture2D(u_velocity_texture, vUv).xy;
        velocity += .001;
//        velocity = normalize(velocity);

        vec2 img_uv = get_img_uv();
        img_uv -= u_disturb_power * normalize(velocity) * offset;
        img_uv -= u_disturb_power * normalize(velocity) * offset;

        vec3 img = texture2D(u_text_texture, vec2(img_uv.x, 1. - img_uv.y)).rgb;

        float opacity = get_img_frame_alpha(img_uv, .004);
        gl_FragColor = vec4(img, opacity);
    }
</script>
  
      <script type="module">
import GUI from "//repo.bfw.wiki/bfwrepo/js/lil-gui.esm.js";

const canvasEl = document.querySelector("canvas");
const imgInput = document.querySelector("#image-selector-input");

const params = {
  cursorSize: 3,
  cursorPower: 50,
  distortionPower: .5,
  loadMyImage: () => {
    imgInput.click();
  } };


imgInput.onchange = () => {
  const [file] = imgInput.files;
  if (file) {
    const reader = new FileReader();
    reader.onload = e => {
      loadImage(e.target.result);
    };
    reader.readAsDataURL(file);
  }
};

const pointer = {
  x: .65 * window.innerWidth,
  y: .5 * window.innerHeight,
  dx: 0,
  dy: 0,
  moved: false };


const res = {
  w: null,
  h: null };


let outputColor, velocity, divergence, pressure, imageTexture, imgRatio;
let isPreview = false;

const gl = canvasEl.getContext("webgl");
gl.getExtension("OES_texture_float");

const vertexShader = createShader(
document.getElementById("vertShader").innerHTML,
gl.VERTEX_SHADER);

const splatProgram = createProgram("fragShaderPoint");
const divergenceProgram = createProgram("fragShaderDivergence");
const pressureProgram = createProgram("fragShaderPressure");
const gradientSubtractProgram = createProgram("fragShaderGradientSubtract");
const advectionProgram = createProgram("fragShaderAdvection");
const displayProgram = createProgram("fragShaderOutputShader");


resizeCanvas();
initFBOs();
createControls();
setupEvents();
render();

window.addEventListener("resize", () => {
  resizeCanvas();
  initFBOs();
  gl.bindTexture(gl.TEXTURE_2D, imageTexture);
});

loadImage("//repo.bfw.wiki/bfwrepo/image/635f4245169a2.jpeg");


function setupEvents() {
  canvasEl.addEventListener("click", e => {
    isPreview = false;
    updatePointerPosition(e.pageX, e.pageY);
  });

  canvasEl.addEventListener("mousemove", e => {
    isPreview = false;
    updatePointerPosition(e.pageX, e.pageY);
  });

  canvasEl.addEv.........完整代码请登录后点击上方下载按钮下载查看

网友评论0