[
  {
    "path": ".gitattributes",
    "content": "# Auto detect text files and perform LF normalization\n* text=auto\n"
  },
  {
    "path": ".gitignore",
    "content": ".godot/\n"
  },
  {
    "path": "README.md",
    "content": "# FPS Godot Basic Setup\n\n![alt text](https://github.com/StayAtHomeDev-Git/FPS-Godot-Basic-Setup/blob/main/readme_img.png)\n\nThese are the project files for the first episode of my \"FPS Godot Engine Project\" video tutorial series.\n\nThat video series can be found here:\n\n# Installation\n\nVersion: Godot Engine 4.1\n\n- Git or Download the Zip\n- Place project files into a project folder\n- Import project into the Godot Engine\n\nThe project comes with all the source code from the tutorial video and any test levels or resources (materials, nodes, etc).\n\n# License Agreement\n\nCopyright (c) 2023 StayAtHomeDev, LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n# Sponsors\n\nThanks to all the sponsors of this project!\n\nGeekeh\n"
  },
  {
    "path": "controllers/fps_controller.tscn",
    "content": "[gd_scene load_steps=5 format=3 uid=\"uid://c3ffql15mo0aj\"]\n\n[ext_resource type=\"Script\" path=\"res://controllers/scripts/fps_controller.gd\" id=\"1_pgc1p\"]\n[ext_resource type=\"Material\" uid=\"uid://b4gwd5h7ixvct\" path=\"res://materials/player.tres\" id=\"2_gldw4\"]\n\n[sub_resource type=\"CapsuleShape3D\" id=\"CapsuleShape3D_u6tj1\"]\n\n[sub_resource type=\"CapsuleMesh\" id=\"CapsuleMesh_6tv51\"]\nmaterial = ExtResource(\"2_gldw4\")\n\n[node name=\"CharacterBody3D\" type=\"CharacterBody3D\" node_paths=PackedStringArray(\"CAMERA_CONTROLLER\")]\nscript = ExtResource(\"1_pgc1p\")\nMOUSE_SENSITIVITY = 0.25\nCAMERA_CONTROLLER = NodePath(\"CameraController/Camera3D\")\n\n[node name=\"CollisionShape3D\" type=\"CollisionShape3D\" parent=\".\"]\ntransform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)\nshape = SubResource(\"CapsuleShape3D_u6tj1\")\n\n[node name=\"PlaceholderMesh\" type=\"MeshInstance3D\" parent=\"CollisionShape3D\"]\nmesh = SubResource(\"CapsuleMesh_6tv51\")\n\n[node name=\"CameraController\" type=\"Node3D\" parent=\".\"]\ntransform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0)\n\n[node name=\"Camera3D\" type=\"Camera3D\" parent=\"CameraController\"]\n\n[node name=\"ReflectionProbe\" type=\"ReflectionProbe\" parent=\"CameraController/Camera3D\"]\nupdate_mode = 1\nenable_shadows = true\n"
  },
  {
    "path": "controllers/scripts/fps_controller.gd",
    "content": "extends CharacterBody3D\n\n@export var SPEED : float = 5.0\n@export var JUMP_VELOCITY : float = 4.5\n@export var MOUSE_SENSITIVITY : float = 0.5\n@export var TILT_LOWER_LIMIT := deg_to_rad(-90.0)\n@export var TILT_UPPER_LIMIT := deg_to_rad(90.0)\n@export var CAMERA_CONTROLLER : Camera3D\n\nvar _mouse_input : bool = false\nvar _rotation_input : float\nvar _tilt_input : float\nvar _mouse_rotation : Vector3\nvar _player_rotation : Vector3\nvar _camera_rotation : Vector3\n\n# Get the gravity from the project settings to be synced with RigidBody nodes.\nvar gravity = ProjectSettings.get_setting(\"physics/3d/default_gravity\")\n\nfunc _unhandled_input(event: InputEvent) -> void:\n\t\n\t_mouse_input = event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED\n\tif _mouse_input:\n\t\t_rotation_input = -event.relative.x * MOUSE_SENSITIVITY\n\t\t_tilt_input = -event.relative.y * MOUSE_SENSITIVITY\n\t\t\nfunc _input(event):\n\t\n\tif event.is_action_pressed(\"exit\"):\n\t\tget_tree().quit()\n\t\t\nfunc _update_camera(delta):\n\t\n\t# Rotates camera using euler rotation\n\t_mouse_rotation.x += _tilt_input * delta\n\t_mouse_rotation.x = clamp(_mouse_rotation.x, TILT_LOWER_LIMIT, TILT_UPPER_LIMIT)\n\t_mouse_rotation.y += _rotation_input * delta\n\t\n\t_player_rotation = Vector3(0.0,_mouse_rotation.y,0.0)\n\t_camera_rotation = Vector3(_mouse_rotation.x,0.0,0.0)\n\n\tCAMERA_CONTROLLER.transform.basis = Basis.from_euler(_camera_rotation)\n\tglobal_transform.basis = Basis.from_euler(_player_rotation)\n\t\n\tCAMERA_CONTROLLER.rotation.z = 0.0\n\n\t_rotation_input = 0.0\n\t_tilt_input = 0.0\n\t\nfunc _ready():\n\n\t# Get mouse input\n\tInput.mouse_mode = Input.MOUSE_MODE_CAPTURED\n\nfunc _physics_process(delta):\n\t\n\t# Update camera movement based on mouse movement\n\t_update_camera(delta)\n\t\n\t# Add the gravity.\n\tif not is_on_floor():\n\t\tvelocity.y -= gravity * delta\n\n\t# Handle Jump.\n\tif Input.is_action_just_pressed(\"jump\") and is_on_floor():\n\t\tvelocity.y = JUMP_VELOCITY\n\n\t# Get the input direction and handle the movement/deceleration.\n\t# As good practice, you should replace UI actions with custom gameplay actions.\n\tvar input_dir = Input.get_vector(\"move_left\", \"move_right\", \"move_forward\", \"move_backward\")\n\t\n\tvar direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()\n\t\n\tif direction:\n\t\tvelocity.x = direction.x * SPEED\n\t\tvelocity.z = direction.z * SPEED\n\telse:\n\t\tvelocity.x = move_toward(velocity.x, 0, SPEED)\n\t\tvelocity.z = move_toward(velocity.z, 0, SPEED)\n\n\tmove_and_slide()\n"
  },
  {
    "path": "environment/WE_test.tres",
    "content": "[gd_resource type=\"Environment\" load_steps=4 format=3 uid=\"uid://dsay4gdr8k6ur\"]\n\n[ext_resource type=\"Texture2D\" uid=\"uid://b1jvh1ehiaebt\" path=\"res://textures/industrial_sunset_puresky_4k.hdr\" id=\"1_iwpli\"]\n\n[sub_resource type=\"PanoramaSkyMaterial\" id=\"PanoramaSkyMaterial_cmrwf\"]\npanorama = ExtResource(\"1_iwpli\")\n\n[sub_resource type=\"Sky\" id=\"Sky_0poj2\"]\nsky_material = SubResource(\"PanoramaSkyMaterial_cmrwf\")\n\n[resource]\nbackground_mode = 2\nsky = SubResource(\"Sky_0poj2\")\nambient_light_source = 3\nreflected_light_source = 2\nvolumetric_fog_density = 0.017\n"
  },
  {
    "path": "icon.svg.import",
    "content": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dskt1ln2x8owi\"\npath=\"res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex\"\nmetadata={\n\"vram_texture\": false\n}\n\n[deps]\n\nsource_file=\"res://icon.svg\"\ndest_files=[\"res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex\"]\n\n[params]\n\ncompress/mode=0\ncompress/high_quality=false\ncompress/lossy_quality=0.7\ncompress/hdr_compression=1\ncompress/normal_map=0\ncompress/channel_pack=0\nmipmaps/generate=false\nmipmaps/limit=-1\nroughness/mode=0\nroughness/src_normal=\"\"\nprocess/fix_alpha_border=true\nprocess/premult_alpha=false\nprocess/normal_map_invert_y=false\nprocess/hdr_as_srgb=false\nprocess/hdr_clamp_exposure=false\nprocess/size_limit=0\ndetect_3d/compress_to=1\nsvg/scale=1.0\neditor/scale_with_editor_scale=false\neditor/convert_colors_with_editor_theme=false\n"
  },
  {
    "path": "levels/WE_test.tscn",
    "content": "[gd_scene load_steps=2 format=3 uid=\"uid://btv0a42cgxt8g\"]\n\n[ext_resource type=\"Environment\" uid=\"uid://dsay4gdr8k6ur\" path=\"res://environment/WE_test.tres\" id=\"1_cvy6j\"]\n\n[node name=\"WorldEnvironment\" type=\"WorldEnvironment\"]\nenvironment = ExtResource(\"1_cvy6j\")\n\n[node name=\"DirectionalLight3D\" type=\"DirectionalLight3D\" parent=\".\"]\ntransform = Transform3D(0.905183, -0.346446, -0.246207, 0, -0.579281, 0.815128, -0.425021, -0.73784, -0.524356, 0, 0, 0)\nshadow_enabled = true\n"
  },
  {
    "path": "levels/level_001.tscn",
    "content": "[gd_scene load_steps=14 format=3 uid=\"uid://b1yleqbb8tc7x\"]\n\n[ext_resource type=\"PackedScene\" uid=\"uid://btv0a42cgxt8g\" path=\"res://levels/WE_test.tscn\" id=\"1_db21n\"]\n[ext_resource type=\"Material\" uid=\"uid://cn1gsy15bkaff\" path=\"res://materials/grid.tres\" id=\"2_x5xie\"]\n[ext_resource type=\"Texture2D\" uid=\"uid://ivvpsi314b34\" path=\"res://textures/grid.jpg\" id=\"3_yfwkt\"]\n[ext_resource type=\"PackedScene\" uid=\"uid://c3ffql15mo0aj\" path=\"res://controllers/fps_controller.tscn\" id=\"4_liofc\"]\n\n[sub_resource type=\"BoxMesh\" id=\"BoxMesh_gd0ev\"]\nmaterial = ExtResource(\"2_x5xie\")\nsize = Vector3(20, 0.5, 20)\n\n[sub_resource type=\"ConcavePolygonShape3D\" id=\"ConcavePolygonShape3D_oahyi\"]\ndata = PackedVector3Array(-10, 0.25, 10, 10, 0.25, 10, -10, -0.25, 10, 10, 0.25, 10, 10, -0.25, 10, -10, -0.25, 10, 10, 0.25, -10, -10, 0.25, -10, 10, -0.25, -10, -10, 0.25, -10, -10, -0.25, -10, 10, -0.25, -10, 10, 0.25, 10, 10, 0.25, -10, 10, -0.25, 10, 10, 0.25, -10, 10, -0.25, -10, 10, -0.25, 10, -10, 0.25, -10, -10, 0.25, 10, -10, -0.25, -10, -10, 0.25, 10, -10, -0.25, 10, -10, -0.25, -10, 10, 0.25, 10, -10, 0.25, 10, 10, 0.25, -10, -10, 0.25, 10, -10, 0.25, -10, 10, 0.25, -10, -10, -0.25, 10, 10, -0.25, 10, -10, -0.25, -10, 10, -0.25, 10, 10, -0.25, -10, -10, -0.25, -10)\n\n[sub_resource type=\"Shader\" id=\"Shader_cwof1\"]\ncode = \"// NOTE: Shader automatically converted from Godot Engine 4.1.dev4's StandardMaterial3D.\n\nshader_type spatial;\nrender_mode blend_mix,depth_draw_opaque,cull_back,diffuse_burley,specular_schlick_ggx;\nuniform vec4 albedo : source_color;\nuniform sampler2D texture_albedo : source_color,filter_linear_mipmap,repeat_enable;\nuniform float point_size : hint_range(0,128);\nuniform float roughness : hint_range(0,1);\nuniform sampler2D texture_metallic : hint_default_white,filter_linear_mipmap,repeat_enable;\nuniform vec4 metallic_texture_channel;\nuniform sampler2D texture_roughness : hint_roughness_r,filter_linear_mipmap,repeat_enable;\nuniform float specular;\nuniform float metallic;\nvarying vec3 uv1_triplanar_pos;\nuniform float uv1_blend_sharpness;\nvarying vec3 uv1_power_normal;\nuniform vec3 uv1_scale;\nuniform vec3 uv1_offset;\nuniform vec3 uv2_scale;\nuniform vec3 uv2_offset;\n\n\nvoid vertex() {\n\tTANGENT = vec3(0.0,0.0,-1.0) * abs(NORMAL.x);\n\tTANGENT+= vec3(1.0,0.0,0.0) * abs(NORMAL.y);\n\tTANGENT+= vec3(1.0,0.0,0.0) * abs(NORMAL.z);\n\tTANGENT = normalize(TANGENT);\n\tBINORMAL = vec3(0.0,1.0,0.0) * abs(NORMAL.x);\n\tBINORMAL+= vec3(0.0,0.0,-1.0) * abs(NORMAL.y);\n\tBINORMAL+= vec3(0.0,1.0,0.0) * abs(NORMAL.z);\n\tBINORMAL = normalize(BINORMAL);\n\tuv1_power_normal=pow(abs(NORMAL),vec3(uv1_blend_sharpness));\n\tuv1_triplanar_pos = VERTEX * uv1_scale + uv1_offset;\n\tuv1_power_normal/=dot(uv1_power_normal,vec3(1.0));\n\tuv1_triplanar_pos *= vec3(1.0,-1.0, 1.0);\n}\n\nvec4 triplanar_texture(sampler2D p_sampler,vec3 p_weights,vec3 p_triplanar_pos) {\n\tvec4 samp=vec4(0.0);\n\tsamp+= texture(p_sampler,p_triplanar_pos.xy) * p_weights.z;\n\tsamp+= texture(p_sampler,p_triplanar_pos.xz) * p_weights.y;\n\tsamp+= texture(p_sampler,p_triplanar_pos.zy * vec2(-1.0,1.0)) * p_weights.x;\n\treturn samp;\n}\n\nvoid fragment() {\n\tvec4 albedo_tex = triplanar_texture(texture_albedo,uv1_power_normal,uv1_triplanar_pos);\n\tALBEDO = (albedo.rgb * albedo_tex.r) + albedo_tex.g + albedo_tex.b;\n\tfloat metallic_tex = dot(triplanar_texture(texture_metallic,uv1_power_normal,uv1_triplanar_pos),metallic_texture_channel);\n\tMETALLIC = metallic_tex * metallic;\n\tvec4 roughness_texture_channel = vec4(1.0,0.0,0.0,0.0);\n\tfloat roughness_tex = dot(triplanar_texture(texture_roughness,uv1_power_normal,uv1_triplanar_pos),roughness_texture_channel);\n\tROUGHNESS = (1.0 - albedo_tex.g) * roughness;\n\tSPECULAR = specular;\n}\n\"\n\n[sub_resource type=\"ShaderMaterial\" id=\"ShaderMaterial_0racc\"]\nrender_priority = 0\nshader = SubResource(\"Shader_cwof1\")\nshader_parameter/albedo = Color(0.937255, 1, 0, 1)\nshader_parameter/point_size = 1.0\nshader_parameter/roughness = 0.5\nshader_parameter/metallic_texture_channel = Plane(1, 0, 0, 0)\nshader_parameter/specular = 0.5\nshader_parameter/metallic = 0.0\nshader_parameter/uv1_blend_sharpness = 1.0\nshader_parameter/uv1_scale = Vector3(0.5, 0.5, 0.5)\nshader_parameter/uv1_offset = Vector3(0.5, 0.5, 0.5)\nshader_parameter/uv2_scale = Vector3(1, 1, 1)\nshader_parameter/uv2_offset = Vector3(0, 0, 0)\nshader_parameter/texture_albedo = ExtResource(\"3_yfwkt\")\nshader_parameter/texture_roughness = ExtResource(\"3_yfwkt\")\n\n[sub_resource type=\"BoxMesh\" id=\"BoxMesh_xc4gq\"]\nmaterial = SubResource(\"ShaderMaterial_0racc\")\nsize = Vector3(2, 2, 2)\n\n[sub_resource type=\"ConcavePolygonShape3D\" id=\"ConcavePolygonShape3D_vp4dy\"]\ndata = PackedVector3Array(-1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1)\n\n[sub_resource type=\"ShaderMaterial\" id=\"ShaderMaterial_62u37\"]\nrender_priority = 0\nshader = SubResource(\"Shader_cwof1\")\nshader_parameter/albedo = Color(0, 0.67451, 0, 1)\nshader_parameter/point_size = 1.0\nshader_parameter/roughness = 0.5\nshader_parameter/metallic_texture_channel = Plane(1, 0, 0, 0)\nshader_parameter/specular = 0.5\nshader_parameter/metallic = 0.0\nshader_parameter/uv1_blend_sharpness = 1.0\nshader_parameter/uv1_scale = Vector3(0.5, 0.5, 0.5)\nshader_parameter/uv1_offset = Vector3(1, 0.5, 0.5)\nshader_parameter/uv2_scale = Vector3(1, 1, 1)\nshader_parameter/uv2_offset = Vector3(0, 0, 0)\nshader_parameter/texture_albedo = ExtResource(\"3_yfwkt\")\nshader_parameter/texture_roughness = ExtResource(\"3_yfwkt\")\n\n[sub_resource type=\"PrismMesh\" id=\"PrismMesh_rutao\"]\nmaterial = SubResource(\"ShaderMaterial_62u37\")\nleft_to_right = 0.0\nsize = Vector3(8, 2, 2)\n\n[sub_resource type=\"ConcavePolygonShape3D\" id=\"ConcavePolygonShape3D_j6kcl\"]\ndata = PackedVector3Array(-4, 1, 1, 4, -1, 1, -4, -1, 1, -4, 1, -1, -4, -1, -1, 4, -1, -1, -4, 1, 1, -4, 1, -1, 4, -1, 1, -4, 1, -1, 4, -1, -1, 4, -1, 1, -4, 1, -1, -4, 1, 1, -4, -1, -1, -4, 1, 1, -4, -1, 1, -4, -1, -1, -4, -1, 1, 4, -1, 1, -4, -1, -1, 4, -1, 1, 4, -1, -1, -4, -1, -1)\n\n[node name=\"Node3D\" type=\"Node3D\"]\n\n[node name=\"WorldEnvironment\" parent=\".\" instance=ExtResource(\"1_db21n\")]\n\n[node name=\"Floor\" type=\"MeshInstance3D\" parent=\".\"]\ntransform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.25, 0)\nmesh = SubResource(\"BoxMesh_gd0ev\")\n\n[node name=\"StaticBody3D\" type=\"StaticBody3D\" parent=\"Floor\"]\n\n[node name=\"CollisionShape3D\" type=\"CollisionShape3D\" parent=\"Floor/StaticBody3D\"]\nshape = SubResource(\"ConcavePolygonShape3D_oahyi\")\n\n[node name=\"Box\" type=\"MeshInstance3D\" parent=\".\"]\ntransform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 1, -5)\nmesh = SubResource(\"BoxMesh_xc4gq\")\n\n[node name=\"StaticBody3D\" type=\"StaticBody3D\" parent=\"Box\"]\n\n[node name=\"CollisionShape3D\" type=\"CollisionShape3D\" parent=\"Box/StaticBody3D\"]\nshape = SubResource(\"ConcavePolygonShape3D_vp4dy\")\n\n[node name=\"Ramp\" type=\"MeshInstance3D\" parent=\".\"]\ntransform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 5, 0, 0)\nmesh = SubResource(\"PrismMesh_rutao\")\nskeleton = NodePath(\"../Box\")\n\n[node name=\"StaticBody3D\" type=\"StaticBody3D\" parent=\"Ramp\"]\n\n[node name=\"CollisionShape3D\" type=\"CollisionShape3D\" parent=\"Ramp/StaticBody3D\"]\nshape = SubResource(\"ConcavePolygonShape3D_j6kcl\")\n\n[node name=\"CharacterBody3D\" parent=\".\" instance=ExtResource(\"4_liofc\")]\n"
  },
  {
    "path": "materials/grid.tres",
    "content": "[gd_resource type=\"ShaderMaterial\" load_steps=3 format=3 uid=\"uid://cn1gsy15bkaff\"]\n\n[ext_resource type=\"Texture2D\" uid=\"uid://ivvpsi314b34\" path=\"res://textures/grid.jpg\" id=\"1_57ppx\"]\n\n[sub_resource type=\"Shader\" id=\"Shader_cwof1\"]\ncode = \"// NOTE: Shader automatically converted from Godot Engine 4.1.dev4's StandardMaterial3D.\n\nshader_type spatial;\nrender_mode blend_mix,depth_draw_opaque,cull_back,diffuse_burley,specular_schlick_ggx;\nuniform vec4 albedo : source_color;\nuniform sampler2D texture_albedo : source_color,filter_linear_mipmap,repeat_enable;\nuniform float point_size : hint_range(0,128);\nuniform float roughness : hint_range(0,1);\nuniform sampler2D texture_metallic : hint_default_white,filter_linear_mipmap,repeat_enable;\nuniform vec4 metallic_texture_channel;\nuniform sampler2D texture_roughness : hint_roughness_r,filter_linear_mipmap,repeat_enable;\nuniform float specular;\nuniform float metallic;\nvarying vec3 uv1_triplanar_pos;\nuniform float uv1_blend_sharpness;\nvarying vec3 uv1_power_normal;\nuniform vec3 uv1_scale;\nuniform vec3 uv1_offset;\nuniform vec3 uv2_scale;\nuniform vec3 uv2_offset;\n\n\nvoid vertex() {\n\tTANGENT = vec3(0.0,0.0,-1.0) * abs(NORMAL.x);\n\tTANGENT+= vec3(1.0,0.0,0.0) * abs(NORMAL.y);\n\tTANGENT+= vec3(1.0,0.0,0.0) * abs(NORMAL.z);\n\tTANGENT = normalize(TANGENT);\n\tBINORMAL = vec3(0.0,1.0,0.0) * abs(NORMAL.x);\n\tBINORMAL+= vec3(0.0,0.0,-1.0) * abs(NORMAL.y);\n\tBINORMAL+= vec3(0.0,1.0,0.0) * abs(NORMAL.z);\n\tBINORMAL = normalize(BINORMAL);\n\tuv1_power_normal=pow(abs(NORMAL),vec3(uv1_blend_sharpness));\n\tuv1_triplanar_pos = VERTEX * uv1_scale + uv1_offset;\n\tuv1_power_normal/=dot(uv1_power_normal,vec3(1.0));\n\tuv1_triplanar_pos *= vec3(1.0,-1.0, 1.0);\n}\n\nvec4 triplanar_texture(sampler2D p_sampler,vec3 p_weights,vec3 p_triplanar_pos) {\n\tvec4 samp=vec4(0.0);\n\tsamp+= texture(p_sampler,p_triplanar_pos.xy) * p_weights.z;\n\tsamp+= texture(p_sampler,p_triplanar_pos.xz) * p_weights.y;\n\tsamp+= texture(p_sampler,p_triplanar_pos.zy * vec2(-1.0,1.0)) * p_weights.x;\n\treturn samp;\n}\n\nvoid fragment() {\n\tvec4 albedo_tex = triplanar_texture(texture_albedo,uv1_power_normal,uv1_triplanar_pos);\n\tALBEDO = (albedo.rgb * albedo_tex.r) + albedo_tex.g + albedo_tex.b;\n\tfloat metallic_tex = dot(triplanar_texture(texture_metallic,uv1_power_normal,uv1_triplanar_pos),metallic_texture_channel);\n\tMETALLIC = metallic_tex * metallic;\n\tvec4 roughness_texture_channel = vec4(1.0,0.0,0.0,0.0);\n\tfloat roughness_tex = dot(triplanar_texture(texture_roughness,uv1_power_normal,uv1_triplanar_pos),roughness_texture_channel);\n\tROUGHNESS = (1.0 - albedo_tex.g) * roughness;\n\tSPECULAR = specular;\n}\n\"\n\n[resource]\nrender_priority = 0\nshader = SubResource(\"Shader_cwof1\")\nshader_parameter/albedo = Color(0, 0, 0, 1)\nshader_parameter/point_size = 1.0\nshader_parameter/roughness = 0.5\nshader_parameter/metallic_texture_channel = Plane(1, 0, 0, 0)\nshader_parameter/specular = 0.5\nshader_parameter/metallic = 0.0\nshader_parameter/uv1_blend_sharpness = 1.0\nshader_parameter/uv1_scale = Vector3(0.5, 0.5, 0.5)\nshader_parameter/uv1_offset = Vector3(0, 0, 0)\nshader_parameter/uv2_scale = Vector3(1, 1, 1)\nshader_parameter/uv2_offset = Vector3(0, 0, 0)\nshader_parameter/texture_albedo = ExtResource(\"1_57ppx\")\nshader_parameter/texture_roughness = ExtResource(\"1_57ppx\")\n"
  },
  {
    "path": "materials/player.tres",
    "content": "[gd_resource type=\"StandardMaterial3D\" format=3 uid=\"uid://b4gwd5h7ixvct\"]\n\n[resource]\nalbedo_color = Color(0.847059, 0.0862745, 0, 1)\nroughness = 0.32\nemission = Color(0.188235, 0.254902, 1, 1)\nemission_energy_multiplier = 0.0\n"
  },
  {
    "path": "project.godot",
    "content": "; Engine configuration file.\n; It's best edited using the editor UI and not directly,\n; since the parameters that go here are not all obvious.\n;\n; Format:\n;   [section] ; section goes between []\n;   param=value ; assign values to parameters\n\nconfig_version=5\n\n[application]\n\nconfig/name=\"001 - Basic Setup\"\nrun/main_scene=\"res://levels/level_001.tscn\"\nconfig/features=PackedStringArray(\"4.1\", \"Forward Plus\")\nconfig/icon=\"res://icon.svg\"\n\n[display]\n\nwindow/size/always_on_top=true\n\n[input]\n\nmove_forward={\n\"deadzone\": 0.5,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"window_id\":0,\"alt_pressed\":false,\"shift_pressed\":false,\"ctrl_pressed\":false,\"meta_pressed\":false,\"pressed\":false,\"keycode\":0,\"physical_keycode\":87,\"key_label\":0,\"unicode\":119,\"echo\":false,\"script\":null)\n]\n}\nmove_backward={\n\"deadzone\": 0.5,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"window_id\":0,\"alt_pressed\":false,\"shift_pressed\":false,\"ctrl_pressed\":false,\"meta_pressed\":false,\"pressed\":false,\"keycode\":0,\"physical_keycode\":83,\"key_label\":0,\"unicode\":115,\"echo\":false,\"script\":null)\n]\n}\nmove_left={\n\"deadzone\": 0.5,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"window_id\":0,\"alt_pressed\":false,\"shift_pressed\":false,\"ctrl_pressed\":false,\"meta_pressed\":false,\"pressed\":false,\"keycode\":0,\"physical_keycode\":65,\"key_label\":0,\"unicode\":97,\"echo\":false,\"script\":null)\n]\n}\nmove_right={\n\"deadzone\": 0.5,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"window_id\":0,\"alt_pressed\":false,\"shift_pressed\":false,\"ctrl_pressed\":false,\"meta_pressed\":false,\"pressed\":false,\"keycode\":0,\"physical_keycode\":68,\"key_label\":0,\"unicode\":100,\"echo\":false,\"script\":null)\n]\n}\njump={\n\"deadzone\": 0.5,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"window_id\":0,\"alt_pressed\":false,\"shift_pressed\":false,\"ctrl_pressed\":false,\"meta_pressed\":false,\"pressed\":false,\"keycode\":0,\"physical_keycode\":32,\"key_label\":0,\"unicode\":32,\"echo\":false,\"script\":null)\n]\n}\nexit={\n\"deadzone\": 0.5,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"window_id\":0,\"alt_pressed\":false,\"shift_pressed\":false,\"ctrl_pressed\":false,\"meta_pressed\":false,\"pressed\":false,\"keycode\":0,\"physical_keycode\":4194305,\"key_label\":0,\"unicode\":0,\"echo\":false,\"script\":null)\n]\n}\n\n[rendering]\n\ntextures/default_filters/anisotropic_filtering_level=4\ntextures/default_filters/texture_mipmap_bias=-1.0\nanti_aliasing/quality/msaa_3d=3\nanti_aliasing/quality/screen_space_aa=1\n"
  },
  {
    "path": "readme_img.png.import",
    "content": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://s6s85xa1lxce\"\npath=\"res://.godot/imported/readme_img.png-c87ac3de286d8379757c000042cce94f.ctex\"\nmetadata={\n\"vram_texture\": false\n}\n\n[deps]\n\nsource_file=\"res://readme_img.png\"\ndest_files=[\"res://.godot/imported/readme_img.png-c87ac3de286d8379757c000042cce94f.ctex\"]\n\n[params]\n\ncompress/mode=0\ncompress/high_quality=false\ncompress/lossy_quality=0.7\ncompress/hdr_compression=1\ncompress/normal_map=0\ncompress/channel_pack=0\nmipmaps/generate=false\nmipmaps/limit=-1\nroughness/mode=0\nroughness/src_normal=\"\"\nprocess/fix_alpha_border=true\nprocess/premult_alpha=false\nprocess/normal_map_invert_y=false\nprocess/hdr_as_srgb=false\nprocess/hdr_clamp_exposure=false\nprocess/size_limit=0\ndetect_3d/compress_to=1\n"
  },
  {
    "path": "shaders/grid.gdshader",
    "content": "// NOTE: Shader automatically converted from Godot Engine 4.1.dev4's StandardMaterial3D.\n\nshader_type spatial;\nrender_mode blend_mix,depth_draw_opaque,cull_back,diffuse_burley,specular_schlick_ggx;\nuniform vec4 albedo : source_color;\nuniform sampler2D texture_albedo : source_color,filter_linear_mipmap,repeat_enable;\nuniform float point_size : hint_range(0,128);\nuniform float roughness : hint_range(0,1);\nuniform sampler2D texture_metallic : hint_default_white,filter_linear_mipmap,repeat_enable;\nuniform vec4 metallic_texture_channel;\nuniform sampler2D texture_roughness : hint_roughness_r,filter_linear_mipmap,repeat_enable;\nuniform float specular;\nuniform float metallic;\nvarying vec3 uv1_triplanar_pos;\nuniform float uv1_blend_sharpness;\nvarying vec3 uv1_power_normal;\nuniform vec3 uv1_scale;\nuniform vec3 uv1_offset;\nuniform vec3 uv2_scale;\nuniform vec3 uv2_offset;\n\n\nvoid vertex() {\n\tTANGENT = vec3(0.0,0.0,-1.0) * abs(NORMAL.x);\n\tTANGENT+= vec3(1.0,0.0,0.0) * abs(NORMAL.y);\n\tTANGENT+= vec3(1.0,0.0,0.0) * abs(NORMAL.z);\n\tTANGENT = normalize(TANGENT);\n\tBINORMAL = vec3(0.0,1.0,0.0) * abs(NORMAL.x);\n\tBINORMAL+= vec3(0.0,0.0,-1.0) * abs(NORMAL.y);\n\tBINORMAL+= vec3(0.0,1.0,0.0) * abs(NORMAL.z);\n\tBINORMAL = normalize(BINORMAL);\n\tuv1_power_normal=pow(abs(NORMAL),vec3(uv1_blend_sharpness));\n\tuv1_triplanar_pos = VERTEX * uv1_scale + uv1_offset;\n\tuv1_power_normal/=dot(uv1_power_normal,vec3(1.0));\n\tuv1_triplanar_pos *= vec3(1.0,-1.0, 1.0);\n}\n\nvec4 triplanar_texture(sampler2D p_sampler,vec3 p_weights,vec3 p_triplanar_pos) {\n\tvec4 samp=vec4(0.0);\n\tsamp+= texture(p_sampler,p_triplanar_pos.xy) * p_weights.z;\n\tsamp+= texture(p_sampler,p_triplanar_pos.xz) * p_weights.y;\n\tsamp+= texture(p_sampler,p_triplanar_pos.zy * vec2(-1.0,1.0)) * p_weights.x;\n\treturn samp;\n}\n\nvoid fragment() {\n\tvec4 albedo_tex = triplanar_texture(texture_albedo,uv1_power_normal,uv1_triplanar_pos);\n\tALBEDO = (albedo.rgb * albedo_tex.r) + albedo_tex.g + albedo_tex.b;\n\tfloat metallic_tex = dot(triplanar_texture(texture_metallic,uv1_power_normal,uv1_triplanar_pos),metallic_texture_channel);\n\tMETALLIC = metallic_tex * metallic;\n\tvec4 roughness_texture_channel = vec4(1.0,0.0,0.0,0.0);\n\tfloat roughness_tex = dot(triplanar_texture(texture_roughness,uv1_power_normal,uv1_triplanar_pos),roughness_texture_channel);\n\tROUGHNESS = (1.0 - albedo_tex.g) * roughness;\n\tSPECULAR = specular;\n}\n"
  },
  {
    "path": "textures/grid.jpg.import",
    "content": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://ivvpsi314b34\"\npath.bptc=\"res://.godot/imported/grid.jpg-98e91c7ac35e7c2efc8df0a4f602d545.bptc.ctex\"\nmetadata={\n\"imported_formats\": [\"s3tc_bptc\"],\n\"vram_texture\": true\n}\n\n[deps]\n\nsource_file=\"res://textures/grid.jpg\"\ndest_files=[\"res://.godot/imported/grid.jpg-98e91c7ac35e7c2efc8df0a4f602d545.bptc.ctex\"]\n\n[params]\n\ncompress/mode=2\ncompress/high_quality=true\ncompress/lossy_quality=0.7\ncompress/hdr_compression=1\ncompress/normal_map=0\ncompress/channel_pack=0\nmipmaps/generate=true\nmipmaps/limit=-1\nroughness/mode=0\nroughness/src_normal=\"\"\nprocess/fix_alpha_border=true\nprocess/premult_alpha=false\nprocess/normal_map_invert_y=false\nprocess/hdr_as_srgb=false\nprocess/hdr_clamp_exposure=false\nprocess/size_limit=0\ndetect_3d/compress_to=0\n"
  },
  {
    "path": "textures/industrial_sunset_puresky_4k.hdr.import",
    "content": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://b1jvh1ehiaebt\"\npath.bptc=\"res://.godot/imported/industrial_sunset_puresky_4k.hdr-f720137328f9b57effb6dcc1298b5e3b.bptc.ctex\"\nmetadata={\n\"imported_formats\": [\"s3tc_bptc\"],\n\"vram_texture\": true\n}\n\n[deps]\n\nsource_file=\"res://textures/industrial_sunset_puresky_4k.hdr\"\ndest_files=[\"res://.godot/imported/industrial_sunset_puresky_4k.hdr-f720137328f9b57effb6dcc1298b5e3b.bptc.ctex\"]\n\n[params]\n\ncompress/mode=2\ncompress/high_quality=false\ncompress/lossy_quality=0.7\ncompress/hdr_compression=1\ncompress/normal_map=0\ncompress/channel_pack=0\nmipmaps/generate=true\nmipmaps/limit=-1\nroughness/mode=0\nroughness/src_normal=\"\"\nprocess/fix_alpha_border=true\nprocess/premult_alpha=false\nprocess/normal_map_invert_y=false\nprocess/hdr_as_srgb=false\nprocess/hdr_clamp_exposure=false\nprocess/size_limit=0\ndetect_3d/compress_to=0\n"
  }
]