This is the testing Godot forums! All forum posts unique to this forum will be deleted! Please use the main forums here for any posts you want to keep. All forum rules still apply.

Large terrain texturing. How to change pixel RGB value to texture?

BadSadCoderBadSadCoder Posts: 6Member

I have a question about large terrain texturing. I've heard about splat maps but I don't like 3/4 texture limit.
Lets say I have texture like the one I've attached. Kind of splat map. I would like shader to read RGB pixel value from my texturemap file and replace it with specific texture image. Those color=texture.png pairs would be defined:

swamp = (0,12,0)
sand = (213,12,0)
dirtpath = (123,123,123)
rock = (12,12,12)
riverbed = (123,0,19)

and so on.
I would also like that those textures to blend with each other... Simple blending nothing fancy. How one can achieve that?

I think that in Arma game series textures on terrains are made like that.

Comments

  • ZylannZylann Posts: 31Member
    edited May 2020

    I work on a terrain plugin and I've been thinking about this for a while.
    The approach I may try soon is to use a texture array, and sample a slice of that array in a shader based on the index of the texture in the splatmap (so it would not be colors like you said, but more like a specialized splatmap painted with a specific tool, although you could feed in such color textures and generate a proper splatmap from it).
    That kind of splatmap would be different from the classic RGBA=1234, instead it would be R=textureIndex1, G=textureIndex2, B=blendingFactor. Then in the shader, color could simply be calculated like this:

    // Not true code, only as example
    
    vec3 index_and_weight = texture(u_terrain_splatmap, cell_position);
    
    float index1 = index_and_weight.r * 255;
    float index2 = index_and_weight.g * 255;
    float weight = index_and_weight.b;
    
    vec4 color1 = texture(u_texture_array, vec3(ground_uv, index1));
    vec4 color2 = texture(u_texture_array, vec3(ground_uv, index2));
    
    ALBEDO = mix(color1, color2, weight);
    

    The first downside I find so far is that you have to find out how to actually paint such a splatmap, because a constraint is that you cannot have a pixel of the ground that blends more than 2 textures. However, that can be largely enough if taken care of, and the texture array allows for up to 256 different textures, as long as your graphics card can handle it.

    I don't know if that helps, it's only theory, I have yet to actually try this out ;)

  • BadSadCoderBadSadCoder Posts: 6Member

    Maybe this will be more descriptive. Here's link to info about how it is done in Arma. I guess this whole different thing but... maybe this will be some help.
    https://community.bistudio.com/wiki/Layered_Terrain_Surface_Representation

    @Zylann said:
    I work on a terrain plugin and I've been thinking about this for a while.
    The approach I may try soon is to use a texture array, and sample a slice of that array in a shader based on the index of the texture in the splatmap (so it would not be colors like you said, but more like a specialized splatmap painted with a specific tool, although you could feed in such color textures and generate a proper splatmap from it).
    That kind of splatmap would be different from the classic RGBA=1234, instead it would be R=textureIndex1, G=textureIndex2, B=blendingFactor. Then in the shader, color could simply be calculated like this:

    // Not true code, only as example
    
    vec3 index_and_weight = texture(u_terrain_splatmap, cell_position);
    
    float index1 = index_and_weight.r * 255;
    float index2 = index_and_weight.g * 255;
    float weight = index_and_weight.b;
    
    vec4 color1 = texture(u_texture_array, vec3(ground_uv, index1));
    vec4 color2 = texture(u_texture_array, vec3(ground_uv, index2));
    
    ALBEDO = mix(color1, color2, weight);
    

    The first downside I find so far is that you have to find out how to actually paint such a splatmap, because a constraint is that you cannot have a pixel of the ground that blends more than 2 textures. However, that can be largely enough if taken care of, and the texture array allows for up to 256 different textures, as long as your graphics card can handle it.

    I don't know if that helps, it's only theory, I have yet to actually try this out ;)

  • ZylannZylann Posts: 31Member

    It doesnt seem like the Arma link describe how they actually render this internally. It mostly explains how to make a map from a user/modder point of view.

    In other news, I just made my idea work :D https://github.com/Zylann/godot_heightmap_plugin/issues/10#issuecomment-631078641

    Now I think what Arma does more likely is a variation of this technique, just with more indexes and more blend weights (see footnotes in the wiki page).

Leave a Comment

Rich Text Editor. To edit a paragraph's style, hit tab to get to the paragraph menu. From there you will be able to pick one style. Nothing defaults to paragraph. An inline formatting menu will show up when you select text. Hit tab to get into that menu. Some elements, such as rich link embeds, images, loading indicators, and error messages may get inserted into the editor. You may navigate to these using the arrow keys inside of the editor and delete them with the delete or backspace key.