Initial commit
This commit is contained in:
commit
9a144705f5
|
@ -0,0 +1,7 @@
|
||||||
|
# Normalize EOL for all files that Git considers text files.
|
||||||
|
* text=auto eol=lf
|
||||||
|
# LFS files.
|
||||||
|
*.png filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.ttf filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.scn filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.res filter=lfs diff=lfs merge=lfs -text
|
|
@ -0,0 +1,2 @@
|
||||||
|
# Godot 4+ specific ignores
|
||||||
|
.godot/
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,79 @@
|
||||||
|
[preset.0]
|
||||||
|
|
||||||
|
name="Windows Desktop"
|
||||||
|
platform="Windows Desktop"
|
||||||
|
runnable=true
|
||||||
|
custom_features=""
|
||||||
|
export_filter="all_resources"
|
||||||
|
include_filter=""
|
||||||
|
exclude_filter=""
|
||||||
|
export_path="../../../Protectorate.exe"
|
||||||
|
encryption_include_filters=""
|
||||||
|
encryption_exclude_filters=""
|
||||||
|
encrypt_pck=false
|
||||||
|
encrypt_directory=false
|
||||||
|
script_export_mode=1
|
||||||
|
script_encryption_key=""
|
||||||
|
|
||||||
|
[preset.0.options]
|
||||||
|
|
||||||
|
custom_template/debug=""
|
||||||
|
custom_template/release=""
|
||||||
|
debug/export_console_script=1
|
||||||
|
binary_format/embed_pck=true
|
||||||
|
texture_format/bptc=false
|
||||||
|
texture_format/s3tc=true
|
||||||
|
texture_format/etc=false
|
||||||
|
texture_format/etc2=false
|
||||||
|
texture_format/no_bptc_fallbacks=true
|
||||||
|
binary_format/architecture="x86_64"
|
||||||
|
codesign/enable=false
|
||||||
|
codesign/identity_type=0
|
||||||
|
codesign/identity=""
|
||||||
|
codesign/password=""
|
||||||
|
codesign/timestamp=true
|
||||||
|
codesign/timestamp_server_url=""
|
||||||
|
codesign/digest_algorithm=1
|
||||||
|
codesign/description=""
|
||||||
|
codesign/custom_options=PackedStringArray()
|
||||||
|
application/modify_resources=true
|
||||||
|
application/icon=""
|
||||||
|
application/console_wrapper_icon=""
|
||||||
|
application/icon_interpolation=4
|
||||||
|
application/file_version=""
|
||||||
|
application/product_version=""
|
||||||
|
application/company_name=""
|
||||||
|
application/product_name=""
|
||||||
|
application/file_description=""
|
||||||
|
application/copyright=""
|
||||||
|
application/trademarks=""
|
||||||
|
|
||||||
|
[preset.1]
|
||||||
|
|
||||||
|
name="Linux/X11"
|
||||||
|
platform="Linux/X11"
|
||||||
|
runnable=true
|
||||||
|
custom_features=""
|
||||||
|
export_filter="all_resources"
|
||||||
|
include_filter=""
|
||||||
|
exclude_filter=""
|
||||||
|
export_path="../../../Protectorate.x86_64"
|
||||||
|
encryption_include_filters=""
|
||||||
|
encryption_exclude_filters=""
|
||||||
|
encrypt_pck=false
|
||||||
|
encrypt_directory=false
|
||||||
|
script_export_mode=1
|
||||||
|
script_encryption_key=""
|
||||||
|
|
||||||
|
[preset.1.options]
|
||||||
|
|
||||||
|
custom_template/debug=""
|
||||||
|
custom_template/release=""
|
||||||
|
debug/export_console_script=1
|
||||||
|
binary_format/embed_pck=true
|
||||||
|
texture_format/bptc=false
|
||||||
|
texture_format/s3tc=true
|
||||||
|
texture_format/etc=false
|
||||||
|
texture_format/etc2=false
|
||||||
|
texture_format/no_bptc_fallbacks=true
|
||||||
|
binary_format/architecture="x86_64"
|
|
@ -0,0 +1,36 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bqih4uf556hba"
|
||||||
|
path.s3tc="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc", "etc2"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://icon.png"
|
||||||
|
dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.s3tc.ctex", "res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.etc2.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=2
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/bptc_ldr=0
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=0
|
Binary file not shown.
|
@ -0,0 +1,33 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="font_data_dynamic"
|
||||||
|
type="FontFile"
|
||||||
|
uid="uid://d0yr073mjcs68"
|
||||||
|
path="res://.godot/imported/immortal.ttf-1429e0fa3f3d49f06937da84431aae4f.fontdata"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://immortal.ttf"
|
||||||
|
dest_files=["res://.godot/imported/immortal.ttf-1429e0fa3f3d49f06937da84431aae4f.fontdata"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
Rendering=null
|
||||||
|
antialiasing=1
|
||||||
|
generate_mipmaps=false
|
||||||
|
multichannel_signed_distance_field=false
|
||||||
|
msdf_pixel_range=8
|
||||||
|
msdf_size=48
|
||||||
|
allow_system_fallback=true
|
||||||
|
force_autohinter=false
|
||||||
|
hinting=1
|
||||||
|
subpixel_positioning=1
|
||||||
|
oversampling=0.0
|
||||||
|
Fallbacks=null
|
||||||
|
fallbacks=[]
|
||||||
|
Compress=null
|
||||||
|
compress=true
|
||||||
|
preload=[]
|
||||||
|
language_support={}
|
||||||
|
script_support={}
|
||||||
|
opentype_features={}
|
|
@ -0,0 +1,92 @@
|
||||||
|
class_name PlayerController extends Node3D
|
||||||
|
|
||||||
|
const _BACKWARD := "player_controller_backward"
|
||||||
|
|
||||||
|
const _FORWARD := "player_controller_forward"
|
||||||
|
|
||||||
|
const _LEFT := "player_controller_left"
|
||||||
|
|
||||||
|
const _RIGHT := "player_controller_right"
|
||||||
|
|
||||||
|
const _ROTATE_CCW := "player_controller_rotate_ccw"
|
||||||
|
|
||||||
|
const _ROTATE_CW := "player_controller_rotate_cw"
|
||||||
|
|
||||||
|
const _DRAG_SPEED_BASE_MODIFIER := 0.15
|
||||||
|
|
||||||
|
const _MOVE_SPEED_BASE_MODIFIER := 50.0
|
||||||
|
|
||||||
|
const _ROTATE_SPEED_BASE := 5.0
|
||||||
|
|
||||||
|
const _TRANSFORM_DELTA := 10.0
|
||||||
|
|
||||||
|
var _is_drag_panning := false
|
||||||
|
|
||||||
|
@onready
|
||||||
|
var _target_position := self.position
|
||||||
|
|
||||||
|
@onready
|
||||||
|
var _target_orientation := self.global_rotation.y
|
||||||
|
|
||||||
|
@export
|
||||||
|
var movement_smoothing := 0.5
|
||||||
|
|
||||||
|
func _input(event: InputEvent) -> void:
|
||||||
|
if event is InputEventMouseButton:
|
||||||
|
match event.button_index:
|
||||||
|
MOUSE_BUTTON_MIDDLE:
|
||||||
|
self._is_drag_panning = event.is_pressed()
|
||||||
|
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED if self._is_drag_panning else Input.MOUSE_MODE_VISIBLE
|
||||||
|
|
||||||
|
MOUSE_BUTTON_WHEEL_DOWN:
|
||||||
|
pass
|
||||||
|
|
||||||
|
MOUSE_BUTTON_WHEEL_UP:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
if (event is InputEventMouseMotion) and self._is_drag_panning:
|
||||||
|
var global_basis := self.global_transform.basis
|
||||||
|
var camera_settings := GameSettings.camera_settings
|
||||||
|
|
||||||
|
var dampened_speed :=\
|
||||||
|
camera_settings.movement_speed_modifier * _DRAG_SPEED_BASE_MODIFIER
|
||||||
|
|
||||||
|
self._target_position += dampened_speed.y * (-global_basis.z) *\
|
||||||
|
event.relative.y * (-1.0 if camera_settings.is_y_inverted else 1.0)
|
||||||
|
|
||||||
|
self._target_position += dampened_speed.x * (-global_basis.x) *\
|
||||||
|
event.relative.x * (-1.0 if camera_settings.is_x_inverted else 1.0)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
if event is InputEventScreenDrag:
|
||||||
|
return
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
var global_basis := self.global_transform.basis
|
||||||
|
var camera_settings := GameSettings.camera_settings
|
||||||
|
var delta_speed := camera_settings.movement_speed_modifier * _MOVE_SPEED_BASE_MODIFIER * delta
|
||||||
|
|
||||||
|
self._target_position += delta_speed.y * (-global_basis.z) *\
|
||||||
|
(Input.get_action_strength(_FORWARD) - Input.get_action_strength(_BACKWARD)) *\
|
||||||
|
(-1.0 if camera_settings.is_y_inverted else 1.0)
|
||||||
|
|
||||||
|
self._target_position += delta_speed.x * (-global_basis.x) *\
|
||||||
|
(Input.get_action_strength(_LEFT) - Input.get_action_strength(_RIGHT)) *\
|
||||||
|
(-1.0 if camera_settings.is_y_inverted else 1.0)
|
||||||
|
|
||||||
|
self._target_orientation += (Input.get_action_strength(_ROTATE_CCW) -\
|
||||||
|
Input.get_action_strength(_ROTATE_CW)) * _ROTATE_SPEED_BASE *\
|
||||||
|
camera_settings.rotation_speed_modifier * delta
|
||||||
|
|
||||||
|
self.global_transform = self.global_transform.interpolate_with(
|
||||||
|
Transform3D(Basis(Vector3.UP, self._target_orientation), self._target_position),
|
||||||
|
delta * _TRANSFORM_DELTA * self.movement_smoothing)
|
||||||
|
|
||||||
|
##
|
||||||
|
##
|
||||||
|
##
|
||||||
|
func is_drag_panning() -> bool:
|
||||||
|
return self._is_drag_panning
|
|
@ -0,0 +1,98 @@
|
||||||
|
; Engine configuration file.
|
||||||
|
; It's best edited using the editor UI and not directly,
|
||||||
|
; since the parameters that go here are not all obvious.
|
||||||
|
;
|
||||||
|
; Format:
|
||||||
|
; [section] ; section goes between []
|
||||||
|
; param=value ; assign values to parameters
|
||||||
|
|
||||||
|
config_version=5
|
||||||
|
|
||||||
|
_global_script_classes=[{
|
||||||
|
"base": "Node3D",
|
||||||
|
"class": &"PlayerController",
|
||||||
|
"language": &"GDScript",
|
||||||
|
"path": "res://player_controller.gd"
|
||||||
|
}, {
|
||||||
|
"base": "Node",
|
||||||
|
"class": &"Settings",
|
||||||
|
"language": &"GDScript",
|
||||||
|
"path": "res://settings.gd"
|
||||||
|
}, {
|
||||||
|
"base": "GeometryInstance3D",
|
||||||
|
"class": &"TerrainInstance3D",
|
||||||
|
"language": &"GDScript",
|
||||||
|
"path": "res://terrain_instance_3d.gd"
|
||||||
|
}]
|
||||||
|
_global_script_class_icons={
|
||||||
|
"PlayerController": "",
|
||||||
|
"Settings": "",
|
||||||
|
"TerrainInstance3D": ""
|
||||||
|
}
|
||||||
|
|
||||||
|
[application]
|
||||||
|
|
||||||
|
config/name="Protectorate"
|
||||||
|
run/main_scene="res://editor.scn"
|
||||||
|
config/features=PackedStringArray("4.0", "Forward Plus")
|
||||||
|
config/icon="res://icon.png"
|
||||||
|
|
||||||
|
[autoload]
|
||||||
|
|
||||||
|
GameSettings="*res://settings.gd"
|
||||||
|
|
||||||
|
[debug]
|
||||||
|
|
||||||
|
gdscript/warnings/assert_always_true=0
|
||||||
|
gdscript/warnings/assert_always_false=0
|
||||||
|
|
||||||
|
[display]
|
||||||
|
|
||||||
|
window/size/viewport_width=1280
|
||||||
|
window/size/viewport_height=800
|
||||||
|
window/stretch/mode="canvas_items"
|
||||||
|
window/stretch/aspect="keep_height"
|
||||||
|
|
||||||
|
[input]
|
||||||
|
|
||||||
|
player_controller_left={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
player_controller_right={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
player_controller_forward={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
player_controller_backward={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
player_controller_rotate_cw={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
player_controller_rotate_ccw={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":81,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
editor_paint={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"pressed":false,"double_click":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
[rendering]
|
||||||
|
|
||||||
|
lights_and_shadows/directional_shadow/soft_shadow_filter_quality=5
|
||||||
|
lights_and_shadows/directional_shadow/16_bits=false
|
||||||
|
lights_and_shadows/positional_shadow/soft_shadow_filter_quality=5
|
Binary file not shown.
|
@ -0,0 +1,36 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bgpk15qrqxly8"
|
||||||
|
path.s3tc="res://.godot/imported/prototype_tiles_large_albedo.png-c3984e5db888f4b509766546fda5695b.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/prototype_tiles_large_albedo.png-c3984e5db888f4b509766546fda5695b.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc", "etc2"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://prototype_tiles_large_albedo.png"
|
||||||
|
dest_files=["res://.godot/imported/prototype_tiles_large_albedo.png-c3984e5db888f4b509766546fda5695b.s3tc.ctex", "res://.godot/imported/prototype_tiles_large_albedo.png-c3984e5db888f4b509766546fda5695b.etc2.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=2
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/bptc_ldr=0
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=0
|
|
@ -0,0 +1,20 @@
|
||||||
|
class_name Settings extends Node
|
||||||
|
|
||||||
|
class CameraSettings:
|
||||||
|
var is_x_inverted := false
|
||||||
|
|
||||||
|
var is_y_inverted := false
|
||||||
|
|
||||||
|
var movement_speed_modifier := Vector2(0.5, 0.5)
|
||||||
|
|
||||||
|
var rotation_speed_modifier := 0.5
|
||||||
|
|
||||||
|
##
|
||||||
|
##
|
||||||
|
##
|
||||||
|
var camera_settings := CameraSettings.new():
|
||||||
|
get:
|
||||||
|
return camera_settings
|
||||||
|
|
||||||
|
set(_value):
|
||||||
|
assert(false, "`camera_settings` is not re-assignable")
|
Binary file not shown.
|
@ -0,0 +1,36 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dmbae0p1ujwcv"
|
||||||
|
path.s3tc="res://.godot/imported/terrain_cursor_emission.png-242c595842e9c0210b5a4ae1147e42e6.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/terrain_cursor_emission.png-242c595842e9c0210b5a4ae1147e42e6.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc", "etc2"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://terrain_cursor_emission.png"
|
||||||
|
dest_files=["res://.godot/imported/terrain_cursor_emission.png-242c595842e9c0210b5a4ae1147e42e6.s3tc.ctex", "res://.godot/imported/terrain_cursor_emission.png-242c595842e9c0210b5a4ae1147e42e6.etc2.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=2
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/bptc_ldr=0
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=true
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=0
|
|
@ -0,0 +1,197 @@
|
||||||
|
@tool
|
||||||
|
class_name TerrainInstance3D extends GeometryInstance3D
|
||||||
|
|
||||||
|
var _mesh := ArrayMesh.new()
|
||||||
|
|
||||||
|
var _material: ShaderMaterial = (func ():
|
||||||
|
var material := ShaderMaterial.new()
|
||||||
|
|
||||||
|
material.shader = preload("res://terrain_shader.gdshader")
|
||||||
|
|
||||||
|
return material).call()
|
||||||
|
|
||||||
|
##
|
||||||
|
##
|
||||||
|
##
|
||||||
|
@export
|
||||||
|
var size: Vector2i = Vector2i.ZERO:
|
||||||
|
get:
|
||||||
|
return size
|
||||||
|
|
||||||
|
set(value):
|
||||||
|
self._mesh.clear_surfaces()
|
||||||
|
|
||||||
|
var width := value.x
|
||||||
|
var height := value.y
|
||||||
|
|
||||||
|
if (width != 0) and (height != 0):
|
||||||
|
if (width != size.x) or (height != size.y):
|
||||||
|
var surface_tool := SurfaceTool.new()
|
||||||
|
|
||||||
|
surface_tool.begin(Mesh.PRIMITIVE_TRIANGLES)
|
||||||
|
|
||||||
|
var center_x := width / 2.0
|
||||||
|
var center_y := height / 2.0
|
||||||
|
|
||||||
|
for y in height + 1:
|
||||||
|
for x in width + 1:
|
||||||
|
surface_tool.set_uv(Vector2(x / float(width), y / float(height)))
|
||||||
|
surface_tool.set_color(Color(0.0, 0.0, 0.0, 0.0))
|
||||||
|
surface_tool.set_normal(Vector3.UP)
|
||||||
|
surface_tool.add_vertex(Vector3(x - center_x, 0.0, y - center_y))
|
||||||
|
|
||||||
|
var vert := 0
|
||||||
|
|
||||||
|
for y in height:
|
||||||
|
for x in width:
|
||||||
|
surface_tool.add_index(vert + width + 2)
|
||||||
|
surface_tool.add_index(vert + width + 1)
|
||||||
|
surface_tool.add_index(vert + 1)
|
||||||
|
surface_tool.add_index(vert + 1)
|
||||||
|
surface_tool.add_index(vert + width + 1)
|
||||||
|
surface_tool.add_index(vert + 0)
|
||||||
|
|
||||||
|
vert += 1
|
||||||
|
|
||||||
|
vert += 1
|
||||||
|
|
||||||
|
RenderingServer.instance_set_base(self.get_instance(),
|
||||||
|
surface_tool.commit(self._mesh).get_rid())
|
||||||
|
|
||||||
|
self._material.set_shader_parameter("AREA", Vector2(value))
|
||||||
|
self._mesh.surface_set_material(0, self._material)
|
||||||
|
|
||||||
|
size = value
|
||||||
|
|
||||||
|
##
|
||||||
|
##
|
||||||
|
##
|
||||||
|
@export
|
||||||
|
var layer_1_albedo: Texture2D = null:
|
||||||
|
get:
|
||||||
|
return layer_1_albedo
|
||||||
|
|
||||||
|
set(value):
|
||||||
|
self._material.set_shader_parameter("LAYER_1_ALBEDO", value)
|
||||||
|
|
||||||
|
layer_1_albedo = value
|
||||||
|
|
||||||
|
##
|
||||||
|
##
|
||||||
|
##
|
||||||
|
@export
|
||||||
|
var layer_1_normal_map: Texture2D = null:
|
||||||
|
get:
|
||||||
|
return layer_1_normal_map
|
||||||
|
|
||||||
|
set(value):
|
||||||
|
self._material.set_shader_parameter("LAYER_1_NORMAL_MAP", value)
|
||||||
|
|
||||||
|
layer_1_normal_map = value
|
||||||
|
|
||||||
|
##
|
||||||
|
##
|
||||||
|
##
|
||||||
|
@export
|
||||||
|
var layer_2_albedo: Texture2D = null:
|
||||||
|
get:
|
||||||
|
return layer_2_albedo
|
||||||
|
|
||||||
|
set(value):
|
||||||
|
self._material.set_shader_parameter("LAYER_2_ALBEDO", value)
|
||||||
|
|
||||||
|
layer_2_albedo = value
|
||||||
|
|
||||||
|
##
|
||||||
|
##
|
||||||
|
##
|
||||||
|
@export
|
||||||
|
var layer_2_normal_map: Texture2D = null:
|
||||||
|
get:
|
||||||
|
return layer_2_normal_map
|
||||||
|
|
||||||
|
set(value):
|
||||||
|
self._material.set_shader_parameter("LAYER_2_NORMAL_MAP", value)
|
||||||
|
|
||||||
|
layer_2_normal_map = value
|
||||||
|
|
||||||
|
##
|
||||||
|
##
|
||||||
|
##
|
||||||
|
@export
|
||||||
|
var layer_3_albedo: Texture2D = null:
|
||||||
|
get:
|
||||||
|
return layer_3_albedo
|
||||||
|
|
||||||
|
set(value):
|
||||||
|
self._material.set_shader_parameter("LAYER_3_ALBEDO", value)
|
||||||
|
|
||||||
|
layer_3_albedo = value
|
||||||
|
|
||||||
|
##
|
||||||
|
##
|
||||||
|
##
|
||||||
|
@export
|
||||||
|
var layer_3_normal_map: Texture2D = null:
|
||||||
|
get:
|
||||||
|
return layer_3_normal_map
|
||||||
|
|
||||||
|
set(value):
|
||||||
|
self._material.set_shader_parameter("LAYER_3_NORMAL_MAP", value)
|
||||||
|
|
||||||
|
layer_3_normal_map = value
|
||||||
|
|
||||||
|
##
|
||||||
|
##
|
||||||
|
##
|
||||||
|
@export
|
||||||
|
var layer_4_albedo: Texture2D = null:
|
||||||
|
get:
|
||||||
|
return layer_4_albedo
|
||||||
|
|
||||||
|
set(value):
|
||||||
|
self._material.set_shader_parameter("LAYER_4_ALBEDO", value)
|
||||||
|
|
||||||
|
layer_4_albedo = value
|
||||||
|
|
||||||
|
##
|
||||||
|
##
|
||||||
|
##
|
||||||
|
@export
|
||||||
|
var layer_4_normal_map: Texture2D = null:
|
||||||
|
get:
|
||||||
|
return layer_4_normal_map
|
||||||
|
|
||||||
|
set(value):
|
||||||
|
self._material.set_shader_parameter("LAYER_4_NORMAL_MAP", value)
|
||||||
|
|
||||||
|
layer_4_normal_map = value
|
||||||
|
|
||||||
|
##
|
||||||
|
##
|
||||||
|
##
|
||||||
|
@export
|
||||||
|
var terrain_map: Texture2D = null:
|
||||||
|
get:
|
||||||
|
return terrain_map
|
||||||
|
|
||||||
|
set(value):
|
||||||
|
self._material.set_shader_parameter("TERRAIN_MAP", value)
|
||||||
|
|
||||||
|
terrain_map = value
|
||||||
|
|
||||||
|
##
|
||||||
|
##
|
||||||
|
##
|
||||||
|
@export
|
||||||
|
var max_height := 100.0:
|
||||||
|
get:
|
||||||
|
return max_height
|
||||||
|
|
||||||
|
set(value):
|
||||||
|
self._material.set_shader_parameter("MAX_HEIGHT", value)
|
||||||
|
|
||||||
|
max_height = max(value, 0.0)
|
||||||
|
|
||||||
|
func _init() -> void:
|
||||||
|
RenderingServer.instance_set_base(self.get_instance(), self._mesh)
|
|
@ -0,0 +1,55 @@
|
||||||
|
shader_type spatial;
|
||||||
|
|
||||||
|
uniform vec2 AREA;
|
||||||
|
|
||||||
|
uniform sampler2D LAYER_1_ALBEDO : hint_default_black;
|
||||||
|
|
||||||
|
uniform sampler2D LAYER_1_NORMAL_MAP : hint_default_black;
|
||||||
|
|
||||||
|
uniform sampler2D LAYER_2_ALBEDO : hint_default_black;
|
||||||
|
|
||||||
|
uniform sampler2D LAYER_2_NORMAL_MAP : hint_default_black;
|
||||||
|
|
||||||
|
uniform sampler2D LAYER_3_ALBEDO : hint_default_black;
|
||||||
|
|
||||||
|
uniform sampler2D LAYER_3_NORMAL_MAP : hint_default_black;
|
||||||
|
|
||||||
|
uniform sampler2D LAYER_4_ALBEDO : hint_default_black;
|
||||||
|
|
||||||
|
uniform sampler2D LAYER_4_NORMAL_MAP : hint_default_black;
|
||||||
|
|
||||||
|
uniform float MAX_HEIGHT = 100.0;
|
||||||
|
|
||||||
|
uniform sampler2D TERRAIN_MAP : hint_default_transparent, repeat_disable;
|
||||||
|
|
||||||
|
void fragment() {
|
||||||
|
vec2 uv = UV * AREA;
|
||||||
|
vec2 uv_alt = uv * -0.25;
|
||||||
|
vec3 splat_map = texture(TERRAIN_MAP, UV).rgb;
|
||||||
|
float blank = clamp(1.0 - splat_map.r - splat_map.g - splat_map.b, 0.0, 1.0);
|
||||||
|
|
||||||
|
ALBEDO = blank * 0.5 * (texture(LAYER_1_ALBEDO, uv).rgb + texture(LAYER_1_ALBEDO, uv_alt).rgb);
|
||||||
|
ALBEDO += splat_map.r * 0.5 * (texture(LAYER_2_ALBEDO, uv).rgb + texture(LAYER_2_ALBEDO, uv_alt).rgb);
|
||||||
|
ALBEDO += splat_map.g * 0.5 * (texture(LAYER_3_ALBEDO, uv).rgb + texture(LAYER_3_ALBEDO, uv_alt).rgb);
|
||||||
|
ALBEDO += splat_map.b * 0.5 * (texture(LAYER_4_ALBEDO, uv).rgb + texture(LAYER_4_ALBEDO, uv_alt).rgb);
|
||||||
|
|
||||||
|
NORMAL_MAP = blank * 0.5 * (texture(LAYER_1_NORMAL_MAP, uv).rgb + texture(LAYER_1_NORMAL_MAP, uv_alt).rgb);
|
||||||
|
NORMAL_MAP += splat_map.r * 0.5 * (texture(LAYER_1_NORMAL_MAP, uv).rgb + texture(LAYER_2_NORMAL_MAP, uv_alt).rgb);
|
||||||
|
NORMAL_MAP += splat_map.g * 0.5 * (texture(LAYER_2_NORMAL_MAP, uv).rgb + texture(LAYER_3_NORMAL_MAP, uv_alt).rgb);
|
||||||
|
NORMAL_MAP += splat_map.b * 0.5 * (texture(LAYER_3_NORMAL_MAP, uv).rgb + texture(LAYER_4_NORMAL_MAP, uv_alt).rgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
float height(vec2 uv) {
|
||||||
|
return MAX_HEIGHT * texture(TERRAIN_MAP, uv).a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vertex() {
|
||||||
|
VERTEX.y = height(UV);
|
||||||
|
|
||||||
|
float left = height(vec2(UV.x - 1.0, UV.y));
|
||||||
|
float right = height(vec2(UV.x + 1.0, UV.y));
|
||||||
|
float forward = height(vec2(UV.x, UV.y + 1.0));
|
||||||
|
float backward = height(vec2(UV.x, UV.y - 1.0));
|
||||||
|
|
||||||
|
NORMAL = normalize(vec3(left - right, 2.0, forward - forward));
|
||||||
|
}
|
Loading…
Reference in New Issue