Godot Version
4.3
Question
I’m developing a 3D painting tool in Godot 4 using the PaintableContainer and PaintHead scripts. I have set up a simple cube mesh in PaintableContainer and a decal system in PaintHead, but the decals are not appearing as expected when I attempt to paint on the mesh.
Here’s a brief overview of my setup:
PaintableContainer.gd:
@tool
extends Node3D
class_name PaintableContainer
@export var texture_size: Vector2 = Vector2(1024, 1024)
var target_mesh: MeshInstance3D
func _ready():
setup_test_mesh()
func setup_test_mesh():
target_mesh = MeshInstance3D.new()
var cube_mesh = BoxMesh.new()
target_mesh.mesh = cube_mesh
add_child(target_mesh)
setup_material(target_mesh)
setup_collision(target_mesh)
func setup_material(mesh_instance: MeshInstance3D):
var material = StandardMaterial3D.new()
material.albedo_color = Color(1, 1, 1, 1)
material.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
mesh_instance.material_override = material
func setup_collision(mesh_instance: MeshInstance3D):
var static_body = StaticBody3D.new()
var collision_shape = CollisionShape3D.new()
var shape = mesh_instance.mesh.create_trimesh_shape()
collision_shape.shape = shape
static_body.add_child(collision_shape)
mesh_instance.add_child(static_body)
PaintHead.gd:
@tool
extends Node3D
class_name PaintHead
@export var decal_size: float = 1
@export var paint_color: Color = Color.RED
var decal: Decal
var mesh_instance: MeshInstance3D
func _ready():
setup_paint_head()
func setup_paint_head():
var color_texture = ImageTexture.new()
var image = Image.create(1, 1, false, Image.FORMAT_RGBA8)
image.set_pixel(0, 0, paint_color)
color_texture.create_from_image(image)
mesh_instance = MeshInstance3D.new()
var mesh = CylinderMesh.new()
mesh_instance.mesh = mesh
add_child(mesh_instance)
decal = Decal.new()
decal.texture_albedo = preload("res://icon.svg")
decal.modulate = paint_color
add_child(decal)
func _process(_delta):
if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
update_paint_position()
func update_paint_position():
var mouse_pos = get_viewport().get_mouse_position()
var camera = get_viewport().get_camera_3d()
if camera:
var from = camera.project_ray_origin(mouse_pos)
var to = from + camera.project_ray_normal(mouse_pos) * 1000
var space_state = get_world_3d().direct_space_state
var result = space_state.intersect_ray(from, to)
if result:
decal.global_transform.origin = result.position
decal.look_at(result.position + result.normal, Vector3.UP)
Key Issues:
The decals do not appear on the cube mesh when I click to paint.
I have implemented raycasting to detect the mesh surface, and I see debug output confirming hit positions, but the decals remain invisible.
What I’ve checked:
Verified that the collision shape matches the mesh.
Ensured that the decal’s layer matches the mesh’s layer.
Printed various debug information, including decal orientation and layer settings.
Questions:
Are there specific settings or configurations I might be missing that could affect decal visibility?
Is there a common issue with decals not rendering on custom meshes that I should be aware of?
I would appreciate any guidance or suggestions to help resolve this issue. Thank you!