phe*_*cks 7 javascript opengl-es webgl ios
我正在尝试渲染到iOS Safari上的WebGL中的浮点纹理(不是在本机应用程序中).我已经设法让iOS手动(例如从JavaScript)创建浮点纹理,但是当我创建一个浮点类型的帧缓冲区并使用GPU渲染它时,它不起作用.
我已经将问题隔离到渲染到浮点纹理的代码,然后将其传递给另一个要显示的着色器.以下是应用于多维数据集的结果:

纹理渲染绘制绿色正方形,纹理的一半大小,然后应用于立方体的每一侧.
只要绿色方块呈现的纹理类型是标准的无符号字节类型,这在桌面和iOS WebGL上都可以正常工作.但是,将类型更改为浮点会导致iOS设备上的渲染纹理失败(同时继续在桌面浏览器上工作).纹理是空的,就好像没有渲染任何东西一样.
我在这里创建了一个示例项目来演示这个问题:https://github.com/felixpalmer/render-2-texture
使用该THREE.Renderer.precision设置更改着色器的精度没有任何区别
gma*_*man 15
据我所知,iOS设备不支持渲染浮点纹理(此时此时大多数移动设备也不支持)
我对WebGL规范的理解是
OES_texture_float:允许您创建和读取32位浮点纹理,但渲染到浮点是依赖于设备的.
OES_texture_float_linear:允许线性滤镜浮点纹理.如果这不存在OES_texture_float那么你只能gl.NEAREST用于浮点纹理.
OES_texture_half_floatOES_texture_half_float_linear除了半浮动纹理外,它们与上面相同.
在WebGL中可以渲染到浮点纹理的传统方法(假设OES_texture_float存在)是创建一个帧缓冲区,为其附加一个浮点纹理,然后调用gl.checkFramebufferStatus.如果它返回gl.FRAMEBUFFER_COMPLETE那么你可以,如果没有那么你就不能.注意:无论下一段如何,此方法都应该有效.
规范已更新,因此您还可以检查WebGL扩展以查明是否可以渲染到浮点纹理.扩展WEBGL_color_buffer_float应该告诉您可以渲染到浮点纹理.EXT_color_buffer_half_float半浮动纹理的扩展名是相同的.我知道没有浏览器实际显示这些扩展,但如果硬件支持它们,它们支持浮点渲染.
例如我在Chrome 41上的2012 Retina MBP报告
gl = document.createElement("canvas").getContext("webgl").getSupportedExtensions()
["ANGLE_instanced_arrays",
"EXT_blend_minmax",
"EXT_frag_depth",
"EXT_shader_texture_lod",
"EXT_sRGB",
"EXT_texture_filter_anisotropic",
"WEBKIT_EXT_texture_filter_anisotropic",
"OES_element_index_uint",
"OES_standard_derivatives",
"OES_texture_float",
"OES_texture_float_linear",
"OES_texture_half_float",
"OES_texture_half_float_linear",
"OES_vertex_array_object",
"WEBGL_compressed_texture_s3tc",
"WEBKIT_WEBGL_compressed_texture_s3tc",
"WEBGL_debug_renderer_info",
"WEBGL_debug_shaders",
"WEBGL_depth_texture",
"WEBKIT_WEBGL_depth_texture",
"WEBGL_lose_context",
"WEBKIT_WEBGL_lose_context"]
Run Code Online (Sandbox Code Playgroud)
Firefox 36报道
gl = document.createElement("canvas").getContext("webgl").getSupportedExtensions().join("\n")
"ANGLE_instanced_arrays
EXT_blend_minmax
EXT_frag_depth
EXT_sRGB
EXT_texture_filter_anisotropic
OES_element_index_uint
OES_standard_derivatives
OES_texture_float
OES_texture_float_linear
OES_texture_half_float
OES_texture_half_float_linear
OES_vertex_array_object
WEBGL_compressed_texture_s3tc
WEBGL_depth_texture
WEBGL_draw_buffers
WEBGL_lose_context
MOZ_WEBGL_lose_context
MOZ_WEBGL_compressed_texture_s3tc
MOZ_WEBGL_depth_texture"
Run Code Online (Sandbox Code Playgroud)
浏览器供应商正在忙于实现WebGL 2.0,并且鉴于该gl.checkFramebufferStatus方法的工作原理,没有时间花费时间使其他扩展字符串出现.
显然有些iOS设备支持,EXT_color_buffer_half_float所以你可以尝试创建一个半浮动纹理,将它附加到帧缓冲区并检查其状态,然后看看是否有效.
这是检查支持的示例.我在我的iPadAir2和我的iPhone5s上运行它
can make floating point textures
can linear filter floating point textures
can make half floating point textures
can linear filter floating point textures
can **NOT** render to FLOAT texture
successfully rendered to HALF_FLOAT_OES texture
Run Code Online (Sandbox Code Playgroud)
这正是我们的预期.
"use strict";
function log(msg) {
var div = document.createElement("div");
div.appendChild(document.createTextNode(msg));
document.body.appendChild(div);
}
function glEnum(gl, v) {
for (var key in gl) {
if (gl[key] === v) {
return key;
}
}
return "0x" + v.toString(16);
}
window.onload = function() {
// Get A WebGL context
var canvas = document.getElementById("c");
var gl = canvas.getContext("webgl");
if (!gl) {
return;
}
function getExt(name, msg) {
var ext = gl.getExtension(name);
log((ext ? "can " : "can **NOT** ") + msg);
return ext;
}
var testFloat = getExt("OES_texture_float", "make floating point textures");
getExt("OES_texture_float_linear", "linear filter floating point textures");
var testHalfFloat = getExt("OES_texture_half_float", "make half floating point textures");
getExt("OES_texture_half_float_linear", "linear filter half floating point textures");
gl.HALF_FLOAT_OES = 0x8D61;
// setup GLSL program
var program = webglUtils.createProgramFromScripts(gl, ["2d-vertex-shader", "2d-fragment-shader"]);
gl.useProgram(program);
// look up where the vertex data needs to go.
var positionLocation = gl.getAttribLocation(program, "a_position");
var colorLoc = gl.getUniformLocation(program, "u_color");
// provide texture coordinates for the rectangle.
var positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
-1.0, -1.0,
1.0, -1.0,
-1.0, 1.0,
-1.0, 1.0,
1.0, -1.0,
1.0, 1.0]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(positionLocation);
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
var whiteTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, whiteTex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE,
new Uint8Array([255, 255, 255, 255]));
function test(format) {
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, format, null);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
var fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
if (status !== gl.FRAMEBUFFER_COMPLETE) {
log("can **NOT** render to " + glEnum(gl, format) + " texture");
return;
}
// Draw the rectangle.
gl.bindTexture(gl.TEXTURE_2D, whiteTex);
gl.uniform4fv(colorLoc, [0, 10, 20, 1]);
gl.drawArrays(gl.TRIANGLES, 0, 6);
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.clearColor(1, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.uniform4fv(colorLoc, [0, 1/10, 1/20, 1]);
gl.drawArrays(gl.TRIANGLES, 0, 6);
var pixel = new Uint8Array(4);
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
if (pixel[0] !== 0 ||
pixel[1] < 248 ||
pixel[2] < 248 ||
pixel[3] < 254) {
log("FAIL!!!: Was not able to actually render to " + glEnum(gl, format) + " texture");
} else {
log("succesfully rendered to " + glEnum(gl, format) + " texture");
}
}
if (testFloat) {
test(gl.FLOAT);
}
if (testHalfFloat) {
test(gl.HALF_FLOAT_OES);
}
}Run Code Online (Sandbox Code Playgroud)
canvas {
border: 1px solid black;
}Run Code Online (Sandbox Code Playgroud)
<script src="//webglfundamentals.org/webgl/resources/webgl-utils.js"></script>
<canvas id="c" width="16" height="16"></canvas>
<!-- vertex shader -->
<script id="2d-vertex-shader" type="x-shader/x-vertex">
attribute vec4 a_position;
void main() {
gl_Position = a_position;
}
</script>
<!-- fragment shader -->
<script id="2d-fragment-shader" type="x-shader/x-fragment">
precision mediump float;
uniform vec4 u_color;
uniform sampler2D u_texture;
void main() {
gl_FragColor = texture2D(u_texture, vec2(0.5, 0.5)) * u_color;
}
</script>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3513 次 |
| 最近记录: |