Created
June 19, 2025 16:22
-
-
Save BalintCsala/87f8a77bf4f38ffed337ec02cbd55b17 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
from PIL import Image | |
def load_normal_map(path): | |
img = Image.open(path).convert("RGB") | |
width, height = img.size | |
normals = [] | |
for y in range(height): | |
row = [] | |
for x in range(width): | |
r, g, b = img.getpixel((x, y)) | |
nx = (r / 255.0) * 2.0 - 1.0 | |
ny = (g / 255.0) * 2.0 - 1.0 | |
nz = (b / 255.0) * 2.0 - 1.0 | |
row.append((nx, ny, nz)) | |
normals.append(row) | |
return normals, width, height | |
def save_heightmap(heights, output_path): | |
height = len(heights) | |
width = len(heights[0]) if height > 0 else 0 | |
flat_values = [val for row in heights for val in row] | |
min_val = min(flat_values) | |
max_val = max(flat_values) | |
if max_val - min_val == 0: | |
normalized = [[128 for _ in range(width)] for _ in range(height)] | |
else: | |
normalized = [ | |
[int((val - min_val) / (max_val - min_val) * 255) for val in row] | |
for row in heights | |
] | |
img = Image.new('L', (width, height)) | |
for y in range(height): | |
for x in range(width): | |
img.putpixel((x, y), normalized[y][x]) | |
img.save(output_path) | |
if __name__ == "__main__": | |
normals, width, height = load_normal_map("normals.png") | |
heights_x_first = [[0]] | |
# Fill up the first row | |
for x in range(1, width): | |
nx, ny, nz = normals[0][x] | |
x_slope = nx / nz | |
heights_x_first[0].append(heights_x_first[0][x - 1] + x_slope) | |
# Fill up the columns | |
for y in range(1, height): | |
row = [] | |
for x in range(0, width): | |
nx, ny, nz = normals[y][x] | |
y_slope = ny / nz | |
row.append(heights_x_first[y - 1][x] + y_slope) | |
heights_x_first.append(row) | |
save_heightmap(heights_x_first, "height_x_first.png") | |
heights_y_first = [[0]] | |
# Fill up the first column | |
for y in range(1, height): | |
nx, ny, nz = normals[y][0] | |
y_slope = ny / nz | |
heights_y_first.append([heights_y_first[y - 1][0] + y_slope]) | |
# Fill up the columns | |
for y in range(0, height): | |
for x in range(1, width): | |
nx, ny, nz = normals[y][x] | |
x_slope = nx / nz | |
heights_y_first[y].append(heights_y_first[y][x - 1] + x_slope) | |
save_heightmap(heights_y_first, "height_y_first.png") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment