Hi there,

I tried the Spatial material and it's detail texture, and i'm disappointed so i made one.

Left is a correct detail texture custom shader, right is Spatial material default detail texture.

The albedo color doesn't mix well whatever you choose "Mix" or "Add" modes, base normal map is almost no more visible overriden by detail normal map, and detail texture uses the same UV scale as the base texture.

I added two parameters to the shader code :

  • Detail texture multiplier input number for UV otherwise it's not a detail texture
  • Input number to specify the strength of the normal map over the detail normal map

This is the correct one code :


shader_type spatial;

uniform float tex1res = 1;
uniform float tex2res = 10;
uniform sampler2D tex1Albedo;
uniform sampler2D tex1Normal;
uniform sampler2D tex2Albedo;
uniform sampler2D tex2Normal;

varying vec4 vertexColor; 
varying vec3 vertexNormal; 

void vertex() {
	vertexColor = COLOR; // make the normal the color
	vertexNormal = NORMAL;
}

void fragment() {
    vec3 a1 = texture(tex1Albedo, UV * tex1res).rgb;
    vec3 n1 = texture(tex1Normal, UV * tex1res).rgb;
    vec3 a2 = texture(tex2Albedo, UV * tex2res).rgb;
    vec3 n2 = texture(tex2Normal, UV * tex2res).rgb;
	
	vec3 resultAlbedo = mix( a1 , a2, 0.5); 
    ALBEDO =  resultAlbedo;

	vec3 addNormals = mix(n1 *1.8,n2,0.5 );		
    vec3 nResult = normalize(addNormals);
    NORMALMAP = nResult;
	
    ROUGHNESS = 0.5;
}

GitHub link https://github.com/DevMagicLord/Godot3/tree/master/shaders/Detail%20Texture

I tried it on a model with complex seams, the detail shader doesn't work well. Using a Spatial Material the albedo and normal (without detail maps) render pretty well.

I tried mix() without multipliers and using a 0.5 for mix value ; but it's same seams issues. Any ideas ?

How it should render

You need the use the little 'hint' keywords to make textures work properly.

So you might have...

uniform sampler2D albedo_texture : hint_albedo;
uniform sampler2D detail_texture : hint_albedo;
uniform sampler2D normal_texture : hint_normal;

I'm not entirely sure if the detail texture also needs the hint, I would think at worse you wouldn't need it.

@Ace Dragon said: You need the use the little 'hint' keywords to make textures work properly.

So you might have...

uniform sampler2D albedo_texture : hint_albedo;
uniform sampler2D detail_texture : hint_albedo;
uniform sampler2D normal_texture : hint_normal;

I'm not entirely sure if the detail texture also needs the hint, I would think at worse you wouldn't need it.

uniform sampler2D tex1Albedo : hint_albedo; uniform sampler2D tex1Normal: hint_normal; uniform sampler2D tex2Albedo : hint_albedo; uniform sampler2D tex2Normal: hint_normal;

It fixed the color, but seams also break lighting

I uploaded the model and textures, anyone can give it a try.

https://github.com/DevMagicLord/Godot3/tree/master/shaders/Detail%20Texture

The correct way

vec3 addNormals = n1 *0.5 + n2 *0.5 ; NORMALMAP = clamp(addNormals,0,1);

The shader with albedo correct :

shader_type spatial; 
uniform float texDetailRes = 10;
uniform sampler2D tex1Albedo : hint_albedo;
uniform sampler2D tex1Normal: hint_normal;
uniform sampler2D tex2Albedo : hint_albedo;
uniform sampler2D tex2Normal: hint_normal;
void fragment() {
    vec3 a1 = texture(tex1Albedo, UV ).rgb;
    vec3 n1 = texture(tex1Normal, UV ).rgb;
    vec3 a2 = texture(tex2Albedo, UV * texDetailRes).rgb;
    vec3 n2 = texture(tex2Normal, UV * texDetailRes).rgb;
	
	vec3 albedoAdd = a1 + a2; 
	vec3 resultAlbedo = clamp(albedoAdd,0,1);
            ALBEDO =  resultAlbedo;
 

	vec3 addNormals = n1 *0.5 + n2 *0.5 ;		 
            NORMALMAP = clamp(addNormals,0,1);
	


    ROUGHNESS = 0.5;
}

I'm not great at shaders, perhaps some people will be able to do something closer to the reference detail texture.

Yea, you can't just add normals together and divide by half to get a new normal. You just have to sum them and normalize that to get a new unit vector normal.

i.e.

NORMALMAP = normalize(mix(n1, n2, 0.5));

that will combine them at 50% and give you a proper normalized unit vector that can be subsequently used for lighting calculations.

Even the original shader you started with did that, you just weren't using a mask that was mixing them the amount you wanted. Your textures don't even look like they're the same as your 'reference', they look like rougher approximations reproduced procedurally.

@deftware said: Yea, you can't just add normals together and divide by half to get a new normal. You just have to sum them and normalize that to get a new unit vector normal.

i.e.

NORMALMAP = normalize(mix(n1, n2, 0.5));

that will combine them at 50% and give you a proper normalized unit vector that can be subsequently used for lighting calculations.

Even the original shader you started with did that, you just weren't using a mask that was mixing them the amount you wanted. Your textures don't even look like they're the same as your 'reference', they look like rougher approximations reproduced procedurally.

On screenshot left is shader with mix right is shader with addition

Shader with addition looks correct and produces same shadowing as others objects spatial material, while mix produces a different shadowing.

vec3 addNormals = n1 *0.5 + n2 *0.5 ; NORMALMAP = clamp(addNormals,0,1);

Write a Reply...