Skip to content

Instantly share code, notes, and snippets.

@fogleman
Created May 5, 2016 17:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fogleman/e4e747ad37aa5b99f3eec1c200cba12c to your computer and use it in GitHub Desktop.
Save fogleman/e4e747ad37aa5b99f3eec1c200cba12c to your computer and use it in GitHub Desktop.
terrain.go
package main
import (
"image"
"image/png"
"net/http"
. "github.com/fogleman/pt/pt"
)
func LoadTile(url string) (image.Image, error) {
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
return png.Decode(resp.Body)
}
func TerrariumToHeightMap(im image.Image) [][]float64 {
w := im.Bounds().Size().X
h := im.Bounds().Size().Y
result := make([][]float64, h)
data := make([]float64, w*h)
for i := range result {
result[i], data = data[:w], data[w:]
}
for y := 0; y < h; y++ {
for x := 0; x < w; x++ {
red, green, blue, _ := im.At(x, y).RGBA()
r := float64(red) / 256
g := float64(green) / 256
b := float64(blue) / 256
h := (r*256 + g + b/256) - 32768
result[y][x] = h * 0.05
}
}
return result
}
func HeightMapToMesh(data [][]float64) *Mesh {
const n = 1
h := len(data)
w := len(data[0])
material := GlossyMaterial(HexColor(0x334D5C), 1.1, Radians(30))
material.Texture = GetTexture("../density/texture.png", 2.2)
var triangles []*Triangle
for y := 0; y < h-n; y += n {
for x := 0; x < w-n; x += n {
v00 := Vector{float64(x) + 0, float64(y) + 0, data[y+0][x+0]}
v01 := Vector{float64(x) + 0, float64(y) + n, data[y+n][x+0]}
v10 := Vector{float64(x) + n, float64(y) + 0, data[y+0][x+n]}
v11 := Vector{float64(x) + n, float64(y) + n, data[y+n][x+n]}
t00 := Vector{float64(x+0) / float64(w), 1 - float64(y+0)/float64(h), 0}
t01 := Vector{float64(x+0) / float64(w), 1 - float64(y+n)/float64(h), 0}
t10 := Vector{float64(x+n) / float64(w), 1 - float64(y+0)/float64(h), 0}
t11 := Vector{float64(x+n) / float64(w), 1 - float64(y+n)/float64(h), 0}
triangles = append(triangles, NewTriangle(v00, v10, v11, t00, t10, t11, material))
triangles = append(triangles, NewTriangle(v00, v11, v01, t00, t11, t01, material))
}
}
return NewMesh(triangles)
}
func main() {
im, err := LoadPNG("../density/out.png")
// im, err := LoadTile("https://terrain-preview.mapzen.com/terrarium/9/91/186.png")
if err != nil {
panic(err)
}
mesh := HeightMapToMesh(TerrariumToHeightMap(im))
mesh.FitInside(Box{V(-1, -1, 0), V(1, 1, 1)}, V(0.5, 0.5, 0))
// mesh.SmoothNormals()
scene := Scene{}
// scene.SetColor(Color{1, 1, 1})
scene.Add(mesh)
light := LightMaterial(Color{1, 1, 1}, 1, NoAttenuation)
scene.Add(NewSphere(V(0, -1, 2), 1, light))
camera := LookAt(Vector{-1, 1, 0.5}, Vector{0, 0, -0.5}, Vector{0, 0, 1}, 35)
IterativeRender("out%03d.png", 1000, &scene, &camera, 2560/2, 1440/2, -1, 4, 4)
}
@nagexiucai
Copy link

hi, what is the "../density/texture.png"?
i have tried texture under pt/examples folder, results are all black.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment