2014-10-16 116 views
0

我有一個short的質感,我想從着色器來閱讀,WebGL的不支持short紋理,所以我分裂短到兩個字節,並將其發送到着色器:短紋理的WebGL

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中上傳支持短紋理的短數據時相比,我的分辨率已經丟失了。任何人都可以看到我做錯了什麼?

enter image description here

這裏是另外一個陌生的不同的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:enter image description here 的WebGL:enter image description here

+1

不應該在着色器中乘以255.0(2^8-1)而不是254.0? – BDL 2014-10-16 11:29:55

+0

甚至* 256 *,因爲'ushortValue = ushortValue >> 8;'除以 – 2014-10-16 11:31:35

+0

我改變了它,謝謝,但仍然是,分辨率仍然不好 – hidayat 2014-10-16 11:41:12

回答

0

我解決同樣的問題,它爲我工作得很好。我的實現是在dart中,但它是相似的。 我有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 。由於紅色字節和grean字節是分開插值的,因此可以在圖像中的高對比度邊緣上繪製不良數據。

結論:兩種解決方案都能正常工作,但都無法用於線性紋理插值。也許可以在片段着色器中執行手動插值。