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 9 of 9

Thread: GLSL 400 multi texturing, how best?

  1. #1
    Intern Contributor
    Join Date
    Dec 2011
    Posts
    54

    GLSL 400 multi texturing, how best?

    Hi,

    I need to help with multi texturing. I wanna more then 4 textures and also using shader color for changing texture color(look to following img)

    Click image for larger version. 

Name:	WoWScrnShot_092409_003328.jpg 
Views:	278 
Size:	82.9 KB 
ID:	1149

    Currently I'm using textures based on height (3: grass[base], rock, snow). I read they using vec4 to combine one texture per channel, this mean just 4 textures, how to do more textures?

    Current GLSL:
    Code :
        vec2 uvNear, uvFar;
     
        nearAndFarTexCoords(uvNear, uvFar);
     
        float textureDistanceFactor = textureDistanceBlendFactor();
     
        // Get grass texture color
        vec4 grassNear  = texture(grassTexture, uvNear);
        vec4 grassFar   = texture(grassTexture, texCoords);
        vec4 grassColor = mix(grassNear, grassFar, textureDistanceFactor);
     
        // Get rock texture color
        vec4 rockNear  = texture(rockTexture, uvNear);
        vec4 rockFar   = texture(rockTexture, uvFar);
        vec4 rockColor = mix(rockNear, rockFar, textureDistanceFactor);
     
        // Blend rock and grass texture based upon the worldNormal vector
        vec4 grassRockColor = mix(rockColor, grassColor, smoothstep(0.75, 0.95, clamp(worldNormal.y, 0.0, 1.0)));
     
        // Now blend with snow based upon world height
        vec4 snowNear  = texture(snowTexture, uvNear);
        vec4 snowFar   = texture(snowTexture, 5.0 * uvFar);
        vec4 snowColor = mix(snowNear, snowFar, textureDistanceFactor);
     
        vec4 diffuseColor = mix(grassRockColor, snowColor, smoothstep(10.0, 15.0, worldPosition.y));
     
        // Calculate the lighting model, keeping the specular component separate
        vec3 ambientAndDiff, spec;
     
        phongModel(ambientAndDiff, spec);
     
        vec4 color = vec4(ambientAndDiff, 1.0) * diffuseColor + vec4(spec, 1.0);

  2. #2
    Junior Member Newbie
    Join Date
    Jun 2013
    Posts
    25
    You said something about using vec4 to combine textures... This sounds odd to me, I'm not sure what you mean by this.

    vec4 has four components and a texture typically also has four components. vec4(Red, Green, Blue, Alpha). One vec4 is one texture.

    So far as the number of textures you can use.... I would say that 8 textures will probably work on most machines, maybe not well.... There will likely be a few here and there that won't like this at all.

    You can also look up 'texture atlas' which is a technique for packing many UV coordinates into just one texture.

  3. #3
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    495
    Quote Originally Posted by marcClintDion View Post
    You said something about using vec4 to combine textures... This sounds odd to me, I'm not sure what you mean by this.
    I assume that he's referring to texture splatting (aka splat mapping), where you have up to four terrain textures then another texture which is effectively 4 alpha channels, one for each of the terrain textures. Most of the time, one channel will be at 1.0 to select a specific terrain texture and the other three at zero; at boundaries between terrain types, two channels will have intermediate values to blend between two textures, with the other two at zero.

    It would be possible to have another 4 terrain textures and another alpha texture (OpenGL 3.x guarantees at least 16 texture image units per shader), but getting to be expensive in terms of both memory consumption and bandwidth and processing time. Given that you're unlikely to want to blend more than two textures at any given point, you'd probably be better off with e.g. a GL_RG8UI texture holding the indices of a primary and secondary texture for each texel plus a GL_R8 texture to specify the blend factor between the two. That supports up to 256 terrain textures with less memory consumption for the "map" texture than the 4-alpha-channels approach (which was originally designed for hardware which lacked array textures, so you couldn't choose which textures to blend, only vary their blend factors).

  4. #4
    Intern Contributor
    Join Date
    Dec 2011
    Posts
    54
    marClintDion: GClements was right, I meant texture splatting

    GClements: So texture splatting is not perfect for this?

    I'm making world editor, so I want to change textures by painting tool

  5. #5
    Intern Contributor
    Join Date
    Dec 2011
    Posts
    54
    Is possible with GLSL 3.3+ multitexturing do it through alphamaps?

    See ex: http://www.sdilej.eu/pics/26b05e6045...095118b7cd.png
    On picture are 5 textures (including base). Base texture is green, alphamap is full. And others alphamaps (each for texture) are filled just where texture is painted. Do you understand what I mean?

    Or exists still better way to make multitexturing for change with tools?

  6. #6
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    495
    Quote Originally Posted by glararan View Post
    See ex: http://www.sdilej.eu/pics/26b05e6045...095118b7cd.png
    On picture are 5 textures (including base). Base texture is green, alphamap is full. And others alphamaps (each for texture) are filled just where texture is painted. Do you understand what I mean?
    Yes. That's typical texture splatting; one base texture and four overlays controlled by a 4-channel alpha map.

    If you're asking how to do it, try:
    Code :
    uniform sampler2D textureMap;
    uniform sampler2D textureBase;
    uniform sampler2D texture0;
    uniform sampler2D texture1;
    uniform sampler2D texture2;
    uniform sampler2D texture3;
    in vec2 texcoordMap;
    in vec2 textureScale;
    void main()
    {
        vec2 texcoord = texcoordMap * textureScale;
        vec4 alpha = texture(textureMap, texcoordMap);
        vec4 color = texture(textureBase, texcoord);
        color = mix(color, texture(texture0, texcoord), alpha[0]);
        color = mix(color, texture(texture1, texcoord), alpha[1]);
        color = mix(color, texture(texture2, texcoord), alpha[2]);
        color = mix(color, texture(texture3, texcoord), alpha[3]);
        ...
    }

  7. #7
    Intern Contributor
    Join Date
    Dec 2011
    Posts
    54
    Ok thanks, and this is btw not possible with more than 4 textures right?

  8. #8
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    495
    Quote Originally Posted by glararan View Post
    and this is btw not possible with more than 4 textures right?
    You'd need another alpha map for each set of 4 terrain textures, but the only hard limit is the number of texture units supported by the implementation. OpenGL 3.x guarantees at least 16 texture units, so 1 base texture, 3 alpha maps and 12 terrain textures is possible.

    However, it's inefficient to read many textures when you're typically only using 1 or 2 at any given point, so you'd probably want to use a different approach with more than 4 textures (or even just with 4 textures).

  9. #9
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,220
    Quote Originally Posted by GClements View Post
    ...but the only hard limit is the number of texture units supported by the implementation.
    And even that isn't a limit anymore, if you're on a GPU/driver which supports ARB_bindless_texture.
    Last edited by Dark Photon; 09-13-2013 at 09:12 AM.

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
  •