Yeah, makes sense. I'm starting to wonder if it is a problem with the decal shader trying to scale the viewport texture onto the decal mesh before the texture exists, since it is being generated live.
Here is the shader code from the decal plugin https://github.com/Mr-Slurpy/Screen-Space-Decals
shader_type spatial;
shader_type spatial;
render_mode unshaded, depth_draw_never, cull_front, depth_test_disable;
uniform sampler2D decal : hint_black;
uniform vec2 offset;
uniform vec2 scale;
uniform bool emulate_lighting;
uniform float brightness;
void fragment(){
//float zdepth = textureLod(DEPTH_TEXTURE, SCREEN_UV, 0.0).r * 2.0 - 1.0;
vec4 pos = inverse(WORLD_MATRIX) * inverse(INV_CAMERA_MATRIX) * INV_PROJECTION_MATRIX * vec4(SCREEN_UV * 2.0 - 1.0, textureLod(DEPTH_TEXTURE, SCREEN_UV, 0.0).r * 2.0 - 1.0, 1.0);
pos.xyz /= pos.w;
bool inside = all(greaterThanEqual(pos.xyz, vec3(-1.0))) && all(lessThanEqual(pos.xyz, vec3(1.0)));
if(inside){
vec4 color = texture(decal, (pos.xy * -0.5 - 0.5) * scale + offset);
if(emulate_lighting){
float lum = dot(textureLod(SCREEN_TEXTURE, SCREEN_UV, 0).rgb, vec3(0.2125, 0.7154, 0.0721));
lum += brightness;
lum = clamp(lum, 0.0, 1.0);
ALBEDO = color.rgb * lum;
}else{
ALBEDO = color.rgb;
}
ALPHA = color.a;
}else{
discard;
}
}
Also the decal.gd script:
tool
extends MeshInstance
const SHADER = preload("decal.shader")
export(Texture) var decal setget set_decal
export(Vector2) var uv_offset = Vector2() setget set_uv_offset
export(Vector2) var uv_scale = Vector2(1, 1) setget set_uv_scale
export(bool) var emulate_lighting = true setget set_emulate_lighting
export(float, -100.0, 100.0) var brightness = 0.0 setget set_brightness
func _init():
mesh = CubeMesh.new()
mesh.material = ShaderMaterial.new()
mesh.material.shader = SHADER
func set_decal(new_decal):
decal = new_decal
mesh.material.set_shader_param("decal", decal)
func set_uv_offset(new_offset):
uv_offset = new_offset
mesh.material.set_shader_param("offset", uv_offset)
func set_uv_scale(new_scale):
uv_scale = new_scale
mesh.material.set_shader_param("scale", uv_scale)
func set_emulate_lighting(new_value):
emulate_lighting = new_value
mesh.material.set_shader_param("emulate_lighting", emulate_lighting)
func set_brightness(new_brightness):
brightness = new_brightness
mesh.material.set_shader_param("brightness", brightness * 0.01)