webgpu实现逼真三维泳池水流重力触摸交互演示效果代码
代码语言:html
所属分类:三维
代码描述:webgpu实现逼真三维泳池水流重力触摸交互演示效果代码
代码标签: webgpu 逼真 三维 泳池 水流 重力 触摸 交互 演示 效果 代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebGPU Water Simulation</title>
<!-- 引入 lil-gui (用于控制面板) -->
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/lil-gui.umd.min.js"></script>
<style>
body {
margin: 0;
background-color: #000;
color: white;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
overflow: hidden;
touch-action: none; /* 防止移动端滚动 */
}
canvas {
display: block;
width: 100vw;
height: 100vh;
}
#loading {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 24px;
font-weight: bold;
pointer-events: none;
}
#help {
position: absolute;
top: 10px;
left: 10px;
background: rgba(0, 0, 0, 0.8);
padding: 10px;
border-radius: 4px;
max-width: 300px;
line-height: 1.5;
font-size: 14px;
transition: opacity 0.3s;
}
#help.collapsed {
width: 40px;
height: 40px;
overflow: hidden;
padding: 0;
background: transparent;
}
#help.collapsed > div {
display: none;
}
#help-toggle {
cursor: pointer;
font-weight: bold;
user-select: none;
color: #aaa;
position: absolute;
top: 0;
left: 0;
padding: 10px;
}
#help-toggle:hover {
color: white;
}
a { color: #4af; }
</style>
</head>
<body>
<div id="loading">正在加载 WebGPU……</div>
<div id="help">
<div id="help-toggle" class="material-icons"></div>
<div style="margin-top: 25px;">
<p><b>WebGPU 水体演示</b></p>
<p>
<b>鼠标左键 + 拖拽:</b>旋转摄像机<br>
<b>点击水面:</b>产生涟漪<br>
<b>空格键:</b>暂停模拟<br>
<b>G 键:</b>切换重力(作用于球体)<br>
</p>
<p>
球体会与水面互动,生成波浪和焦散效果。
焦散效果通过从水面到池底的光线追踪计算得出。
</p>
</div>
</div>
<canvas></canvas>
<script>
/*
-----------------------------------------------------
MATH LIBRARY (Embedded to ensure compatibility)
This section defines vector/matrix operations used by the engine.
-----------------------------------------------------
*/
(function() {
const i = document.createElement("link").relList;
if (i && i.supports && i.supports("modulepreload"))
return;
for (const b of document.querySelectorAll('link[rel="modulepreload"]'))
y(b);
new MutationObserver(b => {
for (const _ of b)
if (_.type === "childList")
for (const P of _.addedNodes)
P.tagName === "LINK" && P.rel === "modulepreload" && y(P)
}
).observe(document, {
childList: !0,
subtree: !0
});
function x(b) {
const _ = {};
return b.integrity && (_.integrity = b.integrity),
b.referrerPolicy && (_.referrerPolicy = b.referrerPolicy),
b.crossOrigin === "use-credentials" ? _.credentials = "include" : b.crossOrigin === "anonymous" ? _.credentials = "omit" : _.credentials = "same-origin",
_
}
function y(b) {
if (b.ep)
return;
b.ep = !0;
const _ = x(b);
fetch(b.href, _)
}
}
)();
function pe(d, i) {
return class extends d {
constructor(...x) {
super(...x),
i(this)
}
}
}
const ge = pe(Array, d => d.fill(0));
let H = 1e-6;
function we(d) {
function i(g=0, w=0) {
const m = new d(2);
return g !== void 0 && (m[0] = g,
w !== void 0 && (m[1] = w)),
m
}
const x = i;
function y(g, w, m) {
const t = m ?? new d(2);
return t[0] = g,
t[1] = w,
t
}
function b(g, w) {
const m = w ?? new d(2);
return m[0] = Math.ceil(g[0]),
m[1] = Math.ceil(g[1]),
m
}
function _(g, w) {
const m = w ?? new d(2);
return m[0] = Math.floor(g[0]),
m[1] = Math.floor(g[1]),
m
}
function P(g, w) {
const m = w ?? new d(2);
return m[0] = Math.round(g[0]),
m[1] = Math.round(g[1]),
m
}
function T(g, w=0, m=1, t) {
const l = t ?? new d(2);
return l[0] = Math.min(m, Math.max(w, g[0])),
l[1] = Math.min(m, Math.max(w, g[1])),
l
}
function z(g, w, m) {
const t = m ?? new d(2);
return t[0] = g[0] + w[0],
t[1] = g[1] + w[1],
t
}
function q(g, w, m, t) {
const l = t ?? new d(2);
return l[0] = g[0] + w[0] * m,
l[1] = g[1] + w[1] * m,
l
}
function V(g, w) {
const m = g[0]
, t = g[1]
, l = w[0]
, s = w[1]
, r = Math.sqrt(m * m + t * t)
, n = Math.sqrt(l * l + s * s)
, a = r * n
, f = a && xt(g, w) / a;
return Math.acos(f)
}
function L(g, w, m) {
const t = m ?? new d(2);
return t[0] = g[0] - w[0],
t[1] = g[1] - w[1],
t
}
const N = L;
function X(g, w) {
return Math.abs(g[0] - w[0]) < H && Math.abs(g[1] - w[1]) < H
}
function nt(g, w) {
return g[0] === w[0] && g[1] === w[1]
}
function Y(g, w, m, t) {
const l = t ?? new d(2);
return l[0] = g[0] + m * (w[0] - g[0]),
l[1] = g[1] + m * (w[1] - g[1]),
l
}
function ot(g, w, m, t) {
const l = t ?? new d(2);
return l[0] = g[0] + m[0] * (w[0] - g[0]),
l[1] = g[1] + m[1] * (w[1] - g[1]),
l
}
function $(g, w, m) {
const t = m ?? new d(2);
return t[0] = Math.max(g[0], w[0]),
t[1] = Math.max(g[1], w[1]),
t
}
function B(g, w, m) {
const t = m ?? new d(2);
return t[0] = Math.min(g[0], w[0]),
t[1] = Math.min(g[1], w[1]),
t
}
function j(g, w, m) {
const t = m ?? new d(2);
return t[0] = g[0] * w,
t[1] = g[1] * w,
t
}
const st = j;
function at(g, w, m) {
const t = m ?? new d(2);
return t[0] = g[0] / w,
t[1] = g[1] / w,
t
}
function pt(g, w) {
const m = w ?? new d(2);
return m[0] = 1 / g[0],
m[1] = 1 / g[1],
m
}
const gt = pt;
function mt(g, w, m) {
const t = m ?? new d(3)
, l = g[0] * w[1] - g[1] * w[0];
return t[0] = 0,
t[1] = 0,
t[2] = l,
t
}
function xt(g, w) {
return g[0] * w[0] + g[1] * w[1]
}
function lt(g) {
const w = g[0]
, m = g[1];
return Math.sqrt(w * w + m * m)
}
const yt = lt;
function Q(g) {
const w = g[0]
, m = g[1];
return w * w + m * m
}
const Z = Q;
function ut(g, w) {
const m = g[0] - w[0]
, t = g[1] - w[1];
return Math.sqrt(m * m + t * t)
}
const k = ut;
function C(g, w) {
const m = g[0] - w[0]
, t = g[1] - w[1];
return m * m + t * t
}
const W = C;
function rt(g, w) {
const m = w ?? new d(2)
, t = g[0]
, l = g[1]
, s = Math.sqrt(t * t + l * l);
return s > 1e-5 ? (m[0] = t / s,
m[1] = l / s) : (m[0] = 0,
m[1] = 0),
m
}
function Ut(g, w) {
const m = w ?? new d(2);
return m[0] = -g[0],
m[1] = -g[1],
m
}
function J(g, w) {
const m = w ?? new d(2);
return m[0] = g[0],
m[1] = g[1],
m
}
const ct = J;
function vt(g, w, m) {
const t = m ?? new d(2);
return t[0] = g[0] * w[0],
t[1] = g[1] * w[1],
t
}
const Rt = vt;
function it(g, w, m) {
const t = m ?? new d(2);
return t[0] = g[0] / w[0],
t[1] = g[1] / w[1],
t
}
const Mt = it;
function bt(g=1, w) {
const m = w ?? new d(2)
, t = Math.random() * 2 * Math.PI;
return m[0] = Math.cos(t) * g,
m[1] = Math.sin(t) * g,
m
}
function M(g) {
const w = g ?? new d(2);
return w[0] = 0,
w[1] = 0,
w
}
function D(g, w, m) {
const t = m ?? new d(2)
, l = g[0]
, s = g[1];
return t[0] = l * w[0] + s * w[4] + w[12],
t[1] = l * w[1] + s * w[5] + w[13],
t
}
function p(g, w, m) {
const t = m ?? new d(2)
, l = g[0]
, s = g[1];
return t[0] = w[0] * l + w[4] * s + w[8],
t[1] = w[1] * l + w[5] * s + w[9],
t
}
function e(g, w, m, t) {
const l = t ?? new d(2)
, s = g[0] - w[0]
, r = g[1] - w[1]
, n = Math.sin(m)
, a = Math.cos(m);
return l[0] = s * a - r * n + w[0],
l[1] = s * n + r * a + w[1],
l
}
function c(g, w, m) {
const t = m ?? new d(2);
return rt(g, t),
j(t, w, t)
}
function o(g, w, m) {
const t = m ?? new d(2);
return lt(g) > w ? c(g, w, t) : J(g, t)
}
function u(g, w, m) {
const t = m ?? new d(2);
return Y(g, w, .5, t)
}
return {
create: i,
fromValues: x,
set: y,
ceil: b,
floor: _,
round: P,
clamp: T,
add: z,
addScaled: q,
angle: V,
subtract: L,
sub: N,
equalsApproximately: X,
equals: nt,
lerp: Y,
lerpV: ot,
max: $,
min: B,
mulScalar: j,
scale: st,
divScalar: at,
inverse: pt,
invert: gt,
cross: mt,
dot: xt,
length: lt,
len: yt,
lengthSq: Q,
lenSq: Z,
distance: ut,
dist: k,
distanceSq: C,
distSq: W,
normalize: rt,
negate: Ut,
copy: J,
clone: ct,
multiply: vt,
mul: Rt,
divide: it,
div: Mt,
random: bt,
zero: M,
transformMat4: D,
transformMat3: p,
rotate: e,
setLength: c,
truncate: o,
midpoint: u
}
}
const oe = new Map;
function fe(d) {
let i = oe.get(d);
return i || (i = we(d),
oe.set(d, i)),
i
}
function me(d) {
function i(n, a, f) {
const h = new d(3);
return n !== void 0 && (h[0] = n,
a !== void 0 && (h[1] = a,
f !== void 0 && (h[2] = f))),
h
}
const x = i;
function y(n, a, f, h) {
const v = h ?? new d(3);
return v[0] = n,
v[1] = a,
v[2] = f,
v
}
function b(n, a) {
const f = a ?? new d(3);
return f[0] = Math.ceil(n[0]),
f[1] = Math.ceil(n[1]),
f[2] = Math.ceil(n[2]),
f
}
function _(n, a) {
const f = a ?? new d(3);
return f[0] = Math.floor(n[0]),
f[1] = Math.floor(n[1]),
f[2] = Math.floor(n[2]),
f
}
function P(n, a) {
const f = a ?? new d(3);
return f[0] = Math.round(n[0]),
f[1] = Math.round(n[1]),
f[2] = Math.round(n[2]),
f
}
function T(n, a=0, f=1, h) {
const v = h ?? new d(3);
return v[0] = Math.min(f, Math.max(a, n[0])),
v[1] = Math.min(f, Math.max(a, n[1])),
v[2] = Math.min(f, Math.max(a, n[2])),
v
}
function z(n, a, f) {
const h = f ?? new d(3);
return h[0] = n[0] + a[0],
h[1] = n[1] + a[1],
h[2] = n[2] + a[2],
h
}
function q(n, a, f, h) {
const v = h ?? new d(3);
return v[0] = n[0] + a[0] * f,
v[1] = n[1] + a[1] * f,
v[2] = n[2] + a[2] * f,
v
}
function V(n, a) {
const f = n[0]
, h = n[1]
, v = n[2]
, S = a[0]
, A = a[1]
, R = a[2]
, E = Math.sqrt(f * f + h * h + v * v)
, U = Math.sqrt(S * S + A * A + R * R)
, I = E * U
, G = I && xt(n, a) / I;
return Math.acos(G)
}
function L(n, a, f) {
const h = f ?? new d(3);
return h[0] = n[0] - a[0],
h[1] = n[1] - a[1],
h[2] = n[2] - a[2],
h
}
const N = L;
function X(n, a) {
return Math.abs(n[0] - a[0]) < H && Math.abs(n[1] - a[1]) < H && Math.abs(n[2] - a[2]) < H
}
function nt(n, a) {
return n[0] === a[0] && n[1] === a[1] && n[2] === a[2]
}
function Y(n, a, f, h) {
const v = h ?? new d(3);
return v[0] = n[0] + f * (a[0] - n[0]),
v[1] = n[1] + f * (a[1] - n[1]),
v[2] = n[2] + f * (a[2] - n[2]),
v
}
function ot(n, a, f, h) {
const v = h ?? new d(3);
return v[0] = n[0] + f[0] * (a[0] - n[0]),
v[1] = n[1] + f[1] * (a[1] - n[1]),
v[2] = n[2] + f[2] * (a[2] - n[2]),
v
}
function $(n, a, f) {
const h = f ?? new d(3);
return h[0] = Math.max(n[0], a[0]),
h[1] = Math.max(n[1], a[1]),
h[2] = Math.max(n[2], a[2]),
h
}
function B(n, a, f) {
const h = f ?? new d(3);
return h[0] = Math.min(n[0], a[0]),
h[1] = Math.min(n[1], a[1]),
h[2] = Math.min(n[2], a[2]),
h
}
function j(n, a, f) {
const h = f ?? new d(3);
return h[0] = n[0] * a,
h[1] = n[1] * a,
h[2] = n[2] * a,
h
}
const st = j;
function at(n, a, f) {
const h = f ?? new d(3);
return h[0] = n[0] / a,
h[1] = n[1] / a,
h[2] = n[2] / a,
h
}
function pt(n, a) {
const f = a ?? new d(3);
return f[0] = 1 / n[0],
f[1] = 1 / n[1],
f[2] = 1 / n[2],
f
}
const gt = pt;
function mt(n, a, f) {
const h = f ?? new d(3)
, v = n[2] * a[0] - n[0] * a[2]
, S = n[0] * a[1] - n[1] * a[0];
return h[0] = n[1] * a[2] - n[2] * a[1],
h[1] = v,
h[2] = S,
h
}
function xt(n, a) {
return n[0] * a[0] + n[1] * a[1] + n[2] * a[2]
}
function lt(n) {
const a = n[0]
, f = n[1]
, h = n[2];
return Math.sqrt(a * a + f * f + h * h)
}
const yt = lt;
function Q(n) {
const a = n[0]
, f = n[1]
, h = n[2];
return a * a + f * f + h * h
}
const Z = Q;
function ut(n, a) {
.........完整代码请登录后点击上方下载按钮下载查看
















网友评论0