78 lines
3.2 KiB
GDScript
78 lines
3.2 KiB
GDScript
extends SceneTree
|
|
const EffectPlayer = preload("res://fx/effect_player.gd")
|
|
var failures := 0
|
|
func check(ok: bool, label: String) -> void:
|
|
if not ok:
|
|
failures += 1
|
|
printerr("FAIL: " + label)
|
|
func _init() -> void:
|
|
call_deferred("run")
|
|
func run() -> void:
|
|
var image := Image.create(2, 2, false, Image.FORMAT_RGBA8)
|
|
image.fill(Color.WHITE)
|
|
var texture := ImageTexture.create_from_image(image)
|
|
var fx := EffectPlayer.new()
|
|
fx.build({"particles": [{"particle": {"BillboardType": 0, "SrcBlendType": 5, "DestBlendType": 6}}]})
|
|
var particle_mat: StandardMaterial3D = fx._emitters[0].material_override
|
|
# A plain white texture and a static quad isolate material face visibility.
|
|
particle_mat.albedo_texture = texture
|
|
var materials := [particle_mat, fx._mesh_material({"BlendingSrcType": 5, "BlendingDestType": 6}, [texture])]
|
|
for i in materials.size():
|
|
check(materials[i].cull_mode == BaseMaterial3D.CULL_DISABLED, "effect material %d is two-sided" % i)
|
|
check(materials[i].depth_draw_mode == BaseMaterial3D.DEPTH_DRAW_DISABLED, "effect material %d does not write depth" % i)
|
|
check(not materials[i].no_depth_test, "effect material %d still tests world depth" % i)
|
|
if DisplayServer.get_name() != "headless":
|
|
materials.append(preload("res://fx/particle_color_material.gd").build(particle_mat, 5))
|
|
materials.append(preload("res://fx/particle_color_material.gd").build(particle_mat, 6))
|
|
await visual(materials)
|
|
else:
|
|
print("SKIP: pixel checks require a rendering backend")
|
|
fx.free()
|
|
print("effect_surface_test: failures=%d" % failures)
|
|
quit(1 if failures else 0)
|
|
func visual(materials: Array) -> void:
|
|
var viewport := SubViewport.new()
|
|
viewport.size = Vector2i(96, 96)
|
|
viewport.own_world_3d = true
|
|
viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS
|
|
root.add_child(viewport)
|
|
var environment := WorldEnvironment.new()
|
|
environment.environment = Environment.new()
|
|
environment.environment.background_mode = Environment.BG_COLOR
|
|
environment.environment.background_color = Color.BLACK
|
|
viewport.add_child(environment)
|
|
var quad := MeshInstance3D.new()
|
|
quad.mesh = QuadMesh.new()
|
|
quad.mesh.size = Vector2(2, 2)
|
|
viewport.add_child(quad)
|
|
var camera := Camera3D.new()
|
|
viewport.add_child(camera)
|
|
camera.current = true
|
|
var blocker := MeshInstance3D.new()
|
|
blocker.mesh = BoxMesh.new()
|
|
blocker.mesh.size = Vector3(2, 2, 0.1)
|
|
var black := StandardMaterial3D.new()
|
|
black.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
|
black.albedo_color = Color.BLACK
|
|
blocker.material_override = black
|
|
viewport.add_child(blocker)
|
|
for i in materials.size():
|
|
quad.material_override = materials[i]
|
|
for side in [1.0, -1.0]:
|
|
camera.position = Vector3(0, 0, side * 3.0)
|
|
camera.look_at(Vector3.ZERO)
|
|
blocker.visible = false
|
|
var color: Color = await center(viewport)
|
|
check(color.r > 0.8, "material %d side %d visible pixel=%s" % [i, int(side), color])
|
|
blocker.position = Vector3(0, 0, side)
|
|
blocker.visible = true
|
|
color = await center(viewport)
|
|
check(color.r < 0.05, "material %d side %d occluded by world" % [i, int(side)])
|
|
viewport.queue_free()
|
|
await process_frame
|
|
func center(viewport: SubViewport) -> Color:
|
|
await process_frame
|
|
await process_frame
|
|
await RenderingServer.frame_post_draw
|
|
return viewport.get_texture().get_image().get_pixel(48, 48)
|