Last active
June 12, 2024 20:41
-
-
Save yosun/072849508d550c8b0641ee3ad646d60a to your computer and use it in GitHub Desktop.
input a depth mask, and get a mesh shaped based on that. includes Black version and Transparent version
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections.Generic; // Added for the dictionary | |
public class HeightmapGeneratorCullBlack : MonoBehaviour | |
{ | |
public Texture2D heightMap; | |
public Material material; | |
public Vector3 size = new Vector3(200, 30, 200); | |
void Start() | |
{ | |
GenerateHeightmap(); | |
} | |
public float threshold = .25f; | |
private void GenerateHeightmap() | |
{ | |
// Create the game object containing the renderer | |
gameObject.AddComponent<MeshFilter>(); | |
gameObject.AddComponent<MeshRenderer>(); | |
if (material) | |
{ | |
GetComponent<Renderer>().material = material; | |
} | |
else | |
{ | |
GetComponent<Renderer>().material.color = Color.white; | |
} | |
// Retrieve a mesh instance | |
Mesh mesh = GetComponent<MeshFilter>().mesh; | |
int width = Mathf.Min(heightMap.width, 255); | |
int height = Mathf.Min(heightMap.height, 255); | |
// Determine the number of valid vertices | |
int validVertexCount = 0; | |
for (int y = 0; y < height; y++) | |
{ | |
for (int x = 0; x < width; x++) | |
{ | |
if (heightMap.GetPixel(x, y).grayscale > threshold) | |
{ | |
validVertexCount++; | |
} | |
} | |
} | |
// Build vertices and UVs, skipping black pixels | |
Vector3[] vertices = new Vector3[validVertexCount]; | |
Vector2[] uv = new Vector2[validVertexCount]; | |
Vector4[] tangents = new Vector4[validVertexCount]; | |
Vector2 uvScale = new Vector2(1.0f / (width - 1), 1.0f / (height - 1)); | |
Vector3 sizeScale = new Vector3(size.x / (width - 1), size.y, size.z / (height - 1)); | |
int vertexIndex = 0; | |
Dictionary<int, int> validVertexMap = new Dictionary<int, int>(); // Map original to valid index | |
for (int y = 0; y < height; y++) | |
{ | |
for (int x = 0; x < width; x++) | |
{ | |
if (heightMap.GetPixel(x, y).grayscale > threshold) | |
{ | |
float pixelHeight = heightMap.GetPixel(x, y).grayscale; | |
Vector3 vertex = new Vector3(x, pixelHeight, y); | |
vertices[vertexIndex] = Vector3.Scale(sizeScale, vertex); | |
uv[vertexIndex] = Vector2.Scale(new Vector2(x, y), uvScale); | |
// Calculate tangent vector | |
Vector3 vertexL = new Vector3(x - 1, heightMap.GetPixel(x - 1, y).grayscale, y); | |
Vector3 vertexR = new Vector3(x + 1, heightMap.GetPixel(x + 1, y).grayscale, y); | |
Vector3 tan = Vector3.Scale(sizeScale, vertexR - vertexL).normalized; | |
tangents[vertexIndex] = new Vector4(tan.x, tan.y, tan.z, -1.0f); | |
validVertexMap[y * width + x] = vertexIndex; // Add to map | |
vertexIndex++; | |
} | |
} | |
} | |
// Assign them to the mesh | |
mesh.vertices = vertices; | |
mesh.uv = uv; | |
// Build triangle indices, adapting to the valid vertices | |
int[] triangles = new int[(validVertexCount - height) * 6]; // Adjust triangle count | |
int index = 0; | |
for (int y = 0; y < height - 1; y++) | |
{ | |
for (int x = 0; x < width - 1; x++) | |
{ | |
int v0 = y * width + x; | |
int v1 = (y + 1) * width + x; | |
int v2 = y * width + x + 1; | |
int v3 = (y + 1) * width + x + 1; | |
// Check validity AND get mapped index | |
if (validVertexMap.TryGetValue(v0, out v0) && | |
validVertexMap.TryGetValue(v1, out v1) && | |
validVertexMap.TryGetValue(v2, out v2) && | |
validVertexMap.TryGetValue(v3, out v3)) | |
{ | |
triangles[index++] = v0; | |
triangles[index++] = v1; | |
triangles[index++] = v2; | |
triangles[index++] = v1; | |
triangles[index++] = v3; | |
triangles[index++] = v2; | |
} | |
} | |
} | |
// And assign them to the mesh | |
mesh.triangles = triangles; | |
// Auto-calculate vertex normals from the mesh | |
mesh.RecalculateNormals(); | |
// Assign tangents after recalculating normals | |
mesh.tangents = tangents; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections.Generic; | |
public class HeightmapGenerator : MonoBehaviour | |
{ | |
public Texture2D heightMap; | |
public Material material; | |
public Vector3 size = new Vector3(200, 30, 200); | |
void Start() | |
{ | |
GenerateHeightmap(); | |
} | |
private void GenerateHeightmap() | |
{ | |
// Create the game object containing the renderer | |
gameObject.AddComponent<MeshFilter>(); | |
gameObject.AddComponent<MeshRenderer>(); | |
if (material) | |
{ | |
GetComponent<Renderer>().material = material; | |
} | |
else | |
{ | |
GetComponent<Renderer>().material.color = Color.white; | |
} | |
// Retrieve a mesh instance | |
Mesh mesh = GetComponent<MeshFilter>().mesh; | |
int width = Mathf.Min(heightMap.width, 255); | |
int height = Mathf.Min(heightMap.height, 255); | |
// Determine the number of valid vertices (non-black) | |
int validVertexCount = 0; | |
for (int y = 0; y < height; y++) | |
{ | |
for (int x = 0; x < width; x++) | |
{ | |
if (heightMap.GetPixel(x, y).grayscale > 0) | |
{ | |
validVertexCount++; | |
} | |
} | |
} | |
// Build vertices and UVs, skipping black pixels | |
Vector3[] vertices = new Vector3[validVertexCount]; | |
Vector2[] uv = new Vector2[validVertexCount]; | |
Vector4[] tangents = new Vector4[validVertexCount]; | |
Vector2 uvScale = new Vector2(1.0f / (width - 1), 1.0f / (height - 1)); | |
Vector3 sizeScale = new Vector3(size.x / (width - 1), size.y, size.z / (height - 1)); | |
int vertexIndex = 0; | |
for (int y = 0; y < height; y++) | |
{ | |
for (int x = 0; x < width; x++) | |
{ | |
if (heightMap.GetPixel(x, y).grayscale > 0) | |
{ | |
float pixelHeight = heightMap.GetPixel(x, y).grayscale; | |
Vector3 vertex = new Vector3(x, pixelHeight, y); | |
vertices[vertexIndex] = Vector3.Scale(sizeScale, vertex); | |
uv[vertexIndex] = Vector2.Scale(new Vector2(x, y), uvScale); | |
// Calculate tangent vector (consider handling edge cases gracefully) | |
Vector3 vertexL = (x > 0) ? new Vector3(x - 1, heightMap.GetPixel(x - 1, y).grayscale, y) : vertex; | |
Vector3 vertexR = (x < width - 1) ? new Vector3(x + 1, heightMap.GetPixel(x + 1, y).grayscale, y) : vertex; | |
Vector3 tan = Vector3.Scale(sizeScale, vertexR - vertexL).normalized; | |
tangents[vertexIndex] = new Vector4(tan.x, tan.y, tan.z, -1.0f); | |
vertexIndex++; | |
} | |
} | |
} | |
// Assign vertices and UVs to the mesh | |
mesh.vertices = vertices; | |
mesh.uv = uv; | |
// Build triangle indices | |
List<int> trianglesList = new List<int>(); // Use a list for dynamic size | |
for (int y = 0; y < height - 1; y++) | |
{ | |
for (int x = 0; x < width - 1; x++) | |
{ | |
int v0 = y * width + x; | |
int v1 = (y + 1) * width + x; | |
int v2 = y * width + x + 1; | |
int v3 = (y + 1) * width + x + 1; | |
// Check if all four vertices are valid (non-black) | |
if (heightMap.GetPixel(x, y).grayscale > 0 && | |
heightMap.GetPixel(x + 1, y).grayscale > 0 && | |
heightMap.GetPixel(x, y + 1).grayscale > 0 && | |
heightMap.GetPixel(x + 1, y + 1).grayscale > 0) | |
{ | |
trianglesList.Add(v0 - CalculateSkippedVertices(v0, width, heightMap)); | |
trianglesList.Add(v1 - CalculateSkippedVertices(v1, width, heightMap)); | |
trianglesList.Add(v2 - CalculateSkippedVertices(v2, width, heightMap)); | |
trianglesList.Add(v1 - CalculateSkippedVertices(v1, width, heightMap)); | |
trianglesList.Add(v3 - CalculateSkippedVertices(v3, width, heightMap)); | |
trianglesList.Add(v2 - CalculateSkippedVertices(v2, width, heightMap)); | |
} | |
} | |
} | |
mesh.triangles = trianglesList.ToArray(); | |
// Auto-calculate vertex normals from the mesh | |
mesh.RecalculateNormals(); | |
// Assign tangents after recalculating normals | |
mesh.tangents = tangents; | |
} | |
// Helper function to calculate the number of skipped vertices | |
int CalculateSkippedVertices(int index, int width, Texture2D heightMap) | |
{ | |
int skipped = 0; | |
int y = index / width; | |
int x = index % width; | |
for (int i = 0; i < y; i++) | |
{ | |
for (int j = 0; j < width; j++) | |
{ | |
if (heightMap.GetPixel(j, i).grayscale == 0) | |
{ | |
skipped++; | |
} | |
} | |
} | |
for (int j = 0; j < x; j++) | |
{ | |
if (heightMap.GetPixel(j, y).grayscale == 0) | |
{ | |
skipped++; | |
} | |
} | |
return skipped; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment