Shaders [SOLVED] Textures in shader: One doesn't get filter and mip and another doesn't show up

Kentae

Member
Game Maker Version: Game Maker Studio 2.3.0.529
Platform: Windows 10

Hi, I have a problem with a shader I am writing for blending textures on 3D terrains.
I have actually found 2 problems.
The first is that one of the textures that I pass to the shader does not seem to be affected by texture filtering or mip mapping but all the others are.
This makes that one texture stand out quite a lot.
The other problem is that one of the textures does not show up properly. The parts of the model that should have the texture appaer as sort of a median colour of the texture. (see the image below)

Texture_Help.jpg
The green areas in the image should be a grass texture.
The brick texture is the one that doesn't seem to be affected by filtering or mip mapping, allthough I'm not sure how well it's visible in this image.

I have tried enabling the filtering and mip mapping specificly for that one texture using the extended GPU functions but it doesn't help, not even if I turn of filtering and mip mapping for all the others first.
I have also tried rearranging the order in wich the textures are passed in to the shader but that does not help either.

As for the other issue of the texture that doesn't show properly, I'm guessing it has to do with the limits of texture slots for a shader.
It says in the documentation that I should have up to 8 slots available and I am currently using exactly that, 8 slots (including the gm_BaseTexture).
You might count only 7 different textures in the image above but that's because the last on is a blendMap that isn't directly shown but rather it determines wich texture should show where.

Here is my current code.
Create Event:
GML:
u_terrain_tiles = shader_get_uniform( sh_terrain, "tiles" );

u_terrain_base = shader_get_sampler_index( sh_terrain, "texBase" );
u_terrain_tex1 = shader_get_sampler_index( sh_terrain, "tex1" );
u_terrain_tex2 = shader_get_sampler_index( sh_terrain, "tex2" );
u_terrain_tex3 = shader_get_sampler_index( sh_terrain, "tex3" );
u_terrain_tex4 = shader_get_sampler_index( sh_terrain, "tex4" );
u_terrain_tex5 = shader_get_sampler_index( sh_terrain, "tex5" );
u_terrain_tex6 = shader_get_sampler_index( sh_terrain, "tex6" );
Draw Code:
GML:
shader_set( sh_terrain );

shader_set_uniform_f( u_terrain_tiles, 128.0 );

texture_set_stage( u_terrain_base, sprite_get_texture( Grass, 0 ) );
texture_set_stage( u_terrain_tex1, sprite_get_texture( Stone, 0 ) );
texture_set_stage( u_terrain_tex2, sprite_get_texture( Dirt, 0 ) );
texture_set_stage( u_terrain_tex3, sprite_get_texture( Sand, 0 ) );
texture_set_stage( u_terrain_tex4, sprite_get_texture( Snow, 0 ) );
texture_set_stage( u_terrain_tex5, sprite_get_texture( Road, 0 ) );
texture_set_stage( u_terrain_tex6, sprite_get_texture( tex_brick, 0 ) );

vertex_submit( model_world, pr_trianglelist, sprite_get_texture( blendMap01, 0 ) );

shader_reset();
Shader Code:
GML:
varying vec3 v_vNormal;
varying vec2 v_vTexcoord;
varying vec4 v_vColour;

// MULTITEXTURE:
// Get the amount of tiles.
uniform float tiles;

// Get the blendmap and textures.
uniform sampler2D texBase;
uniform sampler2D tex1;
uniform sampler2D tex2;
uniform sampler2D tex3;
uniform sampler2D tex4;
uniform sampler2D tex5;
uniform sampler2D tex6;

void main()
{
    // ------------------------------------------------------------ MULTITEXTURE
    
    // Get the tiled textrue coordinates.
    vec2 tiledCoords = v_vTexcoord * tiles;
    
    // Get the blendmap colour.
    vec4 blendMapCol = texture2D( gm_BaseTexture, vec2( v_vTexcoord.x * 0.5, v_vTexcoord.y ) );
    vec4 blendMapCol2 = texture2D( gm_BaseTexture, vec2( v_vTexcoord.x * 0.5 + 0.5, v_vTexcoord.y ) );
    
    // Get the colour of the other textures.
    vec4 texBase = texture2D( texBase, tiledCoords );
    vec4 tex1Col = texture2D( tex1, tiledCoords );
    vec4 tex2Col = texture2D( tex2, tiledCoords );
    vec4 tex3Col = texture2D( tex3, tiledCoords );
    vec4 tex4Col = texture2D( tex4, tiledCoords );
    vec4 tex5Col = texture2D( tex5, tiledCoords );
    vec4 tex6Col = texture2D( tex6, tiledCoords );
    
    // Create a 4-component vector to use for the final colour.
    vec4 finalCol = vec4( 0. );
    
    // Mix the colours of the textures using the blendmap's RGBA as the factor.
    finalCol = mix( texBase, tex1Col, blendMapCol.r );
    finalCol = mix( finalCol, tex2Col, blendMapCol.g );
    finalCol = mix( finalCol, tex3Col, blendMapCol.b );
    
    finalCol = mix( finalCol, tex4Col, blendMapCol2.r );
    finalCol = mix( finalCol, tex5Col, blendMapCol2.g );
    finalCol = mix( finalCol, tex6Col, blendMapCol2.b );
Any and all help is greatly appreciated ^^ Thank you
 

Bart

WiseBart
Did you enable texture filtering for each of the samplers/textures using gpu_set_texfilter_ext?
If I'm not mistaken, gpu_set_texfilter only sets the filtering for the first texture slot, which is always gm_BaseTexture.
Not sure but a similar thing may be going on with your second issue. It looks as if the texture is stretched.
Did you turn on texture repeating using gpu_set_texrepeat_ext? And are the uv's within the 0-1 range?
 

Kentae

Member
@Bart At first I only used gpu_set_texfilter() and it worked on all textures except the one with the issue. I have now tried setting the filter, mip mapping and repeating for every texture indiviually and it still doesn't work.
I find this really weird and I'm starting to think that it may be an actual bug in GM but I wont submit it until I'm completley sure of that.
 

Bart

WiseBart
Ah yes, okay. Then I don't see what could be wrong with that bricks texture.
There's something about that grass texture, though: there's both a sampler2D texBase and a vec4 texBase in the code.
That seems a bit odd.
 

Kentae

Member
There's something about that grass texture, though: there's both a sampler2D texBase and a vec4 texBase in the code.
Yes I noticed that a few minutes ago and fixed it but somehow it did not fix the actual problem : /
I have been able to verify now that the grass texture is being passed in though, it's just not getting repeated for whatever reason.
 

Kentae

Member
I seem to have been able to solve both problems now.
I am however affraid that this fix may be specific to my computer.
In other words, I believe the problem may come up again if I ever ran the project on another computer.

The problem where one texture didn't get the gpu settings applied was fixed by going into the "Main"-tab of the Game Options and ticking the box for "Generate mipmaps for separate texture pages".
I didn't even know this was an option until today.

The next problem where the texture didn't get repeated is the one I think may vary from computer to computer.
I noticed that it was specifically texture slot number 7 (on a range from 0-7), so in other words, the last slot, that didn't get repeated.
So I simply passed the blendmap into this slot since that texture doesn't ever need to be repeated.
The thing is though, it seems that the slots are assigned a bit randomly. I drew out the texture slots for each texture to the screen.
Doing so told me that the first texture that I pass into the shader, in my code that is, gets assigned to slot 7.
Then all the others go in order from 1-6. Slot 0 obviously being reserved by GM as default.
I'm obviously not sure about this but I don't think this is always the way the slots will be assigned but on my computer it works.

I'll mark the topic as solved but I think I may end up with more problems later on hehe.
 
Top