Hi there,

I share shader that blends textures based on vertex color. The example uses red vertex color to weight between two textures. Fell free to modify it for your needs adding more textures and using more vertex colors.

` shader_type spatial;

uniform float grassres = 10; uniform float rockres = 10;

uniform sampler2D grass; uniform sampler2D rock; uniform sampler2D grassN; uniform sampler2D rockN;

varying vec4 vertexColor;

void vertex() { vertexColor = COLOR; }

void fragment(){

vec3 grasstex = texture(grass, UVgrassres).rgb ; vec3 graaNtext = texture(grassN, UVgrassres).rgb ;

vec3 rocktex = texture(rock, UVrockres).rgb ; vec3 rockNtex = texture(rockN, UVrockres).rgb ;

float inverseMultiplier = 1.0 - vertexColor.r; inverseMultiplier = inverseMultiplier >0.01 ? inverseMultiplier : 0.01;

vec3 resultAlbedo = (grasstex inverseMultiplier) + (rocktexvertexColor.r);
ALBEDO = resultAlbedo;

vec3 resultNormal = (graaNtext inverseMultiplier) + (rockNtexvertexColor.r);

NORMAL = resultNormal;

ROUGHNESS =0.5;

} `

I need another shader able to blend textures based on vertex slope. Anyone knows how to get the angle from vertex normal ? using Dot ? @Megalomaniak perhaps ? ;)

Sure, assuming I understand what you want correctly this is the paper you are likely looking for: https://ir.canterbury.ac.nz/bitstream/handle/10092/14845/hons_0801.pdf

PoC code:

shader_type spatial;

uniform sampler2D textureA;
uniform sampler2D textureB;
varying float slopeGradient;

void vertex(){
	vec3 worldNormal = vec3(0.0, 1.0, 0.0);
	slopeGradient = dot(vec4(vec4(worldNormal, 1.0) * WORLD_MATRIX).xyz, NORMAL);
}

void fragment(){
	ALBEDO = mix(texture(textureA, UV, 0.0).rgb, texture(textureB, UV, 0.0).rgb, slopeGradient * 2.0);
}

@Megalomaniak said: Sure, assuming I understand what you want correctly this is the paper you are likely looking for: https://ir.canterbury.ac.nz/bitstream/handle/10092/14845/hons_0801.pdf

PoC code:

shader_type spatial;

uniform sampler2D textureA;
uniform sampler2D textureB;
varying float slopeGradient;

void vertex(){
	vec3 worldNormal = vec3(0.0, 1.0, 0.0);
	slopeGradient = dot(vec4(vec4(worldNormal, 1.0) * WORLD_MATRIX).xyz, NORMAL);
}

void fragment(){
	ALBEDO = mix(texture(textureA, UV, 0.0).rgb, texture(textureB, UV, 0.0).rgb, slopeGradient * 2.0);
}

Thank you so much.

4 days later

I did some work to get better texture mix with clamp to avoid colors saturation.

shader_type spatial;

uniform float textureRes = 10;
uniform float slopeMult = 2.0;

uniform sampler2D textureA;
uniform sampler2D textureB;

uniform sampler2D textureAN;
uniform sampler2D textureBN;

varying float slopeGradient;

void vertex(){
    vec3 worldNormal = vec3(0.0, 1.0, 0.0);
    slopeGradient = dot(vec4(vec4(worldNormal, 1.0) * WORLD_MATRIX).xyz, NORMAL);		
}
void fragment(){
    
    vec3 D1 = texture(textureA, UV * textureRes).rgb;
    vec3 D2 = texture(textureB, UV * textureRes).rgb;
    
    vec3 D1N = texture(textureAN, UV * textureRes).rgb;
    vec3 D2N = texture(textureBN, UV * textureRes).rgb;
    
    float newSlope = clamp(slopeGradient*2.0,0.0, 1.0); 
    
    vec3 DValue = mix(D1,D2,newSlope);
    ALBEDO = DValue;
    
    vec3 NValue = normalize(mix(D1N,D2N,newSlope));  
    NORMALMAP = NValue;
      
    ROUGHNESS = 0.5; 
}

Vertex and slope textures blending shaders are available on GitHub

https://github.com/DevMagicLord/Godot3

5 years later