ui

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 31, 2022 License: MIT Imports: 34 Imported by: 0

README

SDFX-UI

GitHub go.mod Go version of a Go module Go Reference Go Go Report Card MIT license

SDFX-UI is a SDF (2D and 3D) renderer intended for fast development iterations that renders directly to a window. It integrates with your code as a library, meaning that you define your surface and then call the method that starts this UI.

The UI will listen for code updates (you can use your preferred code editor) and displays the new surfaces automatically with the same state (e.g., camera position).

Pull requests are welcome! The priority is to improve the user experience (making a proper UI or adding new capabilities) without losing performance.

Demo

Configuring the Renderer is as simple as creating your signed distance function and calling ui.NewRenderer(anySDF).Run().

package main

import (
	"github.com/Yeicor/sdfx-ui"
	"github.com/deadsy/sdfx/sdf"
)

func main() {
	anySDF, _ := sdf.Box3D(sdf.V3{X: 1, Y: 1, Z: 1}, 0.2)
	_ = ui.NewRenderer(anySDF).Run() // Error handling ignored
}

This is a demo of the workflow for designing your own SDF using this UI (code at examples/spiral/main.go):

Demo video

How does it work?

The first time you run the code, it starts the renderer process. It also starts listening for code changes. When a code change is detected, the app is recompiled by the renderer (taking advantage of Go's fast compilation times) and quickly renders the new surface to the same window (with the same camera position and other settings).

The SDF2 renderer shows the value of the SDF on each pixel using a grayscale: where bright pixels indicate outside the object and darker pixels are inside. The camera can be moved and scaled (using the mouse), rendering only the interesting part of the SDF.

SDF3s are raycasted from a perspective arc-ball camera that can be rotated around a pivot point, move its pivot and move closer or farther away from the pivot (using Blender-like mouse controls). Note that only the shown surface is actually rendered thanks to raycasting from the camera. This also means that the resulting surface can be much more detailed (depending on chosen resolution) than the triangle meshes generated by standard mesh generators.

There is an alternative SDF3 renderer (enabled via ui.Opt3Mesh(...)) which generates a triangle mesh using an algorithm from SDFX and then renders that triangle mesh to the screen thanks to FauxGL. It is a software renderer that is still very fast for our purposes (faster than the required mesh generation to use it). The main advantage over the raycast renderer is very fast camera movements and parameter updates, with the disadvantages of low (limited) detail and slower updates (as the initial mesh generation is slow).

SDFX-UI uses Ebiten for window management and rendering. Ebiten is cross-platform, so it could also be used to showcase a surface (without automatic updates) creating an application for desktop, web, mobile or Nintendo Switch™.

Browser and mobile

They use the same code as the demo, see compilation instructions at examples/spiral/main.go.

Screenshot_20220107_234547 Screenshot_20220107-234815220

Note that mobile only works with mouse and keyboard for now.

Other demos

Show bounding boxes:

Screenshot_20220226_205856

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Option

type Option = func(r *Renderer)

Option configures a Renderer to statically change its default behaviour.

func Opt2BBColor

func Opt2BBColor(getColor func(idx int) color.Color) Option

Opt2BBColor sets the bounding box colors for the different objects.

func Opt2Cam

func Opt2Cam(bb sdf.Box2) Option

Opt2Cam sets the default camera for SDF2 (may grow to follow the aspect ratio of the screen). WARNING: Need to run again the main renderer to apply a change of this option.

func Opt2EvalRange

func Opt2EvalRange(min, max float64) Option

Opt2EvalRange skips the initial scan of the SDF2 to find the minimum and maximum value, and can also be used to make the surface easier to see by setting them to a value close to 0.

func Opt2EvalScanCells

func Opt2EvalScanCells(cells sdf.V2i) Option

Opt2EvalScanCells configures the initial scan of the SDF2 to find minimum and maximum values (defaults to 128x128 cells).

func Opt3BBColor

func Opt3BBColor(getColor func(idx int) color.Color) Option

Opt3BBColor sets the bounding box colors for the different objects.

func Opt3Cam

func Opt3Cam(camCenter sdf.V3, pitch, yaw, dist float64) Option

Opt3Cam sets the default transform for the camera (pivot center, angles and distance). WARNING: Need to run again the main renderer to apply a change of this option.

func Opt3CamFov

func Opt3CamFov(fov float64) Option

Opt3CamFov sets the default Field Of View for the camera (default 90º, in radians).

func Opt3Colors

func Opt3Colors(surface, background, error color.RGBA) Option

Opt3Colors changes rendering colors.

func Opt3LightDir

func Opt3LightDir(lightDir sdf.V3) Option

Opt3LightDir sets the light direction for basic lighting simulation. Actually, two lights are simulated (the given one and the opposite one), as part of the surface would be hard to see otherwise

func Opt3Mesh

func Opt3Mesh(meshGenerator render.Render3, meshCells int, smoothNormalsRadians float64) Option

Opt3Mesh enables and configures the 3D mesh renderer instead of the default raycast based renderer WARNING: Should be the last option applied (as some other options might modify the SDF3).

func Opt3NormalEps

func Opt3NormalEps(normalEps float64) Option

Opt3NormalEps sets the distance between samples used to compute the normals.

func Opt3RayConfig

func Opt3RayConfig(scaleAndSigmoid, stepScale, epsilon float64, maxSteps int) Option

Opt3RayConfig sets the configuration for the raycast (balancing performance and quality). Rendering a pink pixel means that the ray reached maxSteps without hitting the surface or reaching the limit (consider increasing maxSteps (reduce performance), increasing epsilon or increasing stepScale (both reduce quality)).

func Opt3SwapYAndZ

func Opt3SwapYAndZ() Option

Opt3SwapYAndZ sets the UP direction to Y+ instead of Z+ (or swaps it back).

func OptMBackoff

func OptMBackoff(backOff backoff.BackOff) Option

OptMBackoff changes the default backoff algorithm used when trying to connect to the new code. WARNING: Need to run again the main renderer to apply a change of this option.

func OptMColorMode

func OptMColorMode(colorMode int) Option

OptMColorMode changes the default color mode of the renderer WARNING: Need to run again the main renderer to apply a change of this option.

func OptMPartialRenderEvery

func OptMPartialRenderEvery(duration time.Duration) Option

OptMPartialRenderEvery changes the default duration between partial renders (loading a partial render takes a little time and slows down the full render if too frequent). WARNING: Need to run again the main renderer to apply a change of this option.

func OptMResInv

func OptMResInv(resInv int) Option

OptMResInv changes the default image pixels per rendererd pixel WARNING: Need to run again the main renderer to apply a change of this option.

func OptMRunCommand

func OptMRunCommand(runCmd func() *exec.Cmd) Option

OptMRunCommand replaces the default run command (go run -v .) with any other command generator. WARNING: Need to run again the main renderer to apply a change of this option.

func OptMSmoothCamera

func OptMSmoothCamera(smoothCamera bool) Option

OptMSmoothCamera renders camera frames while dragging the mouse if enabled (2D/3D). Disabled by default. WARNING: Need to run again the main renderer to apply a change of this option.

func OptMWatchFiles

func OptMWatchFiles(filePaths []string) Option

OptMWatchFiles replaces the default set of files to watch for changes (["."]). WARNING: Need to run again the main renderer to apply a change of this option.

func OptMZoom

func OptMZoom(zoom float64) Option

OptMZoom changes the default scaling factor (> 1) WARNING: Need to run again the main renderer to apply a change of this option.

type Renderer

type Renderer struct {
	// contains filtered or unexported fields
}

Renderer is a SDF2/SDF3 renderer intended for fast development iterations that renders directly to a window. The first time, it starts the renderer process. It also starts listening for code changes. When a code change is detected, the app is recompiled (taking advantage of go's fast compilation times) by the renderer and communicates directly to the renderer, providing the new surface data to the previous window.

It allows very fast SDF updates (saving camera position) whenever the code changes, speeding up the modelling process. The renderer is mainly CPU-based (with a resolution parameter to control speed vs quality), as sdfx is also CPU-based. The scene is only rendered when something changes, as rendering SDFs with good quality is not real-time.

The SDF2 renderer is based on the PNG renderer, showing the image directly on screen (without creating the PNG file). The camera can be moved and scaled (using the mouse), rendering only the interesting part of the SDF.

SDF3s are raycasted from a perspective arc-ball camera that can be rotated around a pivot point, move its pivot and move closer or farther away from the pivot (using Blender-like mouse controls). Note that only the shown surface is actually rendered thanks to raycasting from the camera. This also means that the resulting surface can be much more detailed (depending on chosen resolution) than the triangle meshes generated by standard renderers.

TODO: Once merged, use max-resolution runtime-computed VoxelSdf2 and VoxelSdf3 to accelerate camera movements

It uses ebiten(https://github.com/hajimehoshi/ebiten) for rendering, which is cross-platform, so it could also be used to showcase a surface (without automatic updates) creating an application for desktop, web or mobile.

func NewRenderer

func NewRenderer(anySDF interface{}, opts ...Option) *Renderer

NewRenderer see Renderer

func (*Renderer) Run

func (r *Renderer) Run() error

Run starts the UI or connects to a previous UI renderer and provides the new surface automatically

type Watcher

type Watcher struct {
	Events chan fsEvent
	Errors chan error
}

Watcher watches a set of files, delivering events to a channel.

func (*Watcher) Add

func (w *Watcher) Add(name string) error

Add starts watching the named file or directory (non-recursively).

func (*Watcher) Close

func (w *Watcher) Close() error

Close removes all watches and closes the events channel.

func (*Watcher) Remove

func (w *Watcher) Remove(name string) error

Remove stops watching the the named file or directory (non-recursively).

Directories

Path Synopsis
examples
spiral
----------------------------------------------------------------------------- SOURCE: https://github.com/deadsy/sdfx/blob/master/examples/spiral/main.go Spirals -----------------------------------------------------------------------------
----------------------------------------------------------------------------- SOURCE: https://github.com/deadsy/sdfx/blob/master/examples/spiral/main.go Spirals -----------------------------------------------------------------------------

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL