[英]Short texture in webGL
我有一个short
的质感,我想从一个着色器阅读,WebGL的不支持short
纹理,所以我分裂短到两个字节,并将其发送到着色器:
var ushortValue = reinterval(i16Value, -32768, 32767, 0, 65535);
textureData[j*4] = ushortValue & 0xFF; // first byte
ushortValue = ushortValue >> 8;
textureData[j*4+1] = ushortValue & 0xFF; // second byte
textureData[j*4+2] = 0;
textureData[j*4+3] = 0;
然后将数据上传到图形卡:
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
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);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, textureData);
在片段着色器中:
vec4 valueInRGBA = texture2D(ctTexture, xy)*255.0; // range 0-1 to 0-255
float real_value = valueInRGBA.r + valueInRGBA.g*256;
real_value = reinterval(real_value , 0.0, 65535.0, 0.0, 1.0);
gl_FragColor = vec4(real_value, real_value, real_value, 1.0);
但是,与在支持短纹理的普通opengl中上传短数据时相比,我失去了分辨率。 谁能看到我在做什么错?
这是我在webgl和opengl之间获得的另一个奇怪的区别,它们具有相同的数据。 我画出上面的值,我得到相同的颜色,但分辨率降低了一点。 然后添加两行:
ct_value = reinterval(ct_value, 0.0, 65535.0, -32768.0, 32767.0);
ct_value = reintervalClamped(ct_value, -275.0, 475.0, 0.0, 1.0);
gl_FragColor = vec4(ct_value,ct_value,ct_value,1.0);
在opengl中,一切看起来都不错,但是在webgl中,所有东西都变成白色,并且代码完全相同。
OpenGL的: WebGL的:
我正在解决同样的问题,对我来说很好。 我的实现是飞镖式的,但是很相似。 我有2种可能的解决方案:
1)使用浮点纹理
gl.getExtension("OES_texture_float")
texture format = GL.LUMINANCE
texture data type = GL.FLOAT
maxValue = (signed)?32767.0:65535.0;
textureData = new Float32List(width*height);
for (int i=0;i<size;i++) {
textureData[i] = data[i]/maxValue;
}
该解决方案效果很好,并且不需要在着色器中执行任何特殊的计算,但是您需要OES_float_linear扩展名才能使用线性纹理插值,并且当前版本的Chrome不支持此功能。
2)使用您的解决方案将短值存储为RGB
pixels = new Uint8List(width*height*3);
for (int i=0;i<width*height;i++) {
int val = (signed)?data[i].abs():data[i];
textureData[i*3] = val&0xFF;
textureData[i*3+1] = val>>8;
textureData[i*3+2] = (signed && data[i]<0)?255:0;
}
着色器中的值重建:
float tval = texture2D(imageTex, vUv).r/256.0+texture2D(imageTex, vUv).g;
if (texture2D(imageTex, vUv).b>0.0) tval = -tval
但是此解决方案有一个大问题,当您放大并启用GL.LINEAR过滤时,它会在图像的高对比度边缘绘制不良数据,因为红色字节和灰色字节是分别插入的。
结论:两种解决方案均有效,但不能与线性纹理插值一起使用。 也许可以在片段着色器中执行手动插值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.