Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
W
WebGL Tutorial
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
최형택
WebGL Tutorial
Commits
b357ae13
Commit
b357ae13
authored
4 years ago
by
Hyung-Taik Choi
Browse files
Options
Downloads
Patches
Plain Diff
Initial commit
parent
54ed78b0
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
5
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
LICENSE
+1
-1
1 addition, 1 deletion
LICENSE
README.md
+1
-17
1 addition, 17 deletions
README.md
gl-matrix.js
+7611
-0
7611 additions, 0 deletions
gl-matrix.js
index.html
+5
-174
5 additions, 174 deletions
index.html
script.js
+57
-97
57 additions, 97 deletions
script.js
with
7675 additions
and
289 deletions
LICENSE
+
1
−
1
View file @
b357ae13
MIT License
MIT License
Copyright (c) 20
17 Pavel Dobryakov
Copyright (c) 20
21 Hyung-Taik Choi
Permission is hereby granted, free of charge, to any person obtaining a copy
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
of this software and associated documentation files (the "Software"), to deal
...
...
This diff is collapsed.
Click to expand it.
README.md
+
1
−
17
View file @
b357ae13
# WebGL Fluid Simulation
# WebGL Fluid Simulation Tutorial
[
Play here
](
https://paveldogreat.github.io/WebGL-Fluid-Simulation/
)
<img
src=
"/screenshot.jpg?raw=true"
width=
"880"
>
## References
http://developer.download.nvidia.com/books/HTML/gpugems/gpugems_ch38.html
https://github.com/mharrys/fluids-2d
https://github.com/haxiomic/GPU-Fluid-Experiments
## License
The code is available under the
[
MIT license
](
LICENSE
)
This diff is collapsed.
Click to expand it.
gl-matrix.js
0 → 100644
+
7611
−
0
View file @
b357ae13
This diff is collapsed.
Click to expand it.
index.html
+
5
−
174
View file @
b357ae13
...
@@ -9,24 +9,12 @@
...
@@ -9,24 +9,12 @@
<meta
name=
"apple-mobile-web-app-capable"
content=
"yes"
>
<meta
name=
"apple-mobile-web-app-capable"
content=
"yes"
>
<meta
name=
"mobile-web-app-capable"
content=
"yes"
>
<meta
name=
"mobile-web-app-capable"
content=
"yes"
>
<link
rel=
"apple-touch-icon"
href=
"logo.png"
>
<link
rel=
"icon"
href=
"logo.png"
>
<title>
WebGL Fluid Simulation
</title>
<title>
WebGL Fluid Simulation
</title>
<meta
name=
"description"
content=
"A WebGL fluid simulation that works in mobile browsers."
>
<meta
name=
"description"
content=
"A WebGL fluid simulation that works in mobile browsers."
>
<meta
property=
"og:type"
content=
"website"
>
<!-- <script type="text/javascript" src="dat.gui.min.js"></script> -->
<meta
property=
"og:title"
content=
"Webgl Fluid Simulation"
>
<meta
property=
"og:description"
content=
"A WebGL fluid simulation that works in mobile browsers."
>
<meta
property=
"og:url"
content=
"https://paveldogreat.github.io/WebGL-Fluid-Simulation/"
>
<meta
property=
"og:image"
content=
"https://paveldogreat.github.io/WebGL-Fluid-Simulation/logo.png"
>
<script
type=
"text/javascript"
src=
"dat.gui.min.js"
></script>
<style>
<style>
@font-face
{
font-family
:
'iconfont'
;
src
:
url
(
'iconfont.ttf'
)
format
(
'truetype'
);
}
*
{
*
{
user-select
:
none
;
user-select
:
none
;
...
@@ -49,176 +37,19 @@
...
@@ -49,176 +37,19 @@
height
:
100%
;
height
:
100%
;
}
}
.dg
{
opacity
:
0.9
;
}
.dg
.property-name
{
overflow
:
visible
;
}
.bigFont
{
font-size
:
150%
;
color
:
#8C8C8C
;
}
.cr.function.appBigFont
{
font-size
:
150%
;
line-height
:
27px
;
color
:
#A5F8D3
;
background-color
:
#023C40
;
}
.cr.function.appBigFont
.property-name
{
float
:
none
;
}
.cr.function.appBigFont
.icon
{
position
:
sticky
;
bottom
:
27px
;
}
.icon
{
font-family
:
'iconfont'
;
font-size
:
130%
;
float
:
right
;
}
.twitter
:before
{
content
:
'a'
;
}
.github
:before
{
content
:
'b'
;
}
.app
:before
{
content
:
'c'
;
}
.discord
:before
{
content
:
'd'
;
}
.promo
{
display
:
none
;
/* display: table; */
position
:
absolute
;
top
:
0
;
left
:
0
;
width
:
100%
;
height
:
100%
;
z-index
:
1
;
overflow
:
auto
;
color
:
lightblue
;
background-color
:
rgba
(
0
,
0
,
0
,
0.4
);
animation
:
promo-appear-animation
0.35s
ease-out
;
}
.promo-middle
{
display
:
table-cell
;
vertical-align
:
middle
;
}
.promo-content
{
width
:
80vw
;
height
:
80vh
;
max-width
:
80vh
;
max-height
:
80vw
;
margin
:
auto
;
padding
:
0
;
font-size
:
2.8vmax
;
font-family
:
Futura
,
"Trebuchet MS"
,
Arial
,
sans-serif
;
text-align
:
center
;
background-image
:
url
(
"promo_back.png"
);
background-position
:
center
;
background-repeat
:
no-repeat
;
background-size
:
cover
;
border-radius
:
15px
;
box-shadow
:
0
4px
8px
0
rgba
(
0
,
0
,
0
,
0.2
),
0
6px
20px
0
rgba
(
0
,
0
,
0
,
0.19
);
}
.promo-header
{
height
:
10%
;
padding
:
2px
16px
;
}
.promo-close
{
width
:
10%
;
height
:
100%
;
text-align
:
left
;
float
:
left
;
font-size
:
1.3em
;
/* transition: 0.2s; */
}
.promo-close
:hover
{
/* transform: scale(1.25); */
cursor
:
pointer
;
}
.promo-body
{
padding
:
8px
16px
16px
16px
;
margin
:
auto
;
}
.promo-body
p
{
margin-top
:
0
;
mix-blend-mode
:
color-dodge
;
}
.link
{
width
:
100%
;
display
:
inline-block
;
}
.link
img
{
width
:
100%
;
}
@keyframes
promo-appear-animation
{
0%
{
transform
:
scale
(
2.0
);
opacity
:
0
;
}
100%
{
transform
:
scale
(
1.0
);
opacity
:
1
;
}
}
</style>
</style>
<script>
<!--
<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', 'UA-105392568-1', 'auto');
ga('create', 'UA-105392568-1', 'auto');
ga('send', 'pageview');
ga('send', 'pageview');
</script>
</script>
<script
async
src=
"https://www.google-analytics.com/analytics.js"
></script>
<script async src="https://www.google-analytics.com/analytics.js"></script>
-->
</head>
</head>
<body>
<body>
<canvas></canvas>
<canvas></canvas>
<!-- Mother of God, pls forgive me -->
<div
class=
"promo"
>
<div
class=
"promo-middle"
>
<div
class=
"promo-content"
>
<div
class=
"promo-header"
>
<span
class=
"promo-close"
>
×
</span>
</div>
<div
class=
"promo-body"
>
<p>
Try Fluid Simulation app!
</p>
<div
class=
"links-container"
>
<a
class=
"link"
id=
"apple_link"
target=
"_blank"
>
<img
class=
"link-img"
alt=
"Download on the App Store"
src=
"app_badge.png"
/>
</a>
<a
class=
"link"
id=
"google_link"
target=
"_blank"
>
<img
class=
"link-img"
alt=
"Get it on Google Play"
src=
"gp_badge.png"
/>
</a>
</div>
</div>
</div>
</div>
</div>
<script
src=
"./script.js"
></script>
<script
src=
"./script.js"
></script>
</body>
</body>
</html>
</html>
\ No newline at end of file
This diff is collapsed.
Click to expand it.
script.js
+
57
−
97
View file @
b357ae13
/*
/*
MIT License
MIT License
Copyright (c) 20
17 Pavel Dobryakov
Copyright (c) 20
21 Hyung-Taik Choi
Permission is hereby granted, free of charge, to any person obtaining a copy
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
of this software and associated documentation files (the "Software"), to deal
...
@@ -26,30 +26,30 @@ SOFTWARE.
...
@@ -26,30 +26,30 @@ SOFTWARE.
// Mobile promo section
// Mobile promo section
const
promoPopup
=
document
.
getElementsByClassName
(
'
promo
'
)[
0
];
//
const promoPopup = document.getElementsByClassName('promo')[0];
const
promoPopupClose
=
document
.
getElementsByClassName
(
'
promo-close
'
)[
0
];
//
const promoPopupClose = document.getElementsByClassName('promo-close')[0];
if
(
isMobile
())
{
//
if (isMobile()) {
setTimeout
(()
=>
{
//
setTimeout(() => {
promoPopup
.
style
.
display
=
'
table
'
;
//
promoPopup.style.display = 'table';
},
20000
);
//
}, 20000);
}
//
}
promoPopupClose
.
addEventListener
(
'
click
'
,
e
=>
{
//
promoPopupClose.addEventListener('click', e => {
promoPopup
.
style
.
display
=
'
none
'
;
//
promoPopup.style.display = 'none';
});
//
});
const
appleLink
=
document
.
getElementById
(
'
apple_link
'
);
//
const appleLink = document.getElementById('apple_link');
appleLink
.
addEventListener
(
'
click
'
,
e
=>
{
//
appleLink.addEventListener('click', e => {
ga
(
'
send
'
,
'
event
'
,
'
link promo
'
,
'
app
'
);
//
ga('send', 'event', 'link promo', 'app');
window
.
open
(
'
https://apps.apple.com/us/app/fluid-simulation/id1443124993
'
);
//
window.open('https://apps.apple.com/us/app/fluid-simulation/id1443124993');
});
//
});
const
googleLink
=
document
.
getElementById
(
'
google_link
'
);
//
const googleLink = document.getElementById('google_link');
googleLink
.
addEventListener
(
'
click
'
,
e
=>
{
//
googleLink.addEventListener('click', e => {
ga
(
'
send
'
,
'
event
'
,
'
link promo
'
,
'
app
'
);
//
ga('send', 'event', 'link promo', 'app');
window
.
open
(
'
https://play.google.com/store/apps/details?id=games.paveldogreat.fluidsimfree
'
);
//
window.open('https://play.google.com/store/apps/details?id=games.paveldogreat.fluidsimfree');
});
//
});
// Simulation section
// Simulation section
...
@@ -113,7 +113,7 @@ if (!ext.supportLinearFiltering) {
...
@@ -113,7 +113,7 @@ if (!ext.supportLinearFiltering) {
config
.
SUNRAYS
=
false
;
config
.
SUNRAYS
=
false
;
}
}
startGUI
();
//
startGUI();
function
getWebGLContext
(
canvas
)
{
function
getWebGLContext
(
canvas
)
{
const
params
=
{
alpha
:
true
,
depth
:
false
,
stencil
:
false
,
antialias
:
false
,
preserveDrawingBuffer
:
false
};
const
params
=
{
alpha
:
true
,
depth
:
false
,
stencil
:
false
,
antialias
:
false
,
preserveDrawingBuffer
:
false
};
...
@@ -153,7 +153,7 @@ function getWebGLContext (canvas) {
...
@@ -153,7 +153,7 @@ function getWebGLContext (canvas) {
formatR
=
getSupportedFormat
(
gl
,
gl
.
RGBA
,
gl
.
RGBA
,
halfFloatTexType
);
formatR
=
getSupportedFormat
(
gl
,
gl
.
RGBA
,
gl
.
RGBA
,
halfFloatTexType
);
}
}
ga
(
'
send
'
,
'
event
'
,
isWebGL2
?
'
webgl2
'
:
'
webgl
'
,
formatRGBA
==
null
?
'
not supported
'
:
'
supported
'
);
//
ga('send', 'event', isWebGL2 ? 'webgl2' : 'webgl', formatRGBA == null ? 'not supported' : 'supported');
return
{
return
{
gl
,
gl
,
...
@@ -205,80 +205,40 @@ function supportRenderTextureFormat (gl, internalFormat, format, type) {
...
@@ -205,80 +205,40 @@ function supportRenderTextureFormat (gl, internalFormat, format, type) {
return
status
==
gl
.
FRAMEBUFFER_COMPLETE
;
return
status
==
gl
.
FRAMEBUFFER_COMPLETE
;
}
}
function
startGUI
()
{
// function startGUI () {
var
gui
=
new
dat
.
GUI
({
width
:
300
});
// var gui = new dat.GUI({ width: 300 });
gui
.
add
(
config
,
'
DYE_RESOLUTION
'
,
{
'
high
'
:
1024
,
'
medium
'
:
512
,
'
low
'
:
256
,
'
very low
'
:
128
}).
name
(
'
quality
'
).
onFinishChange
(
initFramebuffers
);
// gui.add(config, 'DYE_RESOLUTION', { 'high': 1024, 'medium': 512, 'low': 256, 'very low': 128 }).name('quality').onFinishChange(initFramebuffers);
gui
.
add
(
config
,
'
SIM_RESOLUTION
'
,
{
'
32
'
:
32
,
'
64
'
:
64
,
'
128
'
:
128
,
'
256
'
:
256
}).
name
(
'
sim resolution
'
).
onFinishChange
(
initFramebuffers
);
// gui.add(config, 'SIM_RESOLUTION', { '32': 32, '64': 64, '128': 128, '256': 256 }).name('sim resolution').onFinishChange(initFramebuffers);
gui
.
add
(
config
,
'
DENSITY_DISSIPATION
'
,
0
,
4.0
).
name
(
'
density diffusion
'
);
// gui.add(config, 'DENSITY_DISSIPATION', 0, 4.0).name('density diffusion');
gui
.
add
(
config
,
'
VELOCITY_DISSIPATION
'
,
0
,
4.0
).
name
(
'
velocity diffusion
'
);
// gui.add(config, 'VELOCITY_DISSIPATION', 0, 4.0).name('velocity diffusion');
gui
.
add
(
config
,
'
PRESSURE
'
,
0.0
,
1.0
).
name
(
'
pressure
'
);
// gui.add(config, 'PRESSURE', 0.0, 1.0).name('pressure');
gui
.
add
(
config
,
'
CURL
'
,
0
,
50
).
name
(
'
vorticity
'
).
step
(
1
);
// gui.add(config, 'CURL', 0, 50).name('vorticity').step(1);
gui
.
add
(
config
,
'
SPLAT_RADIUS
'
,
0.01
,
1.0
).
name
(
'
splat radius
'
);
// gui.add(config, 'SPLAT_RADIUS', 0.01, 1.0).name('splat radius');
gui
.
add
(
config
,
'
SHADING
'
).
name
(
'
shading
'
).
onFinishChange
(
updateKeywords
);
// gui.add(config, 'SHADING').name('shading').onFinishChange(updateKeywords);
gui
.
add
(
config
,
'
COLORFUL
'
).
name
(
'
colorful
'
);
// gui.add(config, 'COLORFUL').name('colorful');
gui
.
add
(
config
,
'
PAUSED
'
).
name
(
'
paused
'
).
listen
();
// gui.add(config, 'PAUSED').name('paused').listen();
gui
.
add
({
fun
:
()
=>
{
// gui.add({ fun: () => {
splatStack
.
push
(
parseInt
(
Math
.
random
()
*
20
)
+
5
);
// splatStack.push(parseInt(Math.random() * 20) + 5);
}
},
'
fun
'
).
name
(
'
Random splats
'
);
// } }, 'fun').name('Random splats');
let
bloomFolder
=
gui
.
addFolder
(
'
Bloom
'
);
// let bloomFolder = gui.addFolder('Bloom');
bloomFolder
.
add
(
config
,
'
BLOOM
'
).
name
(
'
enabled
'
).
onFinishChange
(
updateKeywords
);
// bloomFolder.add(config, 'BLOOM').name('enabled').onFinishChange(updateKeywords);
bloomFolder
.
add
(
config
,
'
BLOOM_INTENSITY
'
,
0.1
,
2.0
).
name
(
'
intensity
'
);
// bloomFolder.add(config, 'BLOOM_INTENSITY', 0.1, 2.0).name('intensity');
bloomFolder
.
add
(
config
,
'
BLOOM_THRESHOLD
'
,
0.0
,
1.0
).
name
(
'
threshold
'
);
// bloomFolder.add(config, 'BLOOM_THRESHOLD', 0.0, 1.0).name('threshold');
let
sunraysFolder
=
gui
.
addFolder
(
'
Sunrays
'
);
// let sunraysFolder = gui.addFolder('Sunrays');
sunraysFolder
.
add
(
config
,
'
SUNRAYS
'
).
name
(
'
enabled
'
).
onFinishChange
(
updateKeywords
);
// sunraysFolder.add(config, 'SUNRAYS').name('enabled').onFinishChange(updateKeywords);
sunraysFolder
.
add
(
config
,
'
SUNRAYS_WEIGHT
'
,
0.3
,
1.0
).
name
(
'
weight
'
);
// sunraysFolder.add(config, 'SUNRAYS_WEIGHT', 0.3, 1.0).name('weight');
let
captureFolder
=
gui
.
addFolder
(
'
Capture
'
);
// let captureFolder = gui.addFolder('Capture');
captureFolder
.
addColor
(
config
,
'
BACK_COLOR
'
).
name
(
'
background color
'
);
// captureFolder.addColor(config, 'BACK_COLOR').name('background color');
captureFolder
.
add
(
config
,
'
TRANSPARENT
'
).
name
(
'
transparent
'
);
// captureFolder.add(config, 'TRANSPARENT').name('transparent');
captureFolder
.
add
({
fun
:
captureScreenshot
},
'
fun
'
).
name
(
'
take screenshot
'
);
// captureFolder.add({ fun: captureScreenshot }, 'fun').name('take screenshot');
let
github
=
gui
.
add
({
fun
:
()
=>
{
// if (isMobile())
window
.
open
(
'
https://github.com/PavelDoGreat/WebGL-Fluid-Simulation
'
);
// gui.close();
ga
(
'
send
'
,
'
event
'
,
'
link button
'
,
'
github
'
);
// }
}
},
'
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
:
()
=>
{
ga
(
'
send
'
,
'
event
'
,
'
link button
'
,
'
twitter
'
);
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
'
;
let
discord
=
gui
.
add
({
fun
:
()
=>
{
ga
(
'
send
'
,
'
event
'
,
'
link button
'
,
'
discord
'
);
window
.
open
(
'
https://discordapp.com/invite/CeqZDDE
'
);
}
},
'
fun
'
).
name
(
'
Discord
'
);
discord
.
__li
.
className
=
'
cr function bigFont
'
;
discord
.
__li
.
style
.
borderLeft
=
'
3px solid #8C8C8C
'
;
let
discordIcon
=
document
.
createElement
(
'
span
'
);
discord
.
domElement
.
parentElement
.
appendChild
(
discordIcon
);
discordIcon
.
className
=
'
icon discord
'
;
let
app
=
gui
.
add
({
fun
:
()
=>
{
ga
(
'
send
'
,
'
event
'
,
'
link button
'
,
'
app
'
);
window
.
open
(
'
http://onelink.to/5b58bn
'
);
}
},
'
fun
'
).
name
(
'
Check out mobile app
'
);
app
.
__li
.
className
=
'
cr function appBigFont
'
;
app
.
__li
.
style
.
borderLeft
=
'
3px solid #00FF7F
'
;
let
appIcon
=
document
.
createElement
(
'
span
'
);
app
.
domElement
.
parentElement
.
appendChild
(
appIcon
);
appIcon
.
className
=
'
icon app
'
;
if
(
isMobile
())
gui
.
close
();
}
function
isMobile
()
{
function
isMobile
()
{
return
/Mobi|Android/i
.
test
(
navigator
.
userAgent
);
return
/Mobi|Android/i
.
test
(
navigator
.
userAgent
);
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment