Skip to content

Instantly share code, notes, and snippets.

@PierceLBrooks
Last active April 3, 2023 22:27
Show Gist options
  • Save PierceLBrooks/1f5367a4fab05649b29b48f280ca2d66 to your computer and use it in GitHub Desktop.
Save PierceLBrooks/1f5367a4fab05649b29b48f280ca2d66 to your computer and use it in GitHub Desktop.
extends VisualInstance3D
var subworld : World3D = null
var subviewport : SubViewport = null
var texture : ViewportTexture = null
var billboard : Sprite3D = null
var clone : VisualInstance3D = null
var camera : Camera3D = null
var directions = []
var angles = """
[
[0.0, 0.447509765625, 0.0],
[0.0, -0.447509765625, 0.0],
[0.447509765625, 0.0, 0.0],
[-0.447509765625, 0.0, 0.0],
[0.0, 0.0, 0.447509765625],
[0.0, 0.0, -0.447509765625],
[0.3134765625, 0.3134765625, 0.0],
[0.3134765625, -0.3134765625, 0.0],
[-0.3134765625, 0.3134765625, 0.0],
[-0.3134765625, -0.3134765625, 0.0],
[0.0, 0.3134765625, 0.3134765625],
[0.0, -0.3134765625, 0.3134765625],
[0.3134765625, 0.0, 0.3134765625],
[-0.3134765625, 0.0, 0.3134765625],
[0.0, 0.3134765625, -0.3134765625],
[0.0, -0.3134765625, -0.3134765625],
[0.3134765625, 0.0, -0.3134765625],
[-0.3134765625, 0.0, -0.3134765625],
[0.140625, 0.427734375, 0.0],
[0.427734375, 0.140625, 0.0],
[0.140625, -0.427734375, 0.0],
[0.427734375, -0.140625, 0.0],
[-0.140625, 0.427734375, 0.0],
[-0.427734375, 0.140625, 0.0],
[-0.140625, -0.427734375, 0.0],
[-0.427734375, -0.140625, 0.0],
[0.0, 0.427734375, 0.140625],
[0.0, 0.140625, 0.427734375],
[0.1875, 0.345703125, 0.1875],
[-0.1875, 0.345703125, 0.1875],
[0.0, -0.427734375, 0.140625],
[0.0, -0.140625, 0.427734375],
[0.1875, -0.345703125, 0.1875],
[-0.1875, -0.345703125, 0.1875],
[0.427734375, 0.0, 0.140625],
[0.140625, 0.0, 0.427734375],
[0.345703125, 0.1875, 0.1875],
[0.345703125, -0.1875, 0.1875],
[0.1875, 0.1875, 0.345703125],
[0.1875, -0.1875, 0.345703125],
[-0.427734375, 0.0, 0.140625],
[-0.140625, 0.0, 0.427734375],
[-0.345703125, 0.1875, 0.1875],
[-0.345703125, -0.1875, 0.1875],
[-0.1875, 0.1875, 0.345703125],
[-0.1875, -0.1875, 0.345703125],
[0.0, 0.427734375, -0.140625],
[0.0, 0.140625, -0.427734375],
[0.1875, 0.345703125, -0.1875],
[-0.1875, 0.345703125, -0.1875],
[0.0, -0.427734375, -0.140625],
[0.0, -0.140625, -0.427734375],
[0.1875, -0.345703125, -0.1875],
[-0.1875, -0.345703125, -0.1875],
[0.427734375, 0.0, -0.140625],
[0.140625, 0.0, -0.427734375],
[0.345703125, 0.1875, -0.1875],
[0.345703125, -0.1875, -0.1875],
[0.1875, 0.1875, -0.345703125],
[0.1875, -0.1875, -0.345703125],
[-0.427734375, 0.0, -0.140625],
[-0.140625, 0.0, -0.427734375],
[-0.345703125, 0.1875, -0.1875],
[-0.345703125, -0.1875, -0.1875],
[-0.1875, 0.1875, -0.345703125],
[-0.1875, -0.1875, -0.345703125]
]
"""
@export var observer : Node3D = null
@export var size : Vector2i = Vector2i(640, 640)
@export var distance : float = 10.0
@export_range(1, 20) var layer : int = 20
func get_descendants(node : Node):
var descendants = []
for child in node.get_children():
var grandchildren = get_descendants(child)
descendants.append(child)
descendants += grandchildren
return descendants
# Called when the node enters the scene tree for the first time.
func _ready():
if (observer == null):
return
var json = JSON.parse_string(angles.strip_edges())
for i in range(len(json)):
var direction = json[i]
if (len(direction) < 3):
continue
directions.append(Vector3(direction[0], direction[1], direction[2]).normalized())
subworld = World3D.new()
subviewport = SubViewport.new()
subviewport.world_3d = subworld
subviewport.size = size
subviewport.transparent_bg = true
#subviewport.render_target_clear_mode = SubViewport.CLEAR_MODE_ALWAYS
#subviewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS
texture = ViewportTexture.new()
billboard = Sprite3D.new()
billboard.flip_h = true
billboard.set_name(name+"_billboard")
camera = Camera3D.new()
camera.set_name(name+"_camera")
for i in range(20):
billboard.set_layer_mask_value(i+1, get_layer_mask_value(i+1))
camera.set_cull_mask_value(i+1, false)
set_layer_mask_value(i+1, false)
var descendants = get_descendants(self)
for descendant in descendants:
if (is_instance_of(descendant, Light3D)):
descendant.set_layer_mask_value(layer, true)
camera.set_cull_mask_value(layer, true)
set_layer_mask_value(layer, true)
add_child(subviewport)
subviewport.add_child(camera)
clone = duplicate()
clone.set_name(name+"_clone")
clone.set_script(null)
subviewport.add_child(clone)
texture.set_viewport_path_in_scene(get_tree().root.get_path_to(subviewport))
#await RenderingServer.frame_post_draw
billboard.texture = subviewport.get_texture()
billboard.transparent = true
add_child(billboard)
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
#position += Vector3(randf()-0.5, 0.0, randf()-0.5)*delta*PI
#rotate(Vector3(0.0, 1.0, 0.0), (randf()-0.5)*delta*PI*PI*PI)
if (billboard == null):
return
if (observer != null):
var index = -1
var dot = -1.0
var direction = (observer.position-position).normalized()
for i in range(len(directions)):
var temp = direction.dot(directions[i])
if ((index < 0) || (temp > dot)):
dot = temp
index = i
if (index > -1):
direction = directions[index]
if (direction.dot(Vector3(0.0, 1.0, 0.0)) < 0.999):
billboard.look_at(observer.position)
camera.position = direction*distance
camera.look_at(Vector3())
if (clone != null):
var angle = deg_to_rad(rotation.y)
index = -1
dot = -1.0
direction = Vector3(cos(angle), 0.0, sin(angle))
for i in range(len(directions)):
var temp = direction.dot(directions[i])
if ((index < 0) || (temp > dot)):
dot = temp
index = i
if (index > -1):
direction = directions[index]
if (direction.dot(Vector3(0.0, 1.0, 0.0)) < 0.999):
clone.look_at(direction)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment