相关文章推荐
大气的香槟  ·  ORA-01779: ...·  8 月前    · 
文雅的炒饭  ·  jqGrid ...·  1 年前    · 
千杯不醉的红豆  ·  PostgreSQL ...·  1 年前    · 
胡子拉碴的斑马  ·  128-bit ...·  1 年前    · 

WebGL is based on the OpenGL ES 2.0 specification, and retains the semantics of OpenGL ES in order to maximize portability to mobile devices. There are some significant differences in behavior of similar APIs between OpenGL ES 2.0 and the OpenGL API on desktop systems. Many OpenGL programmers are familiar with the semantics on the desktop, and may not know about these differences in behavior. We highlight them here for clarity.

Contents

[ hide ]

Non-Power of Two Texture Support

While OpenGL 2.0 and later for the desktop offer full support for non-power-of-two (NPOT) textures, OpenGL ES 2.0 and WebGL have only limited NPOT support. The restrictions are defined in Sections 3.8.2, "Shader Execution", and 3.7.11, "Mipmap Generation", of the OpenGL ES 2.0 specification , and are summarized here:

  • generateMipmap(target) generates an INVALID_OPERATION error if the level 0 image of the texture currently bound to target has an NPOT width or height.
  • Sampling an NPOT texture in a shader will produce the RGBA color (0, 0, 0, 1) if:
    • The minification filter is set to anything but NEAREST or LINEAR: in other words, if it uses one of the mipmapped filters.
    • The repeat mode is set to anything but CLAMP_TO_EDGE; repeating NPOT textures are not supported.

If your application doesn't require the REPEAT wrap mode, and can tolerate the lack of mipmaps, then you can simply configure the WebGLTexture object appropriately at creation time:

var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

However, if your application requires the REPEAT wrap mode for correctness, you can easily resize the image to the next largest power of two dimensions using DOM APIs. Here is an example of how to do this. image is an HTML image object that has been fully loaded; its onload handler has already been called.

function createTextureFromImage(image) {
    var texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, texture);
    if (!isPowerOfTwo(image.width) || !isPowerOfTwo(image.height)) {
        // Scale up the texture to the next highest power of two dimensions.
        var canvas = document.createElement("canvas");
        canvas.width = nextHighestPowerOfTwo(image.width);
        canvas.height = nextHighestPowerOfTwo(image.height);
        var ctx = canvas.getContext("2d");
        ctx.drawImage(image, 0, 0, image.width, image.height);
        image = canvas;
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
    gl.generateMipmap(gl.TEXTURE_2D);
    gl.bindTexture(gl.TEXTURE_2D, null);
    return texture;
function isPowerOfTwo(x) {
    return (x & (x - 1)) == 0;
function nextHighestPowerOfTwo(x) {
    --x;
    for (var i = 1; i < 32; i <<= 1) {
        x =




    
 x | x >> i;
    return x + 1;
  

If your application allows, you can also resize your source images offline.

Vertex Attribute 0

On desktop GL, vertex attribute 0 has special semantics. First, it must be enabled as an array, or no geometry will be drawn. Second, it does not have persistent state, so calling glGetVertexAttribfv(0, GL_CURRENT_VERTEX_ATTRIB, ...) generates an OpenGL error.

On OpenGL ES 2.0, vertex attribute 0 has no special semantics.

WebGL follows the OpenGL ES 2.0 convention; all vertex attributes behave identically. This requires implementations on desktop GL to perform a certain amount of emulation, but this was considered to be a small price to pay for consistent behavior.

No double-precision floating-point support

OpenGL ES 2.0 does not support the GL_DOUBLE data type, either for vertex attributes or texture data. This means that the Typed Array view type Float64Array is not currently useful in conjunction with the WebGL API.

No 3D Texture support

OpenGL ES 2.0 does not support 3D textures. It is possible to emulate 3D textures with 2D textures.

// tex is a texture with each slice of the cube placed horizontally across the texture.
// texCoord is a 3d texture coord
// size is the size if the cube in pixels.
vec4 sampleAs3DTexture(sampler2D tex, vec3 texCoord, float size) {
   float sliceSize = 1.0 / size;                         // space of 1 slice
   float slicePixelSize = sliceSize / size;              // space of 1 pixel
   float sliceInnerSize = slicePixelSize * (size - 1.0); // space of size pixels
   float zSlice0 = min(floor(texCoord.z * size), size - 1.0);
   float zSlice1 = min(zSlice0 + 1.0, size - 1.0);
   float xOffset = slicePixelSize * 0.5 + texCoord.x * sliceInnerSize;
   float s0 = xOffset + (zSlice0 * sliceSize);
   float s1 = xOffset + (zSlice1 * sliceSize);
   vec4 slice0Color = texture2D(tex, vec2(s0, texCoord.y));
   vec4 slice1Color = texture2D(tex, vec2(s1, texCoord.y));
   float zOffset = mod(texCoord.z * size, 1.0);
   return mix(slice0Color, slice1Color, zOffset);
  

You can see this in use in this sample. There's an explanation of how it works here.

Here's another where each slice is placed in a grid. For example an 8x8x8 cube might be a texture that is 4x2 slices, each slice 8x8 pixels

// tex is a texture with each slice of the cube placed in grid in a texture.
// texCoord is a 3d texture coord
// size is the size if the cube in pixels.
// slicesPerRow is how many slices there are across the texture
// numRows is the number of rows of slices
vec2 computeSliceOffset(float slice, float slicesPerRow, vec2 sliceSize) {
  return sliceSize * vec2(mod(slice, slicesPerRow), 
                          floor(slice / slicesPerRow));
vec4 sampleAs3DTexture(
    sampler2D tex, vec3 texCoord, float size, float numRows, float slicesPerRow) {
  float slice   = texCoord.z * size;
  float sliceZ  = floor(slice);                         // slice we need
  float zOffset = fract(slice);                         // dist between slices
  vec2 sliceSize = vec2(1.0 / slicesPerRow,             // u space of 1 slice
                        1.0 / numRows);                 // v space of 1 slice
  vec2 slice0Offset = computeSliceOffset(sliceZ, slicesPerRow, sliceSize);
  vec2 slice1Offset = computeSliceOffset(sliceZ + 1.0, slicesPerRow, sliceSize);
  vec2 slicePixelSize = sliceSize / size;               // space of 1 pixel
  vec2 sliceInnerSize = slicePixelSize * (size - 1.0);  // space of size pixels
  vec2 uv = slicePixelSize * 0.5 + texCoord.xy * sliceInnerSize;
  vec4 slice0Color = texture2D(tex, slice0Offset + uv);
  vec4 slice1Color = texture2D(tex, slice1Offset + uv);
  return mix(slice0Color, slice1Color, zOffset);
  return slice0Color;
  

See example here

texture2DLod

GLSL texture functions that end in "Lod" (eg texture2DLod) are only permitted in the vertex shader.

Precision Qualifiers

Precision qualifiers for variables in shaders are significant in GLSL ES. In contrast, on desktop systems, the maximum precision is often used even for lower-precision variables. This implies that the effects of precision qualifiers can often only be seen by testing content on mobile devices.

Per the OpenGL ES 2.0 specification, the built-in macro GL_FRAGMENT_PRECISION_HIGH is defined to one on systems supporting highp precision in the fragment language. Developers wishing to use the highest available precision in their fragment shaders are encouraged to write:

#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
  

Otherwise, if the highest precision is not absolutely required, then this unconditional declaration in the fragment shader:

precision mediump float;
  

will achieve the best portability. Testing should still be done on mobile devices to ensure no rendering artifacts are visible because of the use of lower precision than on desktop systems.

Use non-power-of-two (NPOT) textures when appropriate     No performance penalty     Saves memory   无二限制的纹理(Non-Power-of-Two Textures)   OpenGL仅支持分辨率为2mx2n的纹理。但现在我们可以使用“无二限制”的纹理
如果对three.js一无所知的同学可以先看一篇关于three.js的介绍(什么是three.js): https://blog.csdn.net/doupi520/article/details/53907179 photo-sphere-viewer介绍可以直接看官网: https://photo-sphere-viewer.js.org/ doT.js JS模板语言,...
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,1); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D,texture); gl.t.
unity 可以通过修改图片格式来减少包体大小,不同平台对不用格式图片的加载速度,也有差别.在开发WebGl是因为没有开发好的工具,要对图片进行一个处理,自己写了一个脚本工具类,来进行图片适配WebGl端. 最后的效果,用过选择文件夹来处理文件夹下的图片,不用人工一张一张设置了. 先创建一个TextureImportChanging类,继承EditorWindow类. 主要方法:先设置一个设置图片格式的界面, using UnityEngine; using UnityEditor; texture bound to texture unit 0 is not renderable. It maybe non-power-of-2 and have incompatible tex 解决办法:有可能是你加载的图片不是2的方尺寸的图片,然后你又在代码中使用了必须使用2的方尺寸纹理才能做的特效,比如渐进纹理mipmap,还有可能是你的图片还没加载完成,你就开始使用了,这个时候需要等待加载完毕
1. 简介     在PC上开发时,其天空盒的效果很好,但是为Android平台Build之后,其效果简直没法看。     更为恼火的是,之后PC上的纹理效果也变差了,新加入的纹理效果都会变差,看其纹理格式,使用ETC进行了压缩。 2. Unity3D默认纹理格式问题 2.1 在导入时是否自动压缩      Edit->Preferences... 当选择此选项之后,每当导入新的