Wrote a shader

This commit is contained in:
Florian 2025-09-16 00:19:40 +02:00
parent 774a74da04
commit 2274eab9e1
8 changed files with 113 additions and 9 deletions

27
building.gd Normal file
View file

@ -0,0 +1,27 @@
class_name Building extends Node2D
var location : Vector2i # x is the angle, y is the height in the grid
var dimension : Vector2i = Vector2.ONE # same as above
@onready var grid : Grid = get_parent()
# make sure location is set before adding a building to the scene tree
# also make sure that the buildings are instantiated as children of the grid
func _ready() -> void:
var angle = location.x * TAU / grid.num_collumns; # currently assumes anchor is bottom left
var height = grid.ground_radius + location.y * grid.cell_height;
position = height * Vector2.from_angle(angle)
print(angle, " ", height, " ", position)
func overlaps(other : Building):
# heights don't overlap
if location.y >= other.location.y + other.dimension.y: return false # other is below
if location.y + dimension.y <= other.location.y: return false # other is above
# angles overlap. We can now assume heights overlap
var relative_other_loc = (other.location.x - location.x + grid.num_collumns) % grid.num_collumns
if dimension.x > relative_other_loc: return true
if relative_other_loc + other.dimension > grid.num_collumns: return true
# If we get here, angles do not overlap
return false

1
building.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://b2ji03ekijjnn

34
building.gdshader Normal file
View file

@ -0,0 +1,34 @@
shader_type canvas_item;
uniform ivec2 location;
uniform ivec2 dimension = ivec2(1,1);
uniform float ground_height = 3000.;
uniform float cell_height = 300.;
uniform int num_cells = 60;
varying vec2 world_position;
void vertex()
{
world_position = (MODEL_MATRIX * vec4(VERTEX, 0.0, 1.0)).xy;
}
void fragment() {
float radius = sqrt(world_position.x * world_position.x + world_position.y * world_position.y);
float angle = atan(world_position.y, world_position.x);
float sample_y = 1. - ((radius - ground_height) / cell_height - float( location.y)) / float(dimension.y);
float sample_x = mod(fract(angle / TAU + 1.) * float(num_cells) - float(location.x) + float(num_cells), float(num_cells)) / float(dimension.x);
if(sample_y > 1. || sample_y < 0. || sample_x > 1. || sample_x < 0.) {
discard;
}
COLOR = texture(TEXTURE, vec2(sample_x, sample_y));
}
//void light() {
// // Called for every pixel for every light affecting the CanvasItem.
// // Uncomment to replace the default light processing function with this one.
//}

1
building.gdshader.uid Normal file
View file

@ -0,0 +1 @@
uid://c7gb1nqwvkr37

22
building.tscn Normal file
View file

@ -0,0 +1,22 @@
[gd_scene load_steps=5 format=3 uid="uid://djawvtdwp423v"]
[ext_resource type="Script" uid="uid://b2ji03ekijjnn" path="res://building.gd" id="1_5j34s"]
[ext_resource type="Texture2D" uid="uid://cy70quh6k3s1j" path="res://icon.svg" id="2_2yopf"]
[ext_resource type="Shader" uid="uid://c7gb1nqwvkr37" path="res://building.gdshader" id="2_f1gjg"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_qnfc1"]
resource_local_to_scene = true
shader = ExtResource("2_f1gjg")
shader_parameter/location = Vector2i(45, 0)
shader_parameter/dimension = Vector2i(1, 1)
shader_parameter/ground_height = 3000.0
shader_parameter/cell_height = 300.0
shader_parameter/num_cells = 60
[node name="Building" type="Node2D"]
script = ExtResource("1_5j34s")
[node name="Sprite2D" type="Sprite2D" parent="."]
material = SubResource("ShaderMaterial_qnfc1")
scale = Vector2(7, 7)
texture = ExtResource("2_2yopf")

View file

@ -1,4 +1,4 @@
extends Sprite2D
extends Node2D
@export var radius : float;
func _draw():

View file

@ -1,8 +1,8 @@
[gd_scene load_steps=5 format=3 uid="uid://33k5v6skcbsm"]
[ext_resource type="Texture2D" uid="uid://cy70quh6k3s1j" path="res://icon.svg" id="1_qbwya"]
[ext_resource type="Script" uid="uid://b5fhsy1xlreco" path="res://draw_circle.gd" id="2_2bhor"]
[ext_resource type="Script" uid="uid://m3vyyfk8gnma" path="res://grid.gd" id="3_2bhor"]
[ext_resource type="PackedScene" uid="uid://djawvtdwp423v" path="res://building.tscn" id="3_5i67w"]
[sub_resource type="CircleShape2D" id="CircleShape2D_5i67w"]
radius = 3000.0
@ -14,8 +14,7 @@ radius = 3000.0
[node name="CollisionShape2D" type="CollisionShape2D" parent="Ground"]
shape = SubResource("CircleShape2D_5i67w")
[node name="Sprite2D" type="Sprite2D" parent="Ground"]
texture = ExtResource("1_qbwya")
[node name="GroundVisual" type="Node2D" parent="Ground"]
script = ExtResource("2_2bhor")
radius = 3000.0
@ -29,3 +28,9 @@ cell_height = 300.0
num_collumns = 60
debug = true
metadata/_custom_type_script = "uid://m3vyyfk8gnma"
[node name="Building" parent="." instance=ExtResource("3_5i67w")]
position = Vector2(-5212, -1497)
[node name="Building2" parent="." instance=ExtResource("3_5i67w")]
position = Vector2(49, 25)

24
grid.gd
View file

@ -5,6 +5,8 @@ class_name Grid extends Node2D
@export var num_collumns : int
@export var debug : bool
var buildings : Array[Building] = []
func _draw() -> void:
if !debug:
return
@ -16,8 +18,20 @@ func _draw() -> void:
var angle = i * TAU / num_collumns;
draw_line(Vector2.ZERO, 10000 * Vector2.from_angle(angle), Color.SKY_BLUE);
#func cart_to_sphere(cart : Vector2):
#var x = cart.x; var y = cart.y;
#var radius = sqrt(x*x + y*y);
#var angle = tan(y/x)
## TODO
func add_building_to_collumn(building : Building, collumn : int):
# find the height of the top building in the buildings list:
building.location = Vector2(collumn, 0)
var height = 0
# TODO: support other dimensions for buildings
# add the new building one higher than the previous
height += 1
building.location = Vector2i(collumn, height);
# for testing
func _ready() -> void:
var packed : PackedScene = preload("res://building.tscn")
var test_building = packed.instantiate()
test_building.location = Vector2(45, 1)
add_child(test_building)