Skip to content

Commit 9c85a66

Browse files
committed
initial commit
0 parents  commit 9c85a66

14 files changed

+3120
-0
lines changed

OES_texture_float_linear-polyfill.js

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
(function() {
2+
// Uploads a 2x2 floating-point texture where one pixel is 2 and the other
3+
// three pixels are 0. Linear filtering is only supported if a sample taken
4+
// from the center of that texture is (2 + 0 + 0 + 0) / 4 = 0.5.
5+
function supportsOESTextureFloatLinear(gl) {
6+
// Need floating point textures in the first place
7+
if (!gl.getExtension('OES_texture_float')) {
8+
return false;
9+
}
10+
11+
// Create a render target
12+
var framebuffer = gl.createFramebuffer();
13+
var byteTexture = gl.createTexture();
14+
gl.bindTexture(gl.TEXTURE_2D, byteTexture);
15+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
16+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
17+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
18+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
19+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
20+
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
21+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, byteTexture, 0);
22+
23+
// Create a simple floating-point texture with value of 0.5 in the center
24+
var rgba = [
25+
2, 0, 0, 0,
26+
0, 0, 0, 0,
27+
0, 0, 0, 0,
28+
0, 0, 0, 0
29+
];
30+
var floatTexture = gl.createTexture();
31+
gl.bindTexture(gl.TEXTURE_2D, floatTexture);
32+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
33+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
34+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
35+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
36+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.FLOAT, new Float32Array(rgba));
37+
38+
// Create the test shader
39+
var program = gl.createProgram();
40+
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
41+
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
42+
gl.shaderSource(vertexShader, '\
43+
attribute vec2 vertex;\
44+
void main() {\
45+
gl_Position = vec4(vertex, 0.0, 1.0);\
46+
}\
47+
');
48+
gl.shaderSource(fragmentShader, '\
49+
uniform sampler2D texture;\
50+
void main() {\
51+
gl_FragColor = texture2D(texture, vec2(0.5));\
52+
}\
53+
');
54+
gl.compileShader(vertexShader);
55+
gl.compileShader(fragmentShader);
56+
gl.attachShader(program, vertexShader);
57+
gl.attachShader(program, fragmentShader);
58+
gl.linkProgram(program);
59+
60+
// Create a buffer containing a single point
61+
var buffer = gl.createBuffer();
62+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
63+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0]), gl.STREAM_DRAW);
64+
gl.enableVertexAttribArray(0);
65+
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
66+
67+
// Render the point and read back the rendered pixel
68+
var pixel = new Uint8Array(4);
69+
gl.useProgram(program);
70+
gl.viewport(0, 0, 1, 1);
71+
gl.bindTexture(gl.TEXTURE_2D, floatTexture);
72+
gl.drawArrays(gl.POINTS, 0, 1);
73+
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
74+
75+
// The center sample will only have a value of 0.5 if linear filtering works
76+
return pixel[0] === 127 || pixel[0] === 128;
77+
}
78+
79+
// The constructor for the returned extension object
80+
function OESTextureFloatLinear() {
81+
}
82+
83+
// Cache the extension so it's specific to each context like extensions should be
84+
function getOESTextureFloatLinear(gl) {
85+
if (gl.$OES_texture_float_linear$ === void 0) {
86+
Object.defineProperty(gl, '$OES_texture_float_linear$', {
87+
enumerable: false,
88+
configurable: false,
89+
writable: false,
90+
value: new OESTextureFloatLinear()
91+
});
92+
}
93+
return gl.$OES_texture_float_linear$;
94+
}
95+
96+
// This replaces the real getExtension()
97+
function getExtension(name) {
98+
return name === 'OES_texture_float_linear'
99+
? getOESTextureFloatLinear(this)
100+
: oldGetExtension.call(this, name);
101+
}
102+
103+
// This replaces the real getSupportedExtensions()
104+
function getSupportedExtensions() {
105+
var extensions = oldGetSupportedExtensions.call(this);
106+
if (extensions.indexOf('OES_texture_float_linear') === -1) {
107+
extensions.push('OES_texture_float_linear');
108+
}
109+
return extensions;
110+
}
111+
112+
// Get a WebGL context
113+
try {
114+
var gl = document.createElement('canvas').getContext('experimental-webgl');
115+
} catch (e) {
116+
}
117+
118+
// Don't install the polyfill if the browser already supports it or doesn't have WebGL
119+
if (!gl || gl.getSupportedExtensions().indexOf('OES_texture_float_linear') !== -1) {
120+
return;
121+
}
122+
123+
// Install the polyfill if linear filtering works with floating-point textures
124+
if (supportsOESTextureFloatLinear(gl)) {
125+
var oldGetExtension = WebGLRenderingContext.prototype.getExtension;
126+
var oldGetSupportedExtensions = WebGLRenderingContext.prototype.getSupportedExtensions;
127+
WebGLRenderingContext.prototype.getExtension = getExtension;
128+
WebGLRenderingContext.prototype.getSupportedExtensions = getSupportedExtensions;
129+
}
130+
}());

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# WebGL Water Demo
2+
3+
http://madebyevan.com/webgl-water/

cubemap.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* WebGL Water
3+
* http://madebyevan.com/webgl-water/
4+
*
5+
* Copyright 2011 Evan Wallace
6+
* Released under the MIT license
7+
*/
8+
9+
function Cubemap(images) {
10+
this.id = gl.createTexture();
11+
gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.id);
12+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
13+
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
14+
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
15+
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
16+
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
17+
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, images.xneg);
18+
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, images.xpos);
19+
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, images.yneg);
20+
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, images.ypos);
21+
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, images.zneg);
22+
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, images.zpos);
23+
}
24+
25+
Cubemap.prototype.bind = function(unit) {
26+
gl.activeTexture(gl.TEXTURE0 + (unit || 0));
27+
gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.id);
28+
};
29+
30+
Cubemap.prototype.unbind = function(unit) {
31+
gl.activeTexture(gl.TEXTURE0 + (unit || 0));
32+
gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
33+
};

index.html

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<!--
2+
WebGL Water
3+
http://madebyevan.com/webgl-water/
4+
5+
Copyright 2011 Evan Wallace
6+
Released under the MIT license
7+
-->
8+
9+
<!DOCTYPE html>
10+
<html><head>
11+
<title>WebGL Water</title>
12+
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
13+
<script src="OES_texture_float_linear-polyfill.js"></script>
14+
<script src="lightgl.js"></script>
15+
<script src="cubemap.js"></script>
16+
<script src="renderer.js"></script>
17+
<script src="water.js"></script>
18+
<script src="main.js"></script>
19+
<style type="text/css">
20+
body { font: 13px/140% Arial, sans-serif; background: black; color: white; overflow: hidden; }
21+
a { color: inherit; cursor: pointer; }
22+
img { display: none; }
23+
ul { padding: 0 0 0 20px; }
24+
h1 { font: bold italic 30px/30px Georgia; text-align: center; }
25+
h2 { font: bold italic 17px/17px Georgia; padding-top: 10px; }
26+
small { display: block; font-size: 11px; line-height: 15px; }
27+
canvas { position: absolute; top: 0; left: 0; }
28+
#help { position: absolute; top: 0; right: 0; bottom: 0; width: 280px; padding-right: 20px; overflow: auto; }
29+
#loading { position: absolute; left: 0; top: 50%; right: 300px; text-align: center; margin-top: -8px; }
30+
@media (max-width: 600px) {
31+
small { font-size: 8px; line-height: 10px; }
32+
#help { width: 100px; font-size: 10px; line-height: 12px; }
33+
}
34+
</style>
35+
</head><body>
36+
<div id="loading">Loading...</div>
37+
<div id="help">
38+
<h1>WebGL Water</h1>
39+
<p>Made by <a href="http://madebyevan.com/">Evan Wallace</a></p>
40+
<p>This demo requires a decent graphics card and up-to-date drivers. If you can't run the demo, you can still <a href="http://youtube.com/watch?v=R0O_9bp3EKQ">see it on YouTube</a>.</p>
41+
<h2>Interactions:</h2>
42+
<ul>
43+
<li>Draw on the water to make ripples</li>
44+
<li>Drag the background to rotate the camera</li>
45+
<li>Press SPACEBAR to pause and unpause</li>
46+
<li>Drag the sphere to move it around</li>
47+
<li>Press the L key to set the light direction</li>
48+
<li>Press the G key to toggle gravity</li>
49+
</ul>
50+
<h2>Features:</h2>
51+
<ul>
52+
<li>Raytraced reflections and refractions</li>
53+
<li>Analytic ambient occlusion</li>
54+
<li>Heightfield water simulation *</li>
55+
<li>Soft shadows</li>
56+
<li>Caustics **</li>
57+
</ul>
58+
<p><small>* requires the OES_texture_float extension<br>** requires the OES_standard_derivatives extension</small></p>
59+
<p><small>Tile texture from <a href="http://www.flickr.com/photos/zooboing/3682834083/">zooboing</a> on Flickr</small></p>
60+
</div>
61+
<img id="tiles" src="tiles.jpg">
62+
<img id="xneg" src="xneg.jpg">
63+
<img id="xpos" src="xpos.jpg">
64+
<img id="ypos" src="ypos.jpg">
65+
<img id="zneg" src="zneg.jpg">
66+
<img id="zpos" src="zpos.jpg">
67+
<script type="text/javascript"><!--
68+
69+
var _gaq = _gaq || [];
70+
_gaq.push(['_setAccount', 'UA-17521220-1']);
71+
_gaq.push(['_trackPageview']);
72+
73+
(function() {
74+
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
75+
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
76+
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
77+
})();
78+
79+
// --></script>
80+
</body></html>

0 commit comments

Comments
 (0)