Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: texture to texture array

  1. #1
    Intern Newbie
    Join Date
    Dec 2011
    Posts
    47

    Question texture to texture array

    Hi,

    I need advice about sampler2DArray. On OpenGL IRC I spoke about fast loading textures throught uniforms. Guys direct me to glTexStorage3D for 2D textures.

    Now I'm trouble with porting shaders from sampler2D to sampler2DArray.

    Tessellation ev. shader before:
    Code :
    #version 400
     
    layout(quads, fractional_even_spacing, cw) in;
     
    in terrainVertex
    {
        vec2 position;
    } In[];
     
    out worldVertex
    {
        vec4 worldPosition;
        vec3 worldNormal;
        vec4 position;
        vec3 normal;
        vec2 texCoords;
    } Out;
     
    uniform sampler2D heightMap;
     
    // The number of triangles created per height-map texel
    uniform int maxTrianglesPerTexel = 10;
     
    // Distance between each tessellation point at max tess level
    uniform float horizontalScale = 10.0;
     
    // Transformation matrices
    uniform mat4 modelMatrix;
    uniform mat4 modelViewMatrix;
    uniform mat3 worldNormalMatrix;
    uniform mat3 normalMatrix;
    uniform mat4 mvp;
     
    const float maxTessLevel = 64.0;
     
    void main()
    {
        // Calculate extent of this patch in texture coords [0,1]
        vec2 patchExtent = maxTessLevel / (textureSize(heightMap, 0) * maxTrianglesPerTexel);
     
        // Calculate the texture coordinates
        Out.texCoords = In[0].position.xy + gl_TessCoord.xy * patchExtent;
     
        // Calculate the model-space position
        vec4 position;
        position.xz = Out.texCoords * horizontalScale;
        position.y  = texture(heightMap, Out.texCoords).r;
        position.w  = 1.0;
     
        // Transform the position to world coordinates and to eye space
        Out.worldPosition = modelMatrix * position;
        Out.position      = modelViewMatrix * position;
     
        // Calculate the normal
        // This could be moved to a one-time pre-process step to create a normal map.
        // This would be a good candidate for a compute shader.
        // For deformable terrain, would need re-generating when terrain is modified
        const ivec3 offset = ivec3(-1, 0, 1); // Texel offsets
        float delta  = 2.0 * horizontalScale / textureSize(heightMap, 0).x; // Horizontal displacement in world coords
        float left   = textureOffset(heightMap, Out.texCoords, offset.xy).r;
        float right  = textureOffset(heightMap, Out.texCoords, offset.zy).r;
        float top    = textureOffset(heightMap, Out.texCoords, offset.yz).r;
        float bottom = textureOffset(heightMap, Out.texCoords, offset.yx).r;
     
        vec3 x = normalize(vec3(delta, right - left, 0.0));
        vec3 z = normalize(vec3(0.0, top - bottom, delta));
        vec3 n = cross(z, x);
     
        Out.worldNormal = worldNormalMatrix * n;
        Out.normal      = normalMatrix * n;
     
        // Transform to clip-space
        gl_Position = mvp * position;
    }

    I don't know how to use textureOffset(..) (left, right, top, bottom) in sampler2DArray, also texture(..) (position.y), textureSize(..) (patchExtent)

    I read http://www.opengl.org/wiki/Array_Texture so I should use "actual_layer = max(0, min(d​ - 1, floor(layer​ + 0.5)) )" ? And use for in shader? Is this correct way? I don't think it's correct way.

    Thanks for help.
    Last edited by glararan; 09-28-2013 at 06:03 AM.

  2. #2
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    474
    Quote Originally Posted by glararan View Post
    I don't know how to use textureOffset(..) (left, right, top, bottom) in sampler2DArray
    The texture functions work the same as for sampler2D, except that the coordinates contain an extra component to select the layer. For textureOffset, the offset parameter is still an ivec2 (i.e. the offset only applies to selection of texels within a layer, not the selection of a layer).

    Quote Originally Posted by glararan View Post
    I read http://www.opengl.org/wiki/Array_Texture so I should use "actual_layer = max(0, min(d - 1, floor(layer + 0.5)) )" ? And use for in shader? Is this correct way? I don't think it's correct way.
    That just specifies that the layer is rounded to the nearest integer then clamped. Typically, the layer is an integer; although it may have been passed via a floating-point attribute, you wouldn't normally interpolate it.

  3. #3
    Intern Newbie
    Join Date
    Dec 2011
    Posts
    47
    Ok, if its same then following code should be:

    Code :
    #version 400
    #extension GL_EXT_texture_array : enable
     
    layout(quads, fractional_even_spacing, cw) in;
     
    in terrainVertex
    {
        vec2 position;
    } In[];
     
    out worldVertex
    {
        vec4 worldPosition;
        vec3 worldNormal;
        vec4 position;
        vec3 normal;
        vec2 texCoords;
    } Out;
     
    uniform sampler2DArray heightMap;
     
    // The number of triangles created per height-map texel
    uniform int maxTrianglesPerTexel = 10;
     
    // Distance between each tessellation point at max tess level
    uniform float horizontalScale = 10.0;
     
    // Transformation matrices
    uniform mat4 modelMatrix;
    uniform mat4 modelViewMatrix;
    uniform mat3 worldNormalMatrix;
    uniform mat3 normalMatrix;
    uniform mat4 mvp;
     
    const float maxTessLevel = 64.0;
     
    void main()
    {
        // Calculate extent of this patch in texture coords [0,1]
        vec2 patchExtent = maxTessLevel / (textureSize(heightMap, 0).xy * maxTrianglesPerTexel); // -- modified
     
        // Calculate the texture coordinates
        Out.texCoords = In[0].position.xy + gl_TessCoord.xy * patchExtent;
     
        // Calculate the model-space position
        vec4 position;
        position.xz = Out.texCoords * horizontalScale;
        position.y  = texture(heightMap, vec3(Out.texCoords, 0)).r; // -- modified
        position.w  = 1.0;
     
        // Transform the position to world coordinates and to eye space
        Out.worldPosition = modelMatrix * position;
        Out.position      = modelViewMatrix * position;
     
        // Calculate the normal
        // This could be moved to a one-time pre-process step to create a normal map.
        // This would be a good candidate for a compute shader.
        // For deformable terrain, would need re-generating when terrain is modified
        const ivec3 offset = ivec3(-1, 0, 1); // Texel offsets
     
        float delta  = 2.0 * horizontalScale / textureSize(heightMap, 0).x; // Horizontal displacement in world coords
        float left   = textureOffset(heightMap, vec3(Out.texCoords, 0), offset.xy).r; // -- modified
        float right  = textureOffset(heightMap, vec3(Out.texCoords, 0), offset.zy).r; // -- modified
        float top    = textureOffset(heightMap, vec3(Out.texCoords, 0), offset.yz).r; // -- modified
        float bottom = textureOffset(heightMap, vec3(Out.texCoords, 0), offset.yx).r; // -- modified
     
        vec3 x = normalize(vec3(delta, right - left, 0.0));
        vec3 z = normalize(vec3(0.0, top - bottom, delta));
        vec3 n = cross(z, x);
     
        Out.worldNormal = worldNormalMatrix * n;
        Out.normal      = normalMatrix * n;
     
        // Transform to clip-space
        gl_Position = mvp * position;
    }

    ???

    Sampler2D code:
    Code :
    #version 400
     
    layout(quads, fractional_even_spacing, cw) in;
     
    in terrainVertex
    {
        vec2 position;
    } In[];
     
    out worldVertex
    {
        vec4 worldPosition;
        vec3 worldNormal;
        vec4 position;
        vec3 normal;
        vec2 texCoords;
    } Out;
     
    uniform sampler2D heightMap;
     
    // The number of triangles created per height-map texel
    uniform int maxTrianglesPerTexel = 10;
     
    // Distance between each tessellation point at max tess level
    uniform float horizontalScale = 10.0;
     
    // Transformation matrices
    uniform mat4 modelMatrix;
    uniform mat4 modelViewMatrix;
    uniform mat3 worldNormalMatrix;
    uniform mat3 normalMatrix;
    uniform mat4 mvp;
     
    const float maxTessLevel = 64.0;
     
    void main()
    {
        // Calculate extent of this patch in texture coords [0,1]
        vec2 patchExtent = maxTessLevel / (textureSize(heightMap, 0) * maxTrianglesPerTexel);
     
        // Calculate the texture coordinates
        Out.texCoords = In[0].position.xy + gl_TessCoord.xy * patchExtent;
     
        // Calculate the model-space position
        vec4 position;
        position.xz = Out.texCoords * horizontalScale;
        position.y  = texture(heightMap, Out.texCoords).r;
        position.w  = 1.0;
     
        // Transform the position to world coordinates and to eye space
        Out.worldPosition = modelMatrix * position;
        Out.position      = modelViewMatrix * position;
     
        // Calculate the normal
        // This could be moved to a one-time pre-process step to create a normal map.
        // This would be a good candidate for a compute shader.
        // For deformable terrain, would need re-generating when terrain is modified
        const ivec3 offset = ivec3(-1, 0, 1); // Texel offsets
     
        float delta  = 2.0 * horizontalScale / textureSize(heightMap, 0).x; // Horizontal displacement in world coords
        float left   = textureOffset(heightMap, Out.texCoords, offset.xy).r;
        float right  = textureOffset(heightMap, Out.texCoords, offset.zy).r;
        float top    = textureOffset(heightMap, Out.texCoords, offset.yz).r;
        float bottom = textureOffset(heightMap, Out.texCoords, offset.yx).r;
     
        vec3 x = normalize(vec3(delta, right - left, 0.0));
        vec3 z = normalize(vec3(0.0, top - bottom, delta));
        vec3 n = cross(z, x);
     
        Out.worldNormal = worldNormalMatrix * n;
        Out.normal      = normalMatrix * n;
     
        // Transform to clip-space
        gl_Position = mvp * position;
    }


    From modified code I'm getting this.
    There shouldn't be any free space, where is the bug?

  4. #4
    Intern Newbie
    Join Date
    May 2013
    Posts
    42
    Did you bind it as GL_TEXTURE_2D_ARRAY in your (presuming) C++ code?

  5. #5
    Intern Newbie
    Join Date
    Dec 2011
    Posts
    47
    Quote Originally Posted by Osbios View Post
    Did you bind it as GL_TEXTURE_2D_ARRAY in your (presuming) C++ code?
    Ofc, following code is constructor and bind
    Code :
    // -- TextureType in header
        enum TextureType
        {
            Texture1DArray = GL_TEXTURE_1D_ARRAY,
            Texture2DArray = GL_TEXTURE_2D_ARRAY
        };
     
        TextureArray(int textureWidth, int textureHeight, int layersCount, TextureType textureType = Texture2DArray);
     
    // -- constructor
    TextureArray::TextureArray(int textureWidth, int textureHeight, int layersCount, TextureType textureType)
    : type(textureType)
    , textureId(0)
    , width(textureWidth)
    , height(textureHeight)
    , layers(layersCount)
    , GLfuncs(0)
    {
        texels = new GLfloat[width * height * sizeof(float) * layers];
    }
     
     
    // -- bind
    void TextureArray::bind()
    {
        glBindTexture(type, textureId);
     
        GLfuncs->glTexStorage3D(type, 1, GL_RGBA32F, width, height, layers);
    }
     
    /// -- Create constructor of texture array in constructor of map tile
    terrainMapData(new TextureArray(MAP_WIDTH, MAP_HEIGHT, CHUNKS * CHUNKS))

  6. #6
    Intern Newbie
    Join Date
    May 2013
    Posts
    42
    I looked in my code and for the glTexStorage function I use level of 0 and not 1. In fact setting it to 1 causes my FBO on that texture to be not complete. I have no clue why, all the references actually says it has to be at last 1.

    GLfuncs->glTexStorage3D(type, 0, GL_RGBA32F, width, height, layers);

    On a side note: are you sure that sizeof(float) is right inside a new GLfloat(). Looks to me that it just randomly gives you the right value 4 that you need for the 4 color components...

  7. #7
    Intern Newbie
    Join Date
    Dec 2011
    Posts
    47
    Quote Originally Posted by Osbios View Post
    I looked in my code and for the glTexStorage function I use level of 0 and not 1. In fact setting it to 1 causes my FBO on that texture to be not complete. I have no clue why, all the references actually says it has to be at last 1.

    GLfuncs->glTexStorage3D(type, 0, GL_RGBA32F, width, height, layers);

    On a side note: are you sure that sizeof(float) is right inside a new GLfloat(). Looks to me that it just randomly gives you the right value 4 that you need for the 4 color components...
    I just changed glTexStorage3D it show me whole terrain (just from loader), after initializing nVidia driver crashed. No idea why, I will investigate that.

  8. #8
    Intern Newbie
    Join Date
    May 2013
    Posts
    42
    Sorry I mixed up glTexStorage with glTexImage. The 1 for layer is correct!

  9. #9
    Intern Newbie
    Join Date
    Dec 2011
    Posts
    47
    Quote Originally Posted by Osbios View Post
    Sorry I mixed up glTexStorage with glTexImage. The 1 for layer is correct!
    So I should revert my change?

  10. #10
    Intern Newbie
    Join Date
    May 2013
    Posts
    42
    Yes. Like I said I mixed up the glTexStorage and glTexImage functions. Your parameters for glTexStorage3D are correct.

Tags for this Thread

Posting Permissions

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