golang实现3D线条艺术渲染的高效插件库ln的使用

Golang实现3D线条艺术渲染的高效插件库ln的使用

ln - 3D线条艺术引擎

ln是一个用Go编写的基于矢量的3D渲染器,用于生成描述3D场景的2D矢量图形(如SVG)。

Examples

安装

go get github.com/fogleman/ln/ln

主要特性

  • 基本几何体
    • 球体
    • 立方体
    • 三角形
    • 圆柱体
    • 3D函数
  • 三角形网格
    • 支持OBJ和STL格式
  • 基于矢量的"纹理"
  • CSG(构造实体几何)操作
    • 交集
    • 差集
    • 并集
  • 输出PNG或SVG格式

工作原理

ln的核心是Shape接口:

type Shape interface {
	Paths() Paths
	Intersect(Ray) Hit
	Contains(Vector, float64) bool
	BoundingBox() Box
	Compile()
}

每个形状必须提供一些Paths,这些是实体表面的3D折线。最终图像中绘制的所有内容都基于这些路径。

示例:绘制单个立方体

代码

package main

import "github.com/fogleman/ln/ln"

func main() {
	// 创建场景并添加一个立方体
	scene := ln.Scene{}
	scene.Add(ln.NewCube(ln.Vector{-1, -1, -1}, ln.Vector{1, 1, 1}))

	// 定义相机参数
	eye := ln.Vector{4, 3, 2}    // 相机位置
	center := ln.Vector{0, 0, 0} // 相机看向的点
	up := ln.Vector{0, 0, 1}     // 上方向

	// 定义渲染参数
	width := 1024.0  // 渲染宽度
	height := 1024.0 // 渲染高度
	fovy := 50.0     // 垂直视野,度数
	znear := 0.1     // 近平面
	zfar := 10.0     // 远平面
	step := 0.01     // 路径分割的精细度,用于可见性测试

	// 计算描述3D场景的2D路径
	paths := scene.Render(eye, center, up, width, height, fovy, znear, zfar, step)

	// 将路径渲染为图像
	paths.WriteToPNG("out.png", width, height)

	// 将路径保存为svg
	paths.WriteToSVG("out.svg", width, height)
}

输出

Cube

自定义纹理

要为立方体添加垂直条纹纹理,可以定义新类型并重写Paths()函数:

type StripedCube struct {
	ln.Cube
	Stripes int
}

func (c *StripedCube) Paths() ln.Paths {
	var paths ln.Paths
	x1, y1, z1 := c.Min.X, c.Min.Y, c.Min.Z
	x2, y2, z2 := c.Max.X, c.Max.Y, c.Max.Z
	for i := 0; i <= c.Stripes; i++ {
		p := float64(i) / float64(c.Stripes)
		x := x1 + (x2-x1)*p
		y := y1 + (y2-y1)*p
		paths = append(paths, ln.Path{{x, y1, z1}, {x, y1, z2}})
		paths = append(paths, ln.Path{{x, y2, z1}, {x, y2, z2}})
		paths = append(paths, ln.Path{{x1, y, z1}, {x1, y, z2}})
		paths = append(paths, ln.Path{{x2, y, z1}, {x2, y, z2}})
	}
	return paths
}

构造实体几何(CSG)

可以使用Intersection、Difference、Union轻松构建复杂的实体:

shape := ln.NewDifference(
	ln.NewIntersection(
		ln.NewSphere(ln.Vector{}, 1),
		ln.NewCube(ln.Vector{-0.8, -0.8, -0.8}, ln.Vector{0.8, 0.8, 0.8}),
	),
	ln.NewCylinder(0.4, -2, 2),
	ln.NewTransformedShape(ln.NewCylinder(0.4, -2, 2), ln.Rotate(ln.Vector{1, 0, 0}, ln.Radians(90))),
	ln.NewTransformedShape(ln.NewCylinder(0.4, -2, 2), ln.Rotate(ln.Vector{0, 1, 0}, ln.Radians(90))),
)

这表示(球体 & 立方体) - (圆柱体 | 圆柱体 | 圆柱体)

Example


更多关于golang实现3D线条艺术渲染的高效插件库ln的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang实现3D线条艺术渲染的高效插件库ln的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用ln库实现3D线条艺术渲染

ln是一个用Go语言编写的高效3D线条艺术渲染库,它可以将3D场景渲染成具有艺术风格的线条画。下面我将介绍如何使用ln库来创建3D线条艺术效果。

安装ln库

首先安装ln库:

go get github.com/fogleman/ln/ln

基本使用示例

package main

import (
	"github.com/fogleman/ln/ln"
)

func main() {
	// 创建一个场景
	scene := ln.Scene{}
	
	// 添加一个立方体到场景
	cube := ln.NewCube(ln.Vector{-1, -1, -1}, ln.Vector{1, 1, 1})
	scene.Add(cube)
	
	// 定义相机位置和视角
	eye := ln.Vector{4, 3, 2}    // 相机位置
	center := ln.Vector{0, 0, 0} // 看向的中心点
	up := ln.Vector{0, 0, 1}     // 相机的上方向
	
	// 定义渲染参数
	width := 1024  // 图像宽度
	height := 1024 // 图像高度
	fovy := 50.0   // 视野角度
	step := 0.01   // 光线步进大小
	threshold := 0.1 // 阈值
	
	// 渲染场景
	paths := scene.Render(eye, center, up, width, height, fovy, step, threshold)
	
	// 保存为SVG文件
	paths.WriteToSVG("output.svg", width, height)
}

高级特性示例

1. 多种几何体组合

func main() {
	scene := ln.Scene{}
	
	// 添加各种几何体
	scene.Add(ln.NewCube(ln.Vector{-2, -2, -1}, ln.Vector{-1, -1, 1}))
	scene.Add(ln.NewSphere(ln.Vector{0, 0, 0}, 1))
	scene.Add(ln.NewCylinder(ln.Vector{1.5, 0, -1}, ln.Vector{1.5, 0, 1}, 0.5))
	
	// 渲染和保存
	paths := scene.Render(ln.Vector{5, 5, 3}, ln.Vector{0, 0, 0}, ln.Vector{0, 0, 1}, 1024, 1024, 50, 0.01, 0.1)
	paths.WriteToSVG("shapes.svg", 1024, 1024)
}

2. 自定义材质和颜色

type ColoredShape struct {
	Shape  ln.Shape
	Color  ln.Color
}

func (s *ColoredShape) Paths() ln.Paths {
	return s.Shape.Paths()
}

func main() {
	scene := ln.Scene{}
	
	// 创建带颜色的形状
	redSphere := &ColoredShape{ln.NewSphere(ln.Vector{-1, 0, 0}, 1), ln.Red}
	blueCube := &ColoredShape{ln.NewCube(ln.Vector{0, -1, -1}, ln.Vector{2, 1, 1}), ln.Blue}
	
	scene.Add(redSphere)
	scene.Add(blueCube)
	
	// 渲染
	paths := scene.Render(ln.Vector{4, 3, 2}, ln.Vector{0.5, 0, 0}, ln.Vector{0, 0, 1}, 1024, 1024, 50, 0.01, 0.1)
	
	// 保存为彩色SVG
	paths.WriteToColoredSVG("colored.svg", 1024, 1024)
}

3. 动画渲染

func main() {
	for i := 0; i < 36; i++ {
		scene := ln.Scene{}
		angle := float64(i) * 10
		x := 5 * math.Cos(angle*math.Pi/180)
		y := 5 * math.Sin(angle*math.Pi/180)
		
		scene.Add(ln.NewCube(ln.Vector{-1, -1, -1}, ln.Vector{1, 1, 1}))
		scene.Add(ln.NewSphere(ln.Vector{0, 0, 0}, 0.5))
		
		eye := ln.Vector{x, y, 3}
		paths := scene.Render(eye, ln.Vector{0, 0, 0}, ln.Vector{0, 0, 1}, 512, 512, 50, 0.01, 0.1)
		
		filename := fmt.Sprintf("frame%02d.svg", i)
		paths.WriteToSVG(filename, 512, 512)
	}
}

性能优化技巧

  1. **使用层次包围盒(BVH)**加速渲染:
scene := ln.Scene{}
// 添加物体...
bvh := ln.NewBVH(scene.Shapes)
paths := bvh.Render(eye, center, up, width, height, fovy, step, threshold)
  1. 调整步进大小和阈值以获得最佳质量/性能比:
// 更小的step和threshold会提高质量但降低性能
paths := scene.Render(eye, center, up, width, height, fovy, 0.005, 0.05)
  1. 降低分辨率进行快速预览:
// 快速预览使用小分辨率
previewPaths := scene.Render(eye, center, up, 256, 256, fovy, 0.01, 0.1)

ln库非常适合创建技术图解、艺术线条画和抽象可视化。它的输出是矢量图形(SVG),可以无限放大而不失真,非常适合打印或进一步编辑。

回到顶部