This commit is contained in:
Pavel Dobryakov
2017-08-27 18:44:58 +03:00
parent cb6e44f73f
commit ab4ea59816
4 changed files with 100 additions and 17 deletions

BIN
iconfont.ttf Normal file

Binary file not shown.

View File

@@ -1,7 +1,19 @@
<!DOCTYPE html>
<html> <html>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<head> <head>
<meta charset="utf-8">
<title>Fluid Simulation</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta property="og:type" content="website">
<meta property="og:title" content="webgl fluid simulation">
<meta property="og:url" content="https://paveldogreat.github.io/WebGL-Fluid-Simulation/">
<meta property="og:image" content="logo.png">
<script type="text/javascript" src="dat.gui.min.js"></script>
<style> <style>
* {
user-select: none;
}
html, body { html, body {
overflow: hidden; overflow: hidden;
} }
@@ -17,9 +29,48 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.dg {
opacity: 0.9;
}
.dg .property-name {
overflow: visible;
}
@font-face {
font-family: 'iconfont';
src: url('iconfont.ttf') format('truetype');
}
.bigFont {
font-size: 150%;
color: #8C8C8C;
}
.icon {
font-family: 'iconfont';
font-size: 130%;
float: right;
}
.twitter:before {
content: 'a';
}
.github:before {
content: 'b';
}
</style> </style>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-105392568-1', 'auto');
ga('send', 'pageview');
</script>
</head> </head>
<script type="text/javascript" src="dat.gui.min.js"></script>
<body> <body>
<canvas></canvas> <canvas></canvas>
<script src="./script.js"></script> <script src="./script.js"></script>

BIN
logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

View File

@@ -11,6 +11,7 @@ if (!isWebGL2) {
gl = canvas.getContext('webgl', params) || canvas.getContext('experimental-webgl', params); gl = canvas.getContext('webgl', params) || canvas.getContext('experimental-webgl', params);
} }
gl.clearColor(0.0, 0.0, 0.0, 1.0); gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.enable(gl.BLEND);
const halfFloat = gl.getExtension('OES_texture_half_float'); const halfFloat = gl.getExtension('OES_texture_half_float');
let support_linear_float = gl.getExtension('OES_texture_half_float_linear'); let support_linear_float = gl.getExtension('OES_texture_half_float_linear');
@@ -23,20 +24,34 @@ let config = {
TEXTURE_DOWNSAMPLE: 1, TEXTURE_DOWNSAMPLE: 1,
DENSITY_DISSIPATION: 0.98, DENSITY_DISSIPATION: 0.98,
VELOCITY_DISSIPATION: 0.99, VELOCITY_DISSIPATION: 0.99,
SPLAT_RADIUS: 0.005, PRESSURE_CONCENTRATION: 0.8,
CURL: 30,
PRESSURE_ITERATIONS: 25, PRESSURE_ITERATIONS: 25,
CLEAR_PRESSURE: false CURL: 30,
SPLAT_RADIUS: 0.005
} }
var gui = new dat.GUI(); var gui = new dat.GUI({ width: 270 });
gui.add(config, 'TEXTURE_DOWNSAMPLE', { Full: 0, Half: 1, Quarter: 2 }).name('Resolution').onFinishChange(initFramebuffers); gui.add(config, 'TEXTURE_DOWNSAMPLE', { Full: 0, Half: 1, Quarter: 2 }).name('resolution').onFinishChange(initFramebuffers);
gui.add(config, 'DENSITY_DISSIPATION', 0.9, 1.0).name('Density dissipation'); gui.add(config, 'DENSITY_DISSIPATION', 0.9, 1.0).name('density diffusion');
gui.add(config, 'VELOCITY_DISSIPATION', 0.9, 1.0).name('Velocity dissipation'); gui.add(config, 'VELOCITY_DISSIPATION', 0.9, 1.0).name('velocity diffusion');
gui.add(config, 'SPLAT_RADIUS', 0.001, 0.01).name('Splat radius'); gui.add(config, 'PRESSURE_CONCENTRATION', 0.0, 1.0).name('jelly');
gui.add(config, 'CURL', 0, 50).name('Vorticity').step(1); gui.add(config, 'PRESSURE_ITERATIONS', 1, 60).name('iterations');
gui.add(config, 'PRESSURE_ITERATIONS', 1, 60).name('Iterations'); gui.add(config, 'CURL', 0, 50).name('vorticity').step(1);
gui.add(config, 'CLEAR_PRESSURE').name('Clear pressure'); gui.add(config, 'SPLAT_RADIUS', 0.0001, 0.01).name('splat radius');
let github = gui.add({ fun : function () { window.open('https://github.com/PavelDoGreat/WebGL-Fluid-Simulation'); } }, 'fun').name('Github');
github.__li.className = 'cr function bigFont';
github.__li.style.borderLeft = '3px solid #8C8C8C';
let githubIcon = document.createElement('span');
github.domElement.parentElement.appendChild(githubIcon);
githubIcon.className = 'icon github';
let twitter = gui.add({ fun : function () { window.open('https://twitter.com/PavelDoGreat'); } }, 'fun').name('Twitter');
twitter.__li.className = 'cr function bigFont';
twitter.__li.style.borderLeft = '3px solid #8C8C8C';
let twitterIcon = document.createElement('span');
twitter.domElement.parentElement.appendChild(twitterIcon);
twitterIcon.className = 'icon twitter';
class GLProgram { class GLProgram {
constructor (vertexShader, fragmentShader) { constructor (vertexShader, fragmentShader) {
@@ -95,6 +110,19 @@ const baseVertexShader = compileShader(gl.VERTEX_SHADER, `
} }
`); `);
const clearShader = compileShader(gl.FRAGMENT_SHADER, `
precision highp float;
precision mediump sampler2D;
varying vec2 vUv;
uniform sampler2D uTexture;
uniform float value;
void main () {
gl_FragColor = value * texture2D(uTexture, vUv);
}
`);
const displayShader = compileShader(gl.FRAGMENT_SHADER, ` const displayShader = compileShader(gl.FRAGMENT_SHADER, `
precision highp float; precision highp float;
precision mediump sampler2D; precision mediump sampler2D;
@@ -397,6 +425,7 @@ function initFramebuffers () {
initFramebuffers(); initFramebuffers();
const clearProgram = new GLProgram(baseVertexShader, clearShader);
const displayProgram = new GLProgram(baseVertexShader, displayShader); const displayProgram = new GLProgram(baseVertexShader, displayShader);
const splatProgram = new GLProgram(baseVertexShader, splatShader); const splatProgram = new GLProgram(baseVertexShader, splatShader);
const advectionProgram = new GLProgram(baseVertexShader, support_linear_float ? advectionShader : advectionManualFilteringShader); const advectionProgram = new GLProgram(baseVertexShader, support_linear_float ? advectionShader : advectionManualFilteringShader);
@@ -482,9 +511,12 @@ function Update () {
gl.uniform1i(divergenceProgram.uniforms.uVelocity, velocity.first[2]); gl.uniform1i(divergenceProgram.uniforms.uVelocity, velocity.first[2]);
blit(divergence[1]); blit(divergence[1]);
if (config.CLEAR_PRESSURE) { clearProgram.bind();
clear(pressure.first[1]); gl.uniform1i(clearProgram.uniforms.uTexture, pressure.first[2]);
} gl.uniform1f(clearProgram.uniforms.value, config.PRESSURE_CONCENTRATION);
blit(pressure.second[1]);
pressure.swap();
pressureProgram.bind(); pressureProgram.bind();
gl.uniform2f(pressureProgram.uniforms.texelSize, 1.0 / textureWidth, 1.0 / textureHeight); gl.uniform2f(pressureProgram.uniforms.texelSize, 1.0 / textureWidth, 1.0 / textureHeight);
gl.uniform1i(pressureProgram.uniforms.uDivergence, divergence[2]); gl.uniform1i(pressureProgram.uniforms.uDivergence, divergence[2]);
@@ -544,7 +576,7 @@ canvas.addEventListener('mousemove', (e) => {
canvas.addEventListener('touchmove', (e) => { canvas.addEventListener('touchmove', (e) => {
e.preventDefault(); e.preventDefault();
const touches = e.targetTouches; const touches = e.targetTouches;
for (let i = 0; i < e.touches.length; i++) { for (let i = 0; i < touches.length; i++) {
let pointer = pointers[i]; let pointer = pointers[i];
pointer.moved = pointer.down; pointer.moved = pointer.down;
pointer.dx = (touches[i].pageX - pointer.x) * 10.0; pointer.dx = (touches[i].pageX - pointer.x) * 10.0;