Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | baq99 |
Hi everyone,
I have made a terrain from a heightmap and applied a single texture to the entire height and width of the terrain on a 1 to 1 scale. This is a cheap substitute for lighting but looks terrible close up. Is there a way to also tile textures based on the slope of geometry and blend them with the scaled up lightmap?
Here’s the code I used from an online tutorial
tool
extends Spatial
var width;
var height;
var heightData = {}
var vertices = PoolVector3Array()
var UVs = PoolVector2Array()
var normals = PoolVector3Array()
var tmpMesh = Mesh.new()
#paths
var p_heightmap = "res://Textures/Heightmaps/heightmap.png"
var p_material = "res://Materials/terrain_material.tres"
func _ready():
var heightmap = load(p_heightmap).get_data()
width = heightmap.get_width()
height = heightmap.get_height()
# parse image file
heightmap.lock()
for x in range(0,width):
for y in range(0,height):
heightData[Vector2(x,y)] = heightmap.get_pixel(x,y).r*10
heightmap.unlock()
# generate terrain
for x in range(0,width-1):
for y in range(0,height-1):
createQuad(x,y)
var st = SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
st.set_material(load(p_material))
for v in vertices.size():
st.add_color(Color(1,1,1))
st.add_uv(UVs[v])
st.add_normal(normals[v])
st.add_vertex(vertices[v])
st.commit(tmpMesh)
$MeshInstance.mesh = tmpMesh
var shape = ConcavePolygonShape.new()
shape.set_faces(tmpMesh.get_faces())
#$MeshInstance/StaticBody/CollisionShape.shape = shape
$MeshInstance.create_trimesh_collision()
func createQuad(x,y):
var vert1 # vertex positions (Vector2)
var vert2
var vert3
var side1 # sides of each triangle (Vector3)
var side2
var normal # normal for each triangle (Vector3)
# triangle 1
vert1 = Vector3(x,heightData[Vector2(x,y)],-y)
vert2 = Vector3(x,heightData[Vector2(x,y+1)],-y-1)
vert3 = Vector3(x+1,heightData[Vector2(x+1,y+1)],-y-1)
vertices.push_back(vert1)
vertices.push_back(vert2)
vertices.push_back(vert3)
UVs.push_back(Vector2(vert1.x/width, -vert1.z/height))
UVs.push_back(Vector2(vert2.x/width, -vert2.z/height))
UVs.push_back(Vector2(vert3.x/width, -vert3.z/height))
side1 = vert2-vert1
side2 = vert2-vert3
normal = side1.cross(side2)
for _i in range(0,3):
normals.push_back(normal)
# triangle 2
vert1 = Vector3(x,heightData[Vector2(x,y)],-y)
vert2 = Vector3(x+1,heightData[Vector2(x+1,y+1)],-y-1)
vert3 = Vector3(x+1,heightData[Vector2(x+1,y)],-y)
vertices.push_back(vert1)
vertices.push_back(vert2)
vertices.push_back(vert3)
UVs.push_back(Vector2(vert1.x/width, -vert1.z/height))
UVs.push_back(Vector2(vert2.x/width, -vert2.z/height))
UVs.push_back(Vector2(vert3.x/width, -vert3.z/height))
side1 = vert2-vert1
side2 = vert2-vert3
normal = side1.cross(side2)
for _i in range(0,3):
normals.push_back(normal)
My question is: how I would add a second material containing “grass” and “cliff” textures, that’s not scaled to width and height and then adjust that to apply texture based on slope the slope of the triangle in the mesh?
Thanks in advance.
I’ve seen other questions that ask
“can I apply two or more materials to the same mesh?”
answered with
“no you can’t, but you can use multiple textures in one material”.
I’m also aware that you can find the slope of the tris in the mesh and apply textures based off this value, however I don’t know if you can apply two textures at different scales in the same material.
On top of all of that, I have transparency in the lightmap texture which I wouldn’t want to be covered by tiling ground textures.
baq99 | 2021-03-25 18:41