Material / shader to allow for multiple terrain textures

main
copygirl 3 months ago
parent 2595c77e83
commit 7cab61de50
  1. 29
      assets/textures/terrain/dirt.png.import
  2. 29
      assets/textures/terrain/grass.png.import
  3. 29
      assets/textures/terrain/rock.png.import
  4. 29
      assets/textures/terrain/sand.png.import
  5. 9
      level.tscn
  6. 7
      terrain/Terrain+Editing.cs
  7. 11
      terrain/Terrain.cs
  8. 15
      terrain/terrain_material.tres
  9. 12
      terrain/terrain_shader.gdshader

@ -1,35 +1,14 @@
[remap] [remap]
importer="texture" importer="image"
type="CompressedTexture2D" type="Image"
uid="uid://bpo7mkr6sctqr" uid="uid://bpo7mkr6sctqr"
path.s3tc="res://.godot/imported/dirt.png-67313fa97fa5b9369bec725f203ba6a9.s3tc.ctex" path="res://.godot/imported/dirt.png-67313fa97fa5b9369bec725f203ba6a9.image"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps] [deps]
source_file="res://assets/textures/terrain/dirt.png" source_file="res://assets/textures/terrain/dirt.png"
dest_files=["res://.godot/imported/dirt.png-67313fa97fa5b9369bec725f203ba6a9.s3tc.ctex"] dest_files=["res://.godot/imported/dirt.png-67313fa97fa5b9369bec725f203ba6a9.image"]
[params] [params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
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

@ -1,35 +1,14 @@
[remap] [remap]
importer="texture" importer="image"
type="CompressedTexture2D" type="Image"
uid="uid://b0jp1dyxugbr7" uid="uid://b0jp1dyxugbr7"
path.s3tc="res://.godot/imported/grass.png-aff98023336e7c812cce14c63596cfa6.s3tc.ctex" path="res://.godot/imported/grass.png-aff98023336e7c812cce14c63596cfa6.image"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps] [deps]
source_file="res://assets/textures/terrain/grass.png" source_file="res://assets/textures/terrain/grass.png"
dest_files=["res://.godot/imported/grass.png-aff98023336e7c812cce14c63596cfa6.s3tc.ctex"] dest_files=["res://.godot/imported/grass.png-aff98023336e7c812cce14c63596cfa6.image"]
[params] [params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
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

@ -1,35 +1,14 @@
[remap] [remap]
importer="texture" importer="image"
type="CompressedTexture2D" type="Image"
uid="uid://dqyqg6yt7yk3k" uid="uid://dqyqg6yt7yk3k"
path.s3tc="res://.godot/imported/rock.png-6fd2e985e4c17866aa31a92f6096a3ad.s3tc.ctex" path="res://.godot/imported/rock.png-6fd2e985e4c17866aa31a92f6096a3ad.image"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps] [deps]
source_file="res://assets/textures/terrain/rock.png" source_file="res://assets/textures/terrain/rock.png"
dest_files=["res://.godot/imported/rock.png-6fd2e985e4c17866aa31a92f6096a3ad.s3tc.ctex"] dest_files=["res://.godot/imported/rock.png-6fd2e985e4c17866aa31a92f6096a3ad.image"]
[params] [params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
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

@ -1,35 +1,14 @@
[remap] [remap]
importer="texture" importer="image"
type="CompressedTexture2D" type="Image"
uid="uid://bkwjxg6g2itag" uid="uid://bkwjxg6g2itag"
path.s3tc="res://.godot/imported/sand.png-451c9e51968306b5331529d9113b3e49.s3tc.ctex" path="res://.godot/imported/sand.png-451c9e51968306b5331529d9113b3e49.image"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps] [deps]
source_file="res://assets/textures/terrain/sand.png" source_file="res://assets/textures/terrain/sand.png"
dest_files=["res://.godot/imported/sand.png-451c9e51968306b5331529d9113b3e49.s3tc.ctex"] dest_files=["res://.godot/imported/sand.png-451c9e51968306b5331529d9113b3e49.image"]
[params] [params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
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

@ -1,15 +1,12 @@
[gd_scene load_steps=11 format=3 uid="uid://cmootlmme7yid"] [gd_scene load_steps=8 format=3 uid="uid://cmootlmme7yid"]
[ext_resource type="Texture2D" uid="uid://b0jp1dyxugbr7" path="res://assets/textures/terrain/grass.png" id="1_1tbeu"]
[ext_resource type="PackedScene" uid="uid://daihc7acaxfns" path="res://character.tscn" id="1_ymqel"] [ext_resource type="PackedScene" uid="uid://daihc7acaxfns" path="res://character.tscn" id="1_ymqel"]
[ext_resource type="Texture2D" uid="uid://dqyqg6yt7yk3k" path="res://assets/textures/terrain/rock.png" id="2_glt4b"]
[ext_resource type="Script" path="res://CameraController.cs" id="2_wn05g"] [ext_resource type="Script" path="res://CameraController.cs" id="2_wn05g"]
[ext_resource type="Texture2D" uid="uid://bpo7mkr6sctqr" path="res://assets/textures/terrain/dirt.png" id="3_kwxfa"] [ext_resource type="Material" uid="uid://doe8owgx4jeu1" path="res://terrain/terrain_material.tres" id="4_edbby"]
[ext_resource type="PackedScene" uid="uid://c732i0mrp6klk" path="res://objects/tree_oak_round.tscn" id="6_xbyit"] [ext_resource type="PackedScene" uid="uid://c732i0mrp6klk" path="res://objects/tree_oak_round.tscn" id="6_xbyit"]
[ext_resource type="PackedScene" uid="uid://2giwj61d3h66" path="res://objects/tree_oak_tall.tscn" id="7_wghwq"] [ext_resource type="PackedScene" uid="uid://2giwj61d3h66" path="res://objects/tree_oak_tall.tscn" id="7_wghwq"]
[ext_resource type="PackedScene" uid="uid://b65o2rhp8qx74" path="res://objects/tree_oak_cone.tscn" id="8_iglt6"] [ext_resource type="PackedScene" uid="uid://b65o2rhp8qx74" path="res://objects/tree_oak_cone.tscn" id="8_iglt6"]
[ext_resource type="Script" path="res://terrain/Terrain.cs" id="9_rniku"] [ext_resource type="Script" path="res://terrain/Terrain.cs" id="9_rniku"]
[ext_resource type="Texture2D" uid="uid://bkwjxg6g2itag" path="res://assets/textures/terrain/sand.png" id="10_70ou1"]
[node name="Level" type="Node3D"] [node name="Level" type="Node3D"]
@ -39,7 +36,7 @@ far = 50.0
[node name="Terrain" type="StaticBody3D" parent="."] [node name="Terrain" type="StaticBody3D" parent="."]
collision_mask = 0 collision_mask = 0
script = ExtResource("9_rniku") script = ExtResource("9_rniku")
Textures = [ExtResource("1_1tbeu"), ExtResource("3_kwxfa"), ExtResource("10_70ou1"), ExtResource("2_glt4b")] Material = ExtResource("4_edbby")
Tiles = {} Tiles = {}
[node name="Trees" type="Node3D" parent="."] [node name="Trees" type="Node3D" parent="."]

@ -121,7 +121,6 @@ public partial class Terrain
mesh.ClearSurfaces(); mesh.ClearSurfaces();
mesh.SurfaceBegin(Mesh.PrimitiveType.Lines); mesh.SurfaceBegin(Mesh.PrimitiveType.Lines);
void AddLine(Vector3 start, Vector3 end) { void AddLine(Vector3 start, Vector3 end) {
mesh.SurfaceAddVertex(start); mesh.SurfaceAddVertex(start);
mesh.SurfaceAddVertex(end); mesh.SurfaceAddVertex(end);
@ -139,12 +138,10 @@ public partial class Terrain
var corners = GetCornersPosition(hover); var corners = GetCornersPosition(hover);
var margin = 0.1f; var margin = 0.1f;
mesh.SurfaceSetColor(Colors.Black); mesh.SurfaceSetColor(Colors.Black);
AddQuad( AddQuad(corners.TopLeft + new Vector3(-margin, 0, -margin),
corners.TopLeft + new Vector3(-margin, 0, -margin),
corners.TopRight + new Vector3(+margin, 0, -margin), corners.TopRight + new Vector3(+margin, 0, -margin),
corners.BottomLeft + new Vector3(-margin, 0, +margin), corners.BottomLeft + new Vector3(-margin, 0, +margin),
corners.BottomRight + new Vector3(+margin, 0, +margin) corners.BottomRight + new Vector3(+margin, 0, +margin));
);
} }
mesh.SurfaceSetColor(Colors.Blue); mesh.SurfaceSetColor(Colors.Blue);

@ -4,7 +4,7 @@ public partial class Terrain
[Export] public Vector2I Size { get; set; } = new(64, 64); [Export] public Vector2I Size { get; set; } = new(64, 64);
[Export] public float TileSize { get; set; } = 2.0f; [Export] public float TileSize { get; set; } = 2.0f;
[Export] public Godot.Collections.Array<Texture2D> Textures { get; set; } [Export] public ShaderMaterial Material { get; set; }
// If value at position non-existant => [ 0, 0, 0, 0 ] // If value at position non-existant => [ 0, 0, 0, 0 ]
// If value at position is float => [ v, v, v, v ] // If value at position is float => [ v, v, v, v ]
@ -13,7 +13,6 @@ public partial class Terrain
Material _editToolMaterial; Material _editToolMaterial;
Material _terrainMaterial;
public override void _Ready() public override void _Ready()
{ {
_editToolMaterial = new StandardMaterial3D { _editToolMaterial = new StandardMaterial3D {
@ -23,10 +22,6 @@ public partial class Terrain
NoDepthTest = true, NoDepthTest = true,
}; };
_terrainMaterial = new StandardMaterial3D {
AlbedoTexture = Textures?.FirstOrDefault(),
};
UpdateMeshAndShape(); UpdateMeshAndShape();
} }
@ -143,6 +138,7 @@ public partial class Terrain
AddPoint(v3, uv3); AddPoint(v3, uv3);
} }
var rnd = new Random();
for (var x = 0; x < Size.X; x++) for (var x = 0; x < Size.X; x++)
for (var z = 0; z < Size.Y; z++) { for (var z = 0; z < Size.Y; z++) {
var corners = GetCornersPosition(new(x, z)); var corners = GetCornersPosition(new(x, z));
@ -153,6 +149,7 @@ public partial class Terrain
var minDiff = Abs(sorted[0].Value.Y - sorted[2].Value.Y); // Difference between lowest and 3rd lowest point. var minDiff = Abs(sorted[0].Value.Y - sorted[2].Value.Y); // Difference between lowest and 3rd lowest point.
var maxDiff = Abs(sorted[3].Value.Y - sorted[1].Value.Y); // Difference between highest and 3rd highest point. var maxDiff = Abs(sorted[3].Value.Y - sorted[1].Value.Y); // Difference between highest and 3rd highest point.
mesh.SurfaceSetUV2(new(rnd.Next(4), 0.0f));
var first = sorted[(minDiff > maxDiff) ? 0 : 3].Corner; var first = sorted[(minDiff > maxDiff) ? 0 : 3].Corner;
if (first is Corner.TopLeft or Corner.BottomRight) { if (first is Corner.TopLeft or Corner.BottomRight) {
AddTriangle(corners.TopLeft , new(0.0f, 0.0f), AddTriangle(corners.TopLeft , new(0.0f, 0.0f),
@ -172,7 +169,7 @@ public partial class Terrain
} }
mesh.SurfaceEnd(); mesh.SurfaceEnd();
mesh.SurfaceSetMaterial(0, _terrainMaterial); mesh.SurfaceSetMaterial(0, Material);
shape.Data = [.. points]; shape.Data = [.. points];
} }

@ -0,0 +1,15 @@
[gd_resource type="ShaderMaterial" load_steps=7 format=4 uid="uid://doe8owgx4jeu1"]
[ext_resource type="Shader" path="res://terrain/terrain_shader.gdshader" id="1_mf55c"]
[ext_resource type="Image" uid="uid://b0jp1dyxugbr7" path="res://assets/textures/terrain/grass.png" id="5_mau31"]
[ext_resource type="Image" uid="uid://bpo7mkr6sctqr" path="res://assets/textures/terrain/dirt.png" id="6_xc3ue"]
[ext_resource type="Image" uid="uid://dqyqg6yt7yk3k" path="res://assets/textures/terrain/rock.png" id="7_84wdo"]
[ext_resource type="Image" uid="uid://bkwjxg6g2itag" path="res://assets/textures/terrain/sand.png" id="8_3fpcn"]
[sub_resource type="Texture2DArray" id="Texture2DArray_3nq13"]
_images = Array[Image]([ExtResource("5_mau31"), ExtResource("6_xc3ue"), ExtResource("7_84wdo"), ExtResource("8_3fpcn")])
[resource]
render_priority = 0
shader = ExtResource("1_mf55c")
shader_parameter/textures = SubResource("Texture2DArray_3nq13")

@ -0,0 +1,12 @@
shader_type spatial;
render_mode blend_mix, depth_draw_opaque, cull_back, diffuse_burley, specular_schlick_ggx;
uniform sampler2DArray textures : source_color, filter_linear_mipmap, repeat_enable;
void fragment() {
ALBEDO = texture(textures, vec3(UV, UV2.x)).rgb;
METALLIC = 0.0;
SPECULAR = 0.5;
ROUGHNESS = 1.0;
}
Loading…
Cancel
Save