簡體   English   中英

webGL中的紋理短

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM