webgl-3d-animation
Version:
Interactive 3D animation using WebGL showing a 2D predator prey ecology on a grid which is real-time mapped onto the surface of a 3D torus. node.js server side gives access to WAV format files which are rendered using Web Audio API
197 lines (179 loc) • 8.69 kB
HTML
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Event Horizon</title>
<!-- source code at https://github.com/scottstensland/webgl-3d-animation
enjoy Scott Stensland
-->
<script type="text/javascript" src="ui_logic_handler.js"></script>
<script type="text/javascript" src="persistance_handler.js"></script>
<script type="text/javascript" src="common/gl-matrix.1.3.7.js"></script>
<script type="text/javascript" src="common/common.js"></script>
<script type="text/javascript" src="common/vec3.js"></script>
<script type="text/javascript" src="common/webgl-utils.js"></script>
<script type="text/javascript" src="common/Common_Utils.js"></script>
<script type="text/javascript" src="borg.js"></script>
<script type="text/javascript" src="fish_N_sharks.js"></script>
<script type="text/javascript" src="schwartz_surface.js"></script>
<script type="text/javascript" src="chladni.js"></script>
<script type="text/javascript" src="trefoil_knot.js"></script>
<script type="text/javascript" src="audio_display.js"></script>
<script type="text/javascript" src="webaudio_tooling.js"></script>
<script type="text/javascript" src="audio_process.js"></script>
<script type="text/javascript" src="communication_sockets.js"></script>
<script type="text/javascript" src="landscape.js"></script>
<script type="text/javascript" src="render_to_texture.js"></script>
<script id="vertex_shader_render_to_texture" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec2 aTextureCoord;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
varying vec2 vTextureCoord;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vTextureCoord = aTextureCoord;
}
</script>
<script id="fragment_shader_render_to_texture" type="x-shader/x-fragment">
precision mediump float;
varying vec2 vTextureCoord;
uniform sampler2D uSampler;
void main(void) {
gl_FragColor = texture2D(uSampler, vTextureCoord);
}
</script>
<script id="vertex_shader_landscape" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec4 aVertexColor;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform float given_point_size;
varying vec4 vColor;
uniform vec2 u_resolution;
uniform float u_time;
varying float v_time;
void main(void) {
v_time = u_time;
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vColor = aVertexColor;
gl_PointSize = given_point_size;
}
</script>
<script id="fragment_shader_landscape" type="x-shader/x-fragment">
precision mediump float;
varying vec4 vColor;
uniform vec2 resolution;
void main(void) {
vec2 position = (gl_FragCoord.xy / resolution.xy);
gl_FragColor = vColor;
}
</script>
<script id="vertex_shader_01" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec4 aVertexColor;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform float given_point_size;
varying vec4 vColor;
uniform vec2 u_resolution;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vColor = aVertexColor;
gl_PointSize = given_point_size;
}
</script>
<script id="fragment_shader_01" type="x-shader/x-fragment">
precision mediump float;
varying vec4 vColor;
uniform vec2 resolution;
void main(void) {
gl_FragColor = vColor;
}
</script>
<script id="vertex_shader_02" type="x-shader/x-vertex">
precision mediump float;
attribute vec3 aVertexPosition;
varying vec2 position;
void main() {
gl_Position = vec4(aVertexPosition, 1.0);
position = (aVertexPosition.xy + 1.0) * 0.5;
}
</script>
<script id="fragment_shader_02" type="x-shader/x-fragment">
precision mediump float;
varying vec2 position;
uniform vec2 resolution;
float time = 0.5;
float hash(float n) { return fract(sin(n)*93942.234); }
float noise(vec2 p) {
vec2 w = floor(p); vec2 k = fract(p); k = k*k*(3.-2.*k);
float n = w.x + w.y*57.;
float a = hash(n); float b = hash(n+1.);
float c = hash(n+57.); float d = hash(n+58.);
return mix( mix(a, b, k.x), mix(c, d, k.x), k.y);
}
mat2 m = mat2(0.6,0.8,-0.8,0.6);
float fbm(vec2 p) {
float f = 0.;
f += 0.5000*noise(p); p *= 2.02*m;
f += 0.2500*noise(p); p *= 2.01*m;
f += 0.1250*noise(p); p *= 2.03*m;
f += 0.0625*noise(p); f /= 0.9375;
return f;
}
void main() {
vec2 p = vec2(position*6.)*vec2(resolution.x/resolution.y, 1.);
float t = time * .009;
vec2 a = vec2(fbm(p+t*3.), fbm(p-t*3.+8.1));
vec2 b = vec2(fbm(p+t*4. + a*7. + 3.1), fbm(p-t*4. + a*7. + 91.1));
float c = fbm(b*9. + t*20.);
c = smoothstep(0.15,0.98,c);
vec3 col = vec3(c);
col.rb += b*0.17;
gl_FragColor = vec4(col, 1.);
}
</script>
<script type="text/javascript" src="webgl_3d_animation.js"></script>
</head>
<body>
<button id="start-button" style="font-size: 1.5em; padding: 1em; cursor: pointer;">Click to Start Experience</button>
<div id="controls" style="display: none;">
<div>
<label><input type="checkbox" onclick="ui_logic_handler.handleClick('toggle_mute', this);" checked>mute audio</label>
<label><input type="checkbox" onclick="ui_logic_handler.handleClick('animals_audio_vis', this);" checked>audio vis</label>
<label><input type="checkbox" onclick="ui_logic_handler.handleClick('animals_fft', this);" checked>audio fft</label>
<label><input type="checkbox" onclick="ui_logic_handler.handleClick('animals_time_curve', this);" checked>audio time curve</label>
<label><input type="checkbox" onclick="ui_logic_handler.handleClick('animals_borg', this);" checked>borg</label>
<label><input type="checkbox" onclick="ui_logic_handler.handleClick('animals_chladni', this);" checked>chladni</label>
<label><input type="checkbox" onclick="ui_logic_handler.handleClick('animals_pasture', this);" checked>pasture</label>
<label><input type="checkbox" onclick="ui_logic_handler.handleClick('animals_trefoil_knot', this);" checked>trefoil knot</label>
<label><input type="checkbox" onclick="ui_logic_handler.handleClick('animals_schwartz', this);" checked>schwartz</label>
<label><input type="checkbox" onclick="ui_logic_handler.handleClick('animals_fish', this);" checked>fish & sharks</label>
<label><input type="checkbox" onclick="ui_logic_handler.handleClick('animals_doughnut', this);" checked>doughnut</label>
</div>
<p>
<button onclick="webgl_3d_animation.set_camera_perspectives()">reset perspective</button>
</p>
</div>
<ul id="error_output"></ul>
<canvas id="ecology_simulation" style="border: none; display: none;" width="1920" height="1080"></canvas>
<br>
<div id="log_microphone"></div>
<script>
document.getElementById('start-button').addEventListener('click', () => {
// Hide the start button and show the main UI elements
document.getElementById('start-button').style.display = 'none';
document.getElementById('controls').style.display = 'block';
document.getElementById('ecology_simulation').style.display = 'block';
// Call the original startup function. The browser allows the AudioContext
// to start now because this function was triggered by a user click.
if (typeof webgl_3d_animation !== 'undefined' && typeof webgl_3d_animation.internal_webGLStart === 'function') {
webgl_3d_animation.internal_webGLStart();
} else {
console.error("The webgl_3d_animation object or its start function is not available.");
}
}, { once: true }); // {once: true} ensures the event listener is removed after the first click.
</script>
</body>
</html>