Mein Fragment-Shader kompiliert nicht auf einigen Windows-Maschinen. Es beschwert sich über einen "unbestimmten Logarithmus", den mein Shader nicht enthält.WEBGL-Kompilierungsfehler bei Windows (ANGLE d3d9): unbestimmter Logarithmus
Gibt es etwas anderes ist als ein unbestimmter Logarithmus, die diesen Fehler auslösen könnten?
Live-Demo: http://jsfiddle.net/w1r76rxm/
Mein Fragment-Shader:
"#define GLSLIFY 1
uniform int uTextureSize;
uniform float uWindowCenterWidth[2];
uniform float uRescaleSlopeIntercept[2];
uniform sampler2D uTextureContainer[7];
uniform ivec3 uDataDimensions;
uniform mat4 uWorldToData;
uniform int uNumberOfChannels;
uniform int uPixelType;
uniform int uBitsAllocated;
uniform int uInvert;
// hack because can not pass arrays if too big
// best would be to pass texture but have to deal with 16bits
uniform int uLut;
uniform sampler2D uTextureLUT;
varying vec4 vPos;
// include functions
// unpack int 8
float uInt8(in float r){
return r * 256.;
}
// unpack int 16
float uInt16(in float r, in float a){
return r * 256. + a * 65536.;
}
// unpack int 32
float uInt32(in float r, in float g, in float b, in float a){
return r * 256. + g * 65536. + b * 16777216. + a * 4294967296.;
}
// unpack float 32
float uFloat32(in float r, in float g, in float b, in float a){
// create arrays containing bits for rgba values
// value between 0 and 255
float value = r * 255.;
int bytemeR[8];
bytemeR[0] = int(floor(value/128.));
value -= float(bytemeR[0] * 128);
bytemeR[1] = int(floor(value/64.));
value -= float(bytemeR[1] * 64);
bytemeR[2] = int(floor(value/32.));
value -= float(bytemeR[2] * 32);
bytemeR[3] = int(floor(value/16.));
value -= float(bytemeR[3] * 16);
bytemeR[4] = int(floor(value/8.));
value -= float(bytemeR[4] * 8);
bytemeR[5] = int(floor(value/4.));
value -= float(bytemeR[5] * 4);
bytemeR[6] = int(floor(value/2.));
value -= float(bytemeR[6] * 2);
bytemeR[7] = int(floor(value));
value = g * 255.;
int bytemeG[8];
bytemeG[0] = int(floor(value/128.));
value -= float(bytemeG[0] * 128);
bytemeG[1] = int(floor(value/64.));
value -= float(bytemeG[1] * 64);
bytemeG[2] = int(floor(value/32.));
value -= float(bytemeG[2] * 32);
bytemeG[3] = int(floor(value/16.));
value -= float(bytemeG[3] * 16);
bytemeG[4] = int(floor(value/8.));
value -= float(bytemeG[4] * 8);
bytemeG[5] = int(floor(value/4.));
value -= float(bytemeG[5] * 4);
bytemeG[6] = int(floor(value/2.));
value -= float(bytemeG[6] * 2);
bytemeG[7] = int(floor(value));
value = b * 255.;
int bytemeB[8];
bytemeB[0] = int(floor(value/128.));
value -= float(bytemeB[0] * 128);
bytemeB[1] = int(floor(value/64.));
value -= float(bytemeB[1] * 64);
bytemeB[2] = int(floor(value/32.));
value -= float(bytemeB[2] * 32);
bytemeB[3] = int(floor(value/16.));
value -= float(bytemeB[3] * 16);
bytemeB[4] = int(floor(value/8.));
value -= float(bytemeB[4] * 8);
bytemeB[5] = int(floor(value/4.));
value -= float(bytemeB[5] * 4);
bytemeB[6] = int(floor(value/2.));
value -= float(bytemeB[6] * 2);
bytemeB[7] = int(floor(value));
value = a * 255.;
int bytemeA[8];
bytemeA[0] = int(floor(value/128.));
value -= float(bytemeA[0] * 128);
bytemeA[1] = int(floor(value/64.));
value -= float(bytemeA[1] * 64);
bytemeA[2] = int(floor(value/32.));
value -= float(bytemeA[2] * 32);
bytemeA[3] = int(floor(value/16.));
value -= float(bytemeA[3] * 16);
bytemeA[4] = int(floor(value/8.));
value -= float(bytemeA[4] * 8);
bytemeA[5] = int(floor(value/4.));
value -= float(bytemeA[5] * 4);
bytemeA[6] = int(floor(value/2.));
value -= float(bytemeA[6] * 2);
bytemeA[7] = int(floor(value));
// compute float32 value from bit arrays
// sign
int issigned = int(pow(-1., float(bytemeR[0])));
// exponent
int exponent = 0;
exponent += bytemeR[1] * int(pow(2., 7.));
exponent += bytemeR[2] * int(pow(2., 6.));
exponent += bytemeR[3] * int(pow(2., 5.));
exponent += bytemeR[4] * int(pow(2., 4.));
exponent += bytemeR[5] * int(pow(2., 3.));
exponent += bytemeR[6] * int(pow(2., 2.));
exponent += bytemeR[7] * int(pow(2., 1.));
exponent += bytemeG[0];
// fraction
float fraction = 0.;
fraction = float(bytemeG[1]) * pow(2., -1.);
fraction += float(bytemeG[2]) * pow(2., -2.);
fraction += float(bytemeG[3]) * pow(2., -3.);
fraction += float(bytemeG[4]) * pow(2., -4.);
fraction += float(bytemeG[5]) * pow(2., -5.);
fraction += float(bytemeG[6]) * pow(2., -6.);
fraction += float(bytemeG[7]) * pow(2., -7.);
fraction += float(bytemeB[0]) * pow(2., -8.);
fraction += float(bytemeB[1]) * pow(2., -9.);
fraction += float(bytemeB[2]) * pow(2., -10.);
fraction += float(bytemeB[3]) * pow(2., -11.);
fraction += float(bytemeB[4]) * pow(2., -12.);
fraction += float(bytemeB[5]) * pow(2., -13.);
fraction += float(bytemeB[6]) * pow(2., -14.);
fraction += float(bytemeB[7]) * pow(2., -15.);
fraction += float(bytemeA[0]) * pow(2., -16.);
fraction += float(bytemeA[1]) * pow(2., -17.);
fraction += float(bytemeA[2]) * pow(2., -18.);
fraction += float(bytemeA[3]) * pow(2., -19.);
fraction += float(bytemeA[4]) * pow(2., -20.);
fraction += float(bytemeA[5]) * pow(2., -21.);
fraction += float(bytemeA[6]) * pow(2., -22.);
fraction += float(bytemeA[7]) * pow(2., -23.);
return float(issigned) * pow(2., float(exponent - 127)) * (1. + fraction);
}
// entry point for the unpack function
vec4 unpack(vec4 packedRGBA,
int bitsAllocated,
int signedNumber,
int numberOfChannels,
int pixelType) {
// always return a vec4
vec4 unpacked = vec4(0, 0, 0, 0);
if(numberOfChannels == 1){
if(bitsAllocated == 8 || bitsAllocated == 1){
unpacked.x = uInt8(
packedRGBA.r);
}
else if(bitsAllocated == 16){
unpacked.x = uInt16(
packedRGBA.r,
packedRGBA.a);
}
else if(bitsAllocated == 32){
if(pixelType == 0){
unpacked.x = uInt32(
packedRGBA.r,
packedRGBA.g,
packedRGBA.b,
packedRGBA.a);
}
else{
unpacked.x = uFloat32(
packedRGBA.r,
packedRGBA.g,
packedRGBA.b,
packedRGBA.a);
}
}
}
else if(numberOfChannels == 3){
unpacked = packedRGBA;
}
return unpacked;
}
// Support up to textureSize*textureSize*7 voxels
vec4 texture3DPolyfill(ivec3 dataCoordinates,
ivec3 dataDimensions,
int textureSize,
sampler2D textureContainer0,
sampler2D textureContainer1,
sampler2D textureContainer2,
sampler2D textureContainer3,
sampler2D textureContainer4,
sampler2D textureContainer5,
sampler2D textureContainer6,
sampler2D textureContainer[7] // not working on Moto X 2014
) {
// Model coordinate to data index
int index = dataCoordinates.x
+ dataCoordinates.y * dataDimensions.x
+ dataCoordinates.z * dataDimensions.y * dataDimensions.x;
// Map data index to right sampler2D texture
int voxelsPerTexture = textureSize*textureSize;
int textureIndex = int(floor(float(index)/float(voxelsPerTexture)));
// modulo seems incorrect sometimes...
// int inTextureIndex = int(mod(float(index), float(textureSize*textureSize)));
int inTextureIndex = index - voxelsPerTexture*textureIndex;
bug
// Get row and column in the texture
int colIndex = int(mod(float(inTextureIndex), float(textureSize)));
int rowIndex = int(floor(float(inTextureIndex)/float(textureSize)));
// Map row and column to uv
vec2 uv = vec2(0,0);
uv.x = (0.5 + float(colIndex))/float(textureSize);
uv.y = 1. - (0.5 + float(rowIndex))/float(textureSize);
//
vec4 dataValue = vec4(0., 0., 0., 0.);
if(textureIndex == 0){ dataValue = texture2D(textureContainer0, uv); }
else if(textureIndex == 1){dataValue = texture2D(textureContainer1, uv);}
else if(textureIndex == 2){ dataValue = texture2D(textureContainer2, uv); }
else if(textureIndex == 3){ dataValue = texture2D(textureContainer3, uv); }
else if(textureIndex == 4){ dataValue = texture2D(textureContainer4, uv); }
else if(textureIndex == 5){ dataValue = texture2D(textureContainer5, uv); }
else if(textureIndex == 6){ dataValue = texture2D(textureContainer6, uv); }
return dataValue;
}
void main(void) {
// get texture coordinates of current pixel
// doesn't need that in theory
vec4 dataCoordinatesRaw = uWorldToData * vPos;
// rounding trick
// first center of first voxel in data space is CENTERED on (0,0,0)
dataCoordinatesRaw += 0.5;
ivec3 dataCoordinates = ivec3(int(floor(dataCoordinatesRaw.x)), int(floor(dataCoordinatesRaw.y)), int(floor(dataCoordinatesRaw.z)));
// index 100
// dataCoordinates.x = 26; //25
// dataCoordinates.y = 1;
// dataCoordinates.z = 0;
// if data in range, look it up in the texture!
if (all(greaterThanEqual(dataCoordinates, ivec3(0))) &&
all(lessThan(dataCoordinates, uDataDimensions))) {
vec4 packedValue = texture3DPolyfill(
dataCoordinates,
uDataDimensions,
uTextureSize,
uTextureContainer[0],
uTextureContainer[1],
uTextureContainer[2],
uTextureContainer[3],
uTextureContainer[4],
uTextureContainer[5],
uTextureContainer[6],
uTextureContainer // not working on Moto X 2014
);
vec4 dataValue = unpack(
packedValue,
uBitsAllocated,
0,
uNumberOfChannels,
uPixelType);
// how do we deal wil more than 1 channel?
if(uNumberOfChannels == 1){
float intensity = dataValue.r;
// rescale/slope
intensity = intensity*uRescaleSlopeIntercept[0] + uRescaleSlopeIntercept[1];
// window level
// if(intensity < 2000.){
// gl_FragColor = vec4(1.0, 0., 0., 1.);
//return;
// }
float windowMin = uWindowCenterWidth[0] - uWindowCenterWidth[1] * 0.5;
float windowMax = uWindowCenterWidth[0] + uWindowCenterWidth[1] * 0.5;
intensity = (intensity - windowMin)/uWindowCenterWidth[1];
dataValue.r = dataValue.g = dataValue.b = intensity;
}
// Apply LUT table...
//
if(uLut == 1){
// should opacity be grabbed there?
dataValue = texture2D(uTextureLUT, vec2(dataValue.r , 1.0));
}
if(uInvert == 1){
dataValue = vec4(1.) - dataValue;
// how do we deal with that and opacity?
dataValue.a = 1.;
}
gl_FragColor = dataValue;
}
else{
// should be able to choose what we want to do if not in range:
// discard or specific color
discard;
gl_FragColor = vec4(0.011, 0.662, 0.956, 1.0);
}
}"
Github Ausgabe: https://github.com/FNNDSC/ami/issues/39
Best, Nicolas
keine Ahnung, was der Fehler ist aber diese Zeile 'int issigned = int (. pow (-1, Schwimmer (bytemeR [0])));' ist illegal. Sie können keine negativen Zahlen an die Macht bringen. Siehe GLSL-Spezifikation. Andernfalls können Sie mit der Erweiterung ['WEBGL_debug_shaders'] (https://www.khronos.org/registry/webgl/extensions/WEBGL_debug_shaders/) herausfinden, was WebGL an DirectX sendet. Es könnte Ihnen eine Vorstellung davon geben, was den Fehler verursacht – gman
danke wird in das schauen! – Nicolas
@gman das war das Problem - willst du eine Antwort posten, die ich akzeptieren kann oder sollte ich es selbst tun? – Nicolas