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