123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- package renderer
- import (
- . "github.com/fogleman/fauxgl"
- "github.com/nfnt/resize"
- "errors"
- "image"
- "log"
- "os"
- "path/filepath"
- "strings"
- )
- const (
- scale = 1 // optional supersampling
- width = 1000 // output width in pixels
- height = 1000 // output height in pixels
- fovy = 10 // vertical field of view in degrees
- near = 1 // near clipping plane
- far = 40 // far clipping plane
- )
- var (
- eye = V(-6, -6, 5) // camera position
- center = V(0, -0.07, 0) // view center position
- up = V(0, 0, 1) // up vector
- light = V(-1, -2, 5).Normalize() // light direction
- color = ("#42f5b3") // object color
- background = HexColor("#e0e0e0") //Background color
- )
- type RenderOption struct {
- Color string
- BackgroundColor string
- Width int
- Height int
- }
- type Renderer struct {
- Option RenderOption
- }
- func New3DRenderer(option RenderOption) *Renderer {
- return &Renderer{
- Option: option,
- }
- }
- func (r *Renderer) RenderModel(filename string) (image.Image, error) {
- // load a mesh
- var mesh *Mesh
- if strings.ToLower(filepath.Ext(filename)) == ".stl" {
- m, err := LoadSTL(filename)
- if err != nil {
- return nil, err
- }
- mesh = m
- } else if strings.ToLower(filepath.Ext(filename)) == ".obj" {
- m, err := LoadOBJ(filename)
- if err != nil {
- return nil, err
- }
- mesh = m
- } else {
- log.Println("Not supported format, given: " + filepath.Ext(filename))
- return nil, errors.New("Not supported model format")
- }
- // fit mesh in a bi-unit cube centered at the origin
- mesh.UnitCube()
- //log.Println(mesh.BoundingBox(), filename)
- // smooth the normals
- mesh.SmoothNormalsThreshold(Radians(30))
- // create a rendering context
- context := NewContext(r.Option.Width*scale, r.Option.Height*scale)
- context.ClearColorBufferWith(HexColor(r.Option.BackgroundColor))
- // create transformation matrix and light direction
- aspect := float64(width) / float64(height)
- matrix := LookAt(eye, center, up).Perspective(fovy, aspect, near, far)
- // use builtin phong shader
- shader := NewPhongShader(matrix, light, eye)
- shader.ObjectColor = HexColor(r.Option.Color)
- context.Shader = shader
- // render
- context.DrawMesh(mesh)
- // downsample image for antialiasing
- image := context.Image()
- image = resize.Resize(width, height, image, resize.Bilinear)
- return image, nil
- }
- func fileExists(filename string) bool {
- info, err := os.Stat(filename)
- if os.IsNotExist(err) {
- return false
- }
- return !info.IsDir()
- }
|