Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 10 of 10

Thread: Sending raw data as texture to vertex shader

  1. #1
    Junior Member Newbie
    Join Date
    Dec 2010
    Posts
    11

    Sending raw data as texture to vertex shader

    Hello,

    I am developing a terrain fractal generator based on an original heightmap of 256*256. Each point in the height map contain the height but also gradient on X and gradient on Y. These are inputs to my program.
    I want to send this heightmap in the shader and access it's values in the vertex shader. That is, because I cannot compute the elevation given X and Y ( Z is upwards ) unless I can compute the cell in which the XY is located and then compute the elevation based on the height and gradients.
    I have used the following basic code:

    Code :
    glEnable( GL_TEXTURE_2D );glGenTextures(1, &m_uglID);
    glBindTexture(GL_TEXTURE_2D, m_uglID);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB, 256, 256);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 256, GL_RGB, GL_FLOAT, pvBytes);
     
    ...
     
    m_ugl_HeightMapTexture = glGetUniformLocation(m_uglProgram, "TexHeightMap");
     
    ...
     
    glEnable(GL_TEXTURE_2D );
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D , pTexture->GetID());
    glUniform1i(m_ugl_HeightMapTexture, 0);

    shader code:

    Code :
    uniform sampler2D TexHeightMap;
    vec4 GetVertCellParameters( uint i, uint j )
    {
        return texture( TexHeightMap, vec2( i, j ) );
    }
    ...
        vec4 vH00 = GetVertCellParameters( i, j );
        vec4 vH10 = GetVertCellParameters( i + 1u, j );
        vec4 vH01 = GetVertCellParameters( i, j + 1u );
        vec4 vH11 = GetVertCellParameters( i + 1u, j + 1u );


    Code doesn't work ( cannot send the actual data to the shader ), unless data contain only positive values. I need a way to get the whole heightmap ( together with gradients ) to the shader.

  2. #2
    Advanced Member Frequent Contributor
    Join Date
    Apr 2010
    Posts
    720
    Code doesn't work ( cannot send the actual data to the shader ), unless data contain only positive values. I need a way to get the whole heightmap ( together with gradients ) to the shader.
    I can follow you up to this point where you are describing your actual problem For example: what do you mean by "can not sent the actual data to the shader"? You do upload the data, that's what the glTexSubImage2D call does. Can you try explaining the problem again, being careful to state what is happening vs. what you'd expect to happen?

    As a somewhat random guess: are you setting the minification/magnification filter modes for your texture? If not your problem is probably that the default minification filter is GL_NEAREST_MIPMAP_LINEAR, but you don't specify all necessary mipmap levels.

  3. #3
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,117
    The normal way to send negative numbers is to displacement the values eg -1 to +1 is sent as 0 - 2 then you subtract the base in the shader. If space is a problem in the texture you may have to loose accuracy by mapping -1 to 1 to the range 0-1.

  4. #4
    Junior Member Newbie
    Join Date
    Dec 2010
    Posts
    11
    Quote Originally Posted by carsten neumann View Post
    I can follow you up to this point where you are describing your actual problem For example: what do you mean by "can not sent the actual data to the shader"? You do upload the data, that's what the glTexSubImage2D call does. Can you try explaining the problem again, being careful to state what is happening vs. what you'd expect to happen?

    As a somewhat random guess: are you setting the minification/magnification filter modes for your texture? If not your problem is probably that the default minification filter is GL_NEAREST_MIPMAP_LINEAR, but you don't specify all necessary mipmap levels.
    I am uploading the data to the shader, but I cannot see the actual data that are read from the shader ( as I cannot set a breakpoint in the shader ).
    My actual shader just draws the terrain in blue color and a highroad in green; I have tried to send random data to the shader ( rand() % 1500 ) in each float value and things worked pretty much as expected: draw a green highroad with a blue terrain that was having quite random hieghtvalues which is ok.
    When I changed some values to -(rand() % 1500) ( that is, negative values ), the terrain draw partially and the green highroad ( which is drawn last ) is not drawn at all, something like the shader crashed somewhere or I don't know. I suspect the problem comes from the fact that I pass negative values.
    Perhaps I need to map all values in 0-1 but that would add a precision and performance penalty. Best would be to just get the original data into the texture and have it available in the shader as I have it in CPU memory.

  5. #5
    Intern Newbie
    Join Date
    May 2010
    Posts
    38
    Try GL_RGB32F as internalformat for glTexStorage2D.

  6. #6
    Member Regular Contributor
    Join Date
    Aug 2008
    Posts
    450
    Quote Originally Posted by wtherapy View Post
    Perhaps I need to map all values in 0-1 but that would add a precision and performance penalty. Best would be to just get the original data into the texture and have it available in the shader as I have it in CPU memory.
    Yes, texture() accepts values in the range 0.0 - 1.0 when using sampler2D. So if you're providing integer values you're likely to just be getting the texture repeated many times (behaving however the wrap mode specifies). If you use GL_TEXTURE_2D you'll need to divide by the width (+remember to fill or disable mipmaps), alternatively you could use a rectangle texture + sampler2DRect.

  7. #7
    Junior Member Newbie
    Join Date
    Dec 2010
    Posts
    11
    Quote Originally Posted by Dan Bartlett View Post
    Yes, texture() accepts values in the range 0.0 - 1.0 when using sampler2D. So if you're providing integer values you're likely to just be getting the texture repeated many times (behaving however the wrap mode specifies). If you use GL_TEXTURE_2D you'll need to divide by the width (+remember to fill or disable mipmaps), alternatively you could use a rectangle texture + sampler2DRect.
    Hello,

    thanks for the info. I suspect that, when sending integer, the gltext* will just map the highest representable value to 1 and the lowest to 0.
    I have tried your suggestion, but the shader fails to compile with the error:

    0(35) : error C1101: ambiguous overloaded function reference "texture2DRect(sampler2DRect, vec2)"
    (0) : fpf gpf vpf tpf hpf gp4 fp50 vp50 cp50 gp50 uvec4 texture2DRect(usampler2DRect, vec2)
    (0) : fpf gpf vpf tpf hpf gp4 fp50 vp50 cp50 gp50 ivec4 texture2DRect(isampler2DRect, vec2)
    (0) : vec4 texture2DRect(sampler2DRect, vec2)

    my first lines in the shader are

    #version 140
    #extension GL_EXT_gpu_shader4 : enable
    #extension GL_NV_shader_buffer_load : enable
    #extension GL_ARB_uniform_buffer_object : enable

  8. #8
    Member Regular Contributor
    Join Date
    Aug 2008
    Posts
    450
    If you're using #version 140, you should be able to just change the sampler type + continue using texture(). The compiler will determine the correct overloaded texture() function to call.
    Code :
    uniform sampler2DRect TexHeightMap;
    vec4 GetVertCellParameters( uint i, uint j )
    {
        return texture( TexHeightMap, vec2( i, j ) );
    }
    ...

  9. #9
    Junior Member Newbie
    Join Date
    Dec 2010
    Posts
    11
    Quote Originally Posted by Dan Bartlett View Post
    If you're using #version 140, you should be able to just change the sampler type + continue using texture(). The compiler will determine the correct overloaded texture() function to call.
    Code :
    uniform sampler2DRect TexHeightMap;
    vec4 GetVertCellParameters( uint i, uint j )
    {
        return texture( TexHeightMap, vec2( i, j ) );
    }
    ...
    Thanks, just did the modification and something changed, but I seem to still get values of 0 in the shader texture ( I don't think they are 0-1, I think they are just 0 ).

    My code:

    Code :
        glEnable( GL_TEXTURE_RECTANGLE );
        glGenTextures(1, &m_uglID);
        glBindTexture(GL_TEXTURE_RECTANGLE, m_uglID);
        glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGB32F, unW, unH, 0, GL_RGB, GL_FLOAT, pvBytes);
     
    ///
     
        glEnable(GL_TEXTURE_RECTANGLE );
        glActiveTexture(GL_TEXTURE_RECTANGLE);
        glBindTexture(GL_TEXTURE_RECTANGLE, pTexture->GetID());
        glUniform1i(m_ugl_HeightMapTexture, 0);
     
    ///
     
    uniform sampler2DRect TexHeightMap;
     
     
    vec4 GetVertCellParameters( uint i, uint j )
    {
        return texture( TexHeightMap, vec2( i, j ) );
    }

  10. #10
    Junior Member Newbie
    Join Date
    Dec 2010
    Posts
    11
    Quote Originally Posted by Dan Bartlett View Post
    If you're using #version 140, you should be able to just change the sampler type + continue using texture(). The compiler will determine the correct overloaded texture() function to call.
    Code :
    uniform sampler2DRect TexHeightMap;
    vec4 GetVertCellParameters( uint i, uint j )
    {
        return texture( TexHeightMap, vec2( i, j ) );
    }
    ...
    Hello,

    back to the rand()% 1500 generated heightmap,

    using

    Code :
     
    float gvMap[257][257][4];
     
    glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA32F, unW, unH, 0, GL_RGBA, GL_FLOAT, pvBytes);glGetTexImage(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, GL_FLOAT, gvMap);

    I read exactly the same values I pass ( also negative values, where it is the case ).
    However, the shader behaves differently when passing positive or negative values.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •