Windows上的WEBGL编译错误(ANGLE d3d9):无限对数

时间:2016-05-16 12:58:09

标签: windows webgl direct3d

我的片段着色器无法在某些Windows机器上编译。它抱怨我的着色器不包含“无限期对数”。

enter image description here

除了无限期对数之外还有什么可以触发这个错误吗?

现场演示: http://jsfiddle.net/w1r76rxm/

我的片段着色器:

   "#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问题:https://github.com/FNNDSC/ami/issues/39

最佳, 尼古拉斯

1 个答案:

答案 0 :(得分:0)

int issigned = int(pow(-1., float(bytemeR[0])));

无效,应替换为:

int issigned = 1 - 2 * bytemeR[0];