cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

simon_anderson
Journeyman III

GLSL Fragment Shader problem

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

0 Likes
3 Replies
davychen
Adept I

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

0 Likes

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

0 Likes

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

0 Likes