3 Replies Latest reply on Jan 15, 2015 11:04 PM by davychen

    GLSL Fragment Shader problem

    simon.anderson@riotinto.com

      Hi,

       

      I'm a newbie with GLSL and currently experiencing a crash in a fragment shader on my ATI FirePro V and have no idea why. 

       

      If I take out the for loop it seems to work, although I don't think that should matter.  Are there issues with for loops on ATI cards?  Could the vertex shader be the cause of the problem instead?

       

      It runs fine on my intel and NVidia cards.  Any help would be much appreciated - here's the complete code for the fragment shader:

       

      struct Accumulator

      {

          float m_sumOfWeightedValues;

          float m_sumOfWeights;

      };

       

      void main()

      {

          Accumulator acc = Accumulator(0.0f,0.0f);

       

          // For each cell in range

          for(int x=0;x<=1;x++)

          {

              acc.m_sumOfWeights = 0.0f;

              acc.m_sumOfWeightedValues = 0.0f;

          }

       

          if( acc.m_sumOfWeights > 0.0f )

          {

              // Clamp uv to half texel from edge to avoid interpolation / wrapping.

              float padding = 0.5f / textureSize(s_texture_1,0).x;

              float w = clamp(1.0f,padding,1.0f - padding);

              s_frag_color =  texture(s_texture_1,vec2(w,0),0);

          }

      }

       

       

       

      Any help would be much appreciated.

       

      Cheers,

      Simon

        • Re: GLSL Fragment Shader problem
          davychen

          hi Simon,

           

          i've checked your shader,

           

          you said it's complete code,

          but where did you declare GLSL version and "s_texture_1", "s_frag_color "?

           

          i added foloowing lines to your FS,

           

          #version 440 compatibility

          uniform sampler2D s_texture_1;

          out vec4 s_frag_color;

           

          then both compiling & linking of the shader can pass.

          can you check it?

           

          regards

          davy

            • Re: Re: GLSL Fragment Shader problem
              simon.anderson@riotinto.com

              Hi Davy,

               

              Thanks for having a look at this - below are the complete vertex and fragment shaders.  The header file where a lot of the variables are stored isn't attached though.

               

               

               

              #include <core/shaders/default/common/vertex_base.h>

               

               

              /*

                  Trivial vertex shader for IDW - just passes the uv (representing the vertex position in

                  normalised query volume space) along as a varying vec3.

              */

               

               

              /******************************************************************************\

              *

              * OpenGL/OpenGLES

              *

              \******************************************************************************/

               

               

              #ifdef OPENGL || OPENGLES

               

               

                  in float4 s_attribute_0;

                  in half4 s_attribute_1;

                  in half4 s_attribute_2;

               

               

                  out vec3 normalisedFragmentLoc;

               

               

                  void main()

                  {

                      float4 row_0,row_1,row_2;

               

               

                      row_0 = s_transform[0];

                      row_1 = s_transform[1];

                      row_2 = s_transform[2];

               

               

                      float4 position = float4(s_attribute_0.x,s_attribute_0.y,s_attribute_2.w,1.0f);

                      float4 vertex = float4(dot(row_0,position),dot(row_1,position),dot(row_2,position),1.0f);

               

               

                      gl_Position = getPosition(vertex);

                      normalisedFragmentLoc = s_attribute_1.xyz;

                  }

               

               

              #elif DIRECT3D10 || DIRECT3D11

               

               

              /******************************************************************************\

              *

              * DirectX 10/11

              *

              \******************************************************************************/

               

               

               

               

              ----------------------------------------------PIXEL SHADER----------------------------------------------

               

               

               

              #include <core/shaders/default/common/fragment_base.h>

               

               

              /******************************************************************************\

              *

              * OpenGL/OpenGLES

              *

              \******************************************************************************/

               

               

              #ifdef OPENGL || OPENGLES

               

               

              in vec3 normalisedFragmentLoc;

               

               

              uniform sampler2D s_texture_0;      // Drill data measurements. Each texel has the position and value of a down hole measurement, and

                                                  // each row contains samples positioned within a cell of a regular lattice spanning the volume of interest.

               

               

              uniform sampler2D s_texture_1;      // LUT texture to transform from value to color - should be in a seperate pass so that we render *values* in here not the value to color mapping.

               

               

              // Set from script based on dataset

              uniform vec4 volume_range;

              uniform vec4 grid_size;

               

               

              // User controlled parameters

              uniform float idw_range;

              uniform float idw_rangeMultiplierZ;

              uniform float idw_exponent;

              uniform float idw_linearFadeFactor;

              uniform float idw_ignoreTopDist;

              uniform float apply_mapping;

               

               

               

               

              struct Accumulator

              {

                  float m_sumOfWeightedValues;

                  float m_sumOfWeights;

              };

               

               

              float GetWeightedAverage(Accumulator acc)

              {

                  return acc.m_sumOfWeightedValues / acc.m_sumOfWeights;

              }

               

               

              float worldSpaceDistance(vec3 a, vec3 b)

              {

                  vec3 v = volume_range.xyz * (a - b);

                  v.z *= idw_rangeMultiplierZ;

                  return length( v );

              }

               

               

              void Gather(in int row, in int rowLength, inout Accumulator acc)

              {

                  // First two texels represent the bounding box

                  vec4 minV = texelFetch(s_texture_0,ivec2(0,row),0);

                  vec4 maxV = texelFetch(s_texture_0,ivec2(1,row),0);

               

               

                  vec3 closePoint = clamp( normalisedFragmentLoc, minV.xyz, maxV.xyz );

                  if( worldSpaceDistance( normalisedFragmentLoc, closePoint ) < idw_range )

                  {

                      int sampleCount = int(minV.w * rowLength);

                      for(int i=0;i<sampleCount;i++)

                      {

                          vec4 texel = texelFetch(s_texture_0,ivec2(i+2,row),0);

               

               

                          float d = worldSpaceDistance( normalisedFragmentLoc, texel.xyz );

                          if( d < idw_range && texel.z < idw_ignoreTopDist )

                          {

                              float weight = 1.0f / pow(d,idw_exponent);

                              weight *= (1.0f - idw_linearFadeFactor * (d / idw_range));

               

               

                              acc.m_sumOfWeights += weight;

                              acc.m_sumOfWeightedValues += weight * texel.w;

                          }

                      }

                  }

              }

               

               

               

               

              void main()

              {

                  ivec2 encodedSize = textureSize(s_texture_0,0);

                 

                  Accumulator acc = Accumulator(0.0f,0.0f);

               

               

                  // Compensate for sqaushed Z

                  vec3 radiusNormalised = idw_range / volume_range.xyz;

                  radiusNormalised.z /= idw_rangeMultiplierZ;

                 

                  // Index into the lattice

                  ivec3 maxRange = ivec3(grid_size.xyz) - ivec3(1);

                  ivec3 minV = clamp( ivec3(floor( (normalisedFragmentLoc - radiusNormalised) * grid_size.xyz )),ivec3(0),maxRange );

                  ivec3 maxV = clamp( ivec3(floor( (normalisedFragmentLoc + radiusNormalised) * grid_size.xyz )),ivec3(0),maxRange );

               

               

                  // For each cell in range

                  for(int x=minV.x;x<=maxV.x;x++)

                  {

                      for(int y=minV.y;y<=maxV.y;y++)

                      {

                          for(int z=minV.z;z<=maxV.z;z++)

                          {

                              // Find the row in the texture where all values are encoded for this cell

                              int index = int(x + y * grid_size.x + z * (grid_size.x * grid_size.y));

                              Gather(index,encodedSize.x,acc);

                          }

                      }

                  }

               

               

                  // Operate in 2 modes -> either render raw result, or render color mapped result

                  if( apply_mapping < 1.0f )

                  {

                      if( acc.m_sumOfWeights > 0.0f )

                      {

                          float w = GetWeightedAverage(acc);

                          s_frag_color = vec4(vec3(w),1);

                      }

                      else

                      {

                          s_frag_color = vec4(0);

                      }

                  }

                  else

                  {

                      if( acc.m_sumOfWeights > 0.0f )

                      {

                          // Clamp uv to half texel from edge to avoid interpolation / wrapping.

                          float padding = 0.5f / textureSize(s_texture_1,0).x;

                          float w = clamp(GetWeightedAverage(acc),padding,1.0f - padding);

                          s_frag_color = texture(s_texture_1,vec2(w,0),0);

                      }

                      else

                      {

                          discard;

                      }

                  }

                s_frag_color = vec4(0);

              }

               

               

              /******************************************************************************\

              *

              * DirectX 10/11

              *

              \******************************************************************************/

               

               

              #elif DIRECT3D10 || DIRECT3D11

               

               

               

               

              #endif

                • Re: GLSL Fragment Shader problem
                  davychen

                  hi Simon,

                   

                  i modified a little above code, than it can pass.

                   

                  i've changed:

                  in VS:

                   

                  1) float4 & half4 to vec4

                  GLSL doesn't support float4 & half4

                   

                  2) add:

                  uniform vec4 s_transform[3];

                   

                  3) delete getPosition()

                  it seems a user-defined function,

                  and you didn't paste in above code.

                   

                  4) add version declaration

                   

                  in FS:

                  5) add:

                  out vec4 s_frag_color;

                   

                  6) add version declaration

                   

                  that's all.

                   

                  here i paste the code after my change:

                   

                  // vertex shader

                  #version 440 compatibility

                   

                  in vec4 s_attribute_0;

                  in vec4 s_attribute_1;

                  in vec4 s_attribute_2;

                   

                  uniform vec4 s_transform[3];

                   

                  out vec3 normalisedFragmentLoc;

                   

                  void main()

                  {

                    vec4 row_0,row_1,row_2;

                   

                    row_0 = s_transform[0];

                    row_1 = s_transform[1];

                    row_2 = s_transform[2];

                   

                    vec4 position = vec4(s_attribute_0.x,s_attribute_0.y,s_attribute_2.w,1.0f);

                    vec4 vertex = vec4(dot(row_0,position),dot(row_1,position),dot(row_2,position),1.0f);

                   

                    gl_Position = vertex;

                    normalisedFragmentLoc = s_attribute_1.xyz;

                  }

                  // end of vertex shader

                   

                  // fragment shader

                  #version 440 compatibility

                   

                  in vec3 normalisedFragmentLoc;

                   

                  uniform sampler2D s_texture_0;      // Drill data measurements. Each texel has the position and value of a down hole measurement, and

                                                      // each row contains samples positioned within a cell of a regular lattice spanning the volume of interest.

                   

                  uniform sampler2D s_texture_1;      // LUT texture to transform from value to color - should be in a seperate pass so that we render *values* in here not the value to color mapping.

                   

                  // Set from script based on dataset

                  uniform vec4 volume_range;

                  uniform vec4 grid_size;

                   

                  // User controlled parameters

                  uniform float idw_range;

                  uniform float idw_rangeMultiplierZ;

                  uniform float idw_exponent;

                  uniform float idw_linearFadeFactor;

                  uniform float idw_ignoreTopDist;

                  uniform float apply_mapping;

                   

                  out vec4 s_frag_color;

                   

                  struct Accumulator

                  {

                      float m_sumOfWeightedValues;

                      float m_sumOfWeights;

                  };

                   

                  float GetWeightedAverage(Accumulator acc)

                  {

                      return acc.m_sumOfWeightedValues / acc.m_sumOfWeights;

                  }

                   

                  float worldSpaceDistance(vec3 a, vec3 b)

                  {

                      vec3 v = volume_range.xyz * (a - b);

                      v.z *= idw_rangeMultiplierZ;

                      return length( v );

                  }

                   

                  void Gather(in int row, in int rowLength, inout Accumulator acc)

                  {

                      // First two texels represent the bounding box

                      vec4 minV = texelFetch(s_texture_0,ivec2(0,row),0);

                      vec4 maxV = texelFetch(s_texture_0,ivec2(1,row),0);

                   

                      vec3 closePoint = clamp( normalisedFragmentLoc, minV.xyz, maxV.xyz );

                      if( worldSpaceDistance( normalisedFragmentLoc, closePoint ) < idw_range )

                      {

                          int sampleCount = int(minV.w * rowLength);

                          for(int i=0;i<sampleCount;i++)

                          {

                              vec4 texel = texelFetch(s_texture_0,ivec2(i+2,row),0);

                   

                              float d = worldSpaceDistance( normalisedFragmentLoc, texel.xyz );

                              if( d < idw_range && texel.z < idw_ignoreTopDist )

                              {

                                  float weight = 1.0f / pow(d,idw_exponent);

                                  weight *= (1.0f - idw_linearFadeFactor * (d / idw_range));

                   

                                  acc.m_sumOfWeights += weight;

                                  acc.m_sumOfWeightedValues += weight * texel.w;

                              }

                          }

                      }

                  }

                   

                  void main()

                  {

                      ivec2 encodedSize = textureSize(s_texture_0,0);

                    

                      Accumulator acc = Accumulator(0.0f,0.0f);

                   

                   

                      // Compensate for sqaushed Z

                      vec3 radiusNormalised = idw_range / volume_range.xyz;

                      radiusNormalised.z /= idw_rangeMultiplierZ;

                    

                      // Index into the lattice

                      ivec3 maxRange = ivec3(grid_size.xyz) - ivec3(1);

                      ivec3 minV = clamp( ivec3(floor( (normalisedFragmentLoc - radiusNormalised) * grid_size.xyz )),ivec3(0),maxRange );

                      ivec3 maxV = clamp( ivec3(floor( (normalisedFragmentLoc + radiusNormalised) * grid_size.xyz )),ivec3(0),maxRange );

                   

                   

                      // For each cell in range

                      for(int x=minV.x;x<=maxV.x;x++)

                      {

                          for(int y=minV.y;y<=maxV.y;y++)

                          {

                              for(int z=minV.z;z<=maxV.z;z++)

                              {

                                  // Find the row in the texture where all values are encoded for this cell

                                  int index = int(x + y * grid_size.x + z * (grid_size.x * grid_size.y));

                                  Gather(index,encodedSize.x,acc);

                              }

                          }

                      }

                   

                   

                      // Operate in 2 modes -> either render raw result, or render color mapped result

                      if( apply_mapping < 1.0f )

                      {

                          if( acc.m_sumOfWeights > 0.0f )

                          {

                              float w = GetWeightedAverage(acc);

                              s_frag_color = vec4(vec3(w),1);

                          }

                          else

                          {

                              s_frag_color = vec4(0);

                          }

                      }

                      else

                      {

                          if( acc.m_sumOfWeights > 0.0f )

                          {

                              // Clamp uv to half texel from edge to avoid interpolation / wrapping.

                              float padding = 0.5f / textureSize(s_texture_1,0).x;

                              float w = clamp(GetWeightedAverage(acc),padding,1.0f - padding);

                              s_frag_color = texture(s_texture_1,vec2(w,0),0);

                          }

                          else

                          {

                              discard;

                          }

                      }

                    s_frag_color = vec4(0);

                  }

                   

                  // end of fragment shader

                   

                   

                  please check.

                   

                  regards

                  davy