Skip to content

Commit

Permalink
all: avoid using pointer for parameters
Browse files Browse the repository at this point in the history
This change re-writes the vector and matrix utilities and avoid using pointers
in function parameters and return type. See golang.design/s/research for details.

Benchmarks:
name                                old time/op  new time/op  delta
LoadObj-16                           102ms ± 0%   102ms ± 1%    ~     (p=0.631 n=10+10)
Rasterizer/concurrent-size_1-16     52.2ms ± 1%  53.1ms ± 1%  +1.87%  (p=0.000 n=10+10)
Rasterizer/concurrent-size_2-16     26.9ms ± 1%  26.7ms ± 1%  -0.69%  (p=0.004 n=10+10)
Rasterizer/concurrent-size_4-16     15.1ms ± 0%  14.5ms ± 0%  -4.53%  (p=0.000 n=10+10)
Rasterizer/concurrent-size_8-16     10.0ms ± 0%   9.2ms ± 1%  -8.07%  (p=0.000 n=10+10)
Rasterizer/concurrent-size_16-16    8.01ms ± 0%  7.50ms ± 1%  -6.34%  (p=0.000 n=9+10)
Rasterizer/concurrent-size_32-16    7.43ms ± 0%  6.98ms ± 1%  -5.93%  (p=0.000 n=9+10)
Rasterizer/concurrent-size_64-16    7.26ms ± 0%  6.81ms ± 1%  -6.25%  (p=0.000 n=9+10)
Rasterizer/concurrent-size_128-16   7.18ms ± 0%  6.72ms ± 0%  -6.41%  (p=0.000 n=10+10)
Rasterizer/concurrent-size_256-16   7.19ms ± 0%  6.72ms ± 1%  -6.49%  (p=0.000 n=10+10)
Rasterizer/concurrent-size_512-16   7.17ms ± 0%  6.74ms ± 1%  -6.11%  (p=0.000 n=10+9)
Rasterizer/concurrent-size_1024-16  7.35ms ± 0%  6.87ms ± 0%  -6.56%  (p=0.000 n=9+9)
  • Loading branch information
changkun committed Oct 29, 2020
1 parent abb5404 commit 60fba10
Show file tree
Hide file tree
Showing 12 changed files with 303 additions and 377 deletions.
57 changes: 29 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ if err != nil {
}

// set model matrix
scale := ddd.NewVector(1500, 1500, 1500, 0)
trans := ddd.NewVector(-700, -5, 350, 1)
m.SetScale(&scale)
m.SetTranslate(&trans)
m.SetScale(ddd.Vector{1500, 1500, 1500, 0})
m.SetTranslate(ddd.Vector{-700, -5, 350, 1})

// set texture
err = m.SetTexture("path/to/texture.jpg", 150)
Expand All @@ -29,17 +27,17 @@ if err != nil {
}

// set the camera
r.SetCamera(ddd.NewPerspectiveCamera( // perspective
ddd.NewVector(-550, 194, 734, 1),
ddd.NewVector(-1000, 0, 0, 1),
ddd.NewVector(0, 1, 1, 0),
r.SetCamera(ddd.NewPerspectiveCamera(
ddd.Vector{-550, 194, 734, 1},
ddd.Vector{-1000, 0, 0, 1},
ddd.Vector{0, 1, 1, 0},
float64(width)/float64(height),
100, 600, 45,
))
r.SetCamera(ddd.NewOrthographicCamera( // orthographic
ddd.NewVector(-550, 194, 734, 1),
ddd.NewVector(-1000, 0, 0, 1),
ddd.NewVector(0, 1, 1, 0),
r.SetCamera(ddd.NewOrthographicCamera(
ddd.Vector{-550, 194, 734, 1},
ddd.Vector{-1000, 0, 0, 1},
ddd.Vector{0, 1, 1, 0},
-float64(width)/2, float64(width)/2,
float64(height)/2, -float64(height)/2,
200, -200,
Expand All @@ -51,7 +49,7 @@ r.SetScene(s)
s.AddMesh(m)
l := ddd.NewPointLight(
color.RGBA{255, 255, 255, 255},
ddd.NewVector(-200, 250, 600, 1), 0.5, 0.6, 1,
ddd.Vector{-200, 250, 600, 1}, 0.5, 0.6, 1,
)
s.AddLight(l)

Expand All @@ -68,23 +66,26 @@ See complete example [here](./bench/main.go).

## Benchmark

The CPU rasterizer can render the bench example ~100fps:

```go
render perf: 96.52797559309442 fps
render perf: 98.54559512522535 fps
render perf: 100.3256067567289 fps
render perf: 102.2571423546220 fps
render perf: 99.58160787451523 fps
render perf: 98.61453481600944 fps
render perf: 101.7631275961046 fps
render perf: 102.1985880038684 fps
render perf: 94.79118639132228 fps
render perf: 95.41987464309389 fps
The CPU rasterizer can render the bench example ~200fps:

```sh

$ cd bench && go build
$ for i in {1..10}; do perflock -governor 80% ./bench; done
BenchmarkRasterizer 243 4915913 ns/op 203.42101253622673 fps
BenchmarkRasterizer 244 4891938 ns/op 204.41796277875966 fps
BenchmarkRasterizer 242 4884135 ns/op 204.74454534938118 fps
BenchmarkRasterizer 237 4897988 ns/op 204.16546549317803 fps
BenchmarkRasterizer 243 4886564 ns/op 204.64277148523993 fps
BenchmarkRasterizer 243 4912620 ns/op 203.55736857318496 fps
BenchmarkRasterizer 244 4950226 ns/op 202.01097889268084 fps
BenchmarkRasterizer 242 4871713 ns/op 205.26660745409265 fps
BenchmarkRasterizer 244 4926549 ns/op 202.9818438830102 fps
BenchmarkRasterizer 244 4880202 ns/op 204.9095508751482 fps
$ inxi -C
CPU: Topology: 8-Core model: Intel Core i9-9900K bits: 64 type: MT MCP L2 cache: 16.0 MiB Speed: 800 MHz min/max: 800/5000 MHz Core speeds (MHz): 1: 800 2: 800 3: 800 4: 800 5: 800 6: 800 7: 800 8: 801 9: 800 10: 800 11: 800 12: 800 13: 800 14: 800 15: 800 16: 800
```

See more about pprof.

## License

GNU GPLv3 © [Changkun Ou](https://changkun.de)
22 changes: 10 additions & 12 deletions bench/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,8 @@ func main() {
}

// set model matrix
scale := ddd.NewVector(1500, 1500, 1500, 0)
trans := ddd.NewVector(-700, -5, 350, 1)
m.SetScale(&scale)
m.SetTranslate(&trans)
m.SetScale(ddd.Vector{1500, 1500, 1500, 0})
m.SetTranslate(ddd.Vector{-700, -5, 350, 1})

// set texture
err = m.SetTexture("../tests/texture.jpg", 150)
Expand All @@ -36,16 +34,16 @@ func main() {

// set the camera
r.SetCamera(ddd.NewPerspectiveCamera(
ddd.NewVector(-550, 194, 734, 1),
ddd.NewVector(-1000, 0, 0, 1),
ddd.NewVector(0, 1, 1, 0),
ddd.Vector{-550, 194, 734, 1},
ddd.Vector{-1000, 0, 0, 1},
ddd.Vector{0, 1, 1, 0},
float64(width)/float64(height),
100, 600, 45,
))
r.SetCamera(ddd.NewOrthographicCamera(
ddd.NewVector(-550, 194, 734, 1),
ddd.NewVector(-1000, 0, 0, 1),
ddd.NewVector(0, 1, 1, 0),
ddd.Vector{-550, 194, 734, 1},
ddd.Vector{-1000, 0, 0, 1},
ddd.Vector{0, 1, 1, 0},
-float64(width)/2, float64(width)/2,
float64(height)/2, -float64(height)/2,
200, -200,
Expand All @@ -57,7 +55,7 @@ func main() {
s.AddMesh(m)
l := ddd.NewPointLight(
color.RGBA{255, 255, 255, 255},
ddd.NewVector(-200, 250, 600, 1), 0.5, 0.6, 1,
ddd.Vector{-200, 250, 600, 1}, 0.5, 0.6, 1,
)
s.AddLight(l)

Expand All @@ -71,5 +69,5 @@ func main() {
})

ns := result.NsPerOp()
fmt.Printf("render perf: %v fps\n", 1/(time.Duration(ns)).Seconds())
fmt.Printf("BenchmarkRasterizer\t%v\t%v ns/op\t%v fps\n", result.N, ns, 1/(time.Duration(ns)).Seconds())
}
Binary file modified bench/render.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 11 additions & 15 deletions camera.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,12 @@ func (c OrthorgraphicCamera) GetUp() Vector {

// GetProjectionMatrix returns the projection matrix
func (c OrthorgraphicCamera) GetProjectionMatrix() Matrix {
m := NewMatrix()
m.Set(
2/(c.Right-c.Left), 0, 0, (c.Left+c.Right)/(c.Left-c.Right),
0, 2/(c.Top-c.Bottom), 0, (c.Bottom+c.Top)/(c.Bottom-c.Top),
0, 0, 2/(c.Near-c.Far), (c.Far+c.Near)/(c.Far-c.Near),
return Matrix{
2 / (c.Right - c.Left), 0, 0, (c.Left + c.Right) / (c.Left - c.Right),
0, 2 / (c.Top - c.Bottom), 0, (c.Bottom + c.Top) / (c.Bottom - c.Top),
0, 0, 2 / (c.Near - c.Far), (c.Far + c.Near) / (c.Far - c.Near),
0, 0, 0, 1,
)
return m
}
}

// NewOrthographicCamera returns a new orthographic camera with the given params
Expand Down Expand Up @@ -123,13 +121,11 @@ func (c PerspectiveCamera) GetUp() Vector {

// GetProjectionMatrix returns the projection matrix
func (c PerspectiveCamera) GetProjectionMatrix() Matrix {
m := NewMatrix()
m.Set(
-1/(c.Aspect*math.Tan(c.FOV*math.Pi/360)), 0, 0, 0,
0, -1/(math.Tan(c.FOV*math.Pi/360)), 0, 0,
0, 0, (c.Near+c.Far)/(c.Near-c.Far),
2*(c.Near*c.Far)/(c.Near-c.Far),
return Matrix{
-1 / (c.Aspect * math.Tan(c.FOV*math.Pi/360)), 0, 0, 0,
0, -1 / (math.Tan(c.FOV * math.Pi / 360)), 0, 0,
0, 0, (c.Near + c.Far) / (c.Near - c.Far),
2 * (c.Near * c.Far) / (c.Near - c.Far),
0, 0, 1, 0,
)
return m
}
}
Loading

0 comments on commit 60fba10

Please sign in to comment.