Skip to content

Commit 75b093e

Browse files
committed
add support for OES_texture_float_linear
1 parent 4203a1e commit 75b093e

File tree

2 files changed

+134
-2
lines changed

2 files changed

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

tests/gpulightmap.html

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
-->
1616
<!DOCTYPE html>
1717
<html><body>
18+
<script src="OES_texture_float_linear-polyfill.js"></script>
1819
<script src="../lightgl.js"></script>
1920
<script>
2021

@@ -27,8 +28,8 @@
2728
// avoided by using centroid sampling except it isn't supported by WebGL.
2829
antialias: false
2930
});
30-
if (!gl.getExtension('OES_texture_float')) {
31-
document.write('This demo requires the OES_texture_float extension to run');
31+
if (!gl.getExtension('OES_texture_float') || !gl.getExtension('OES_texture_float_linear')) {
32+
document.write('This demo requires the OES_texture_float and OES_texture_float_linear extensions to run');
3233
throw 'not supported';
3334
}
3435

0 commit comments

Comments
 (0)