-
Notifications
You must be signed in to change notification settings - Fork 0
Design 3D
The scenegraph is rooted at a gi3d.Scene
node which is like gi.Viewport2D
, where the scene is rendered, similar to the svg.SVG
node for SVG drawings.
Children of the Scene are Node3D
nodes, with Group
and Solid
as the main subtypes. Node3DBase
is the base implementation, which has a Pose
for the full matrix transform of relative position, scale, rotation, and bounding boxes at multiple levels.
-
Group
is a container -- most discrete objects should be organized into a Group, with Groups of Solids underneath. For maximum efficiency it is important to organize large scenegraphs into hierarchical groups by location, so that regions can be pruned for rendering. The Pose on the Group is inherited by everything under it, so things can be transformed at different levels as well. -
Solid
has aMaterial
to define the color / texture of the solid, and the name of aMesh
that defines the shape.
Objects that have uniform Material color properties on all surfaces can be a single Solid, but if you need e.g., different textures for each side of a box then that must be represented as a Group of Solids using Plane Mesh's, each of which can then bind to a different Texture via their Material settings.
Node bounding boxes are in both local and World reference frames, and are used for visibility and event selection.
All Meshes are stored directly on the Scene, and must have unique names, as they are referenced from Solids by name. The Mesh contains all the verticies, etc that define a shape, and are the major memory-consuming elements of the scene (along with textures). Thus, the Solid is very lightweight and just points to the Mesh, so Meshes can be reused across multiple Solids for efficiency.
Meshes are only indexed triangles, and there are standard shapes such as Box, Sphere, Cylinder, Capsule, and Line (rendered as a thin Box with end points specified).
Textures are also stored by unique names on the Scene, and the Material can optionally refer to a texture -- likewise allowing efficient re-use across different Solids.
The Scene also contains a Library of uniquely-named "objects" (Groups) which can be loaded from 3D object files, and then added into the scenegraph as needed. Thus, a typical, efficient workflow is to initialize a Library of such objects, and then configure the specific scene from these objects. The library objects are Cloned into the scenegraph -- because the Group and Solid nodes are lightweight, this is all very efficient.
The Scene also holds the Camera and Lights for rendering -- there is no point in putting these out in the scenegraph -- if you want to add a Solid representing one of these elements, you can easily do so.
The Scene is fully in charge of the rendering process by iterating over the scene elements and culling out-of-view elements, ordering opaque then transparent elements, etc.
There are standard Render types that manage the relevant GPU programs / Pipelines to do the actual rendering, depending on Material and Mesh properties (e.g., uniform vs per-vertex color vs. texture).
Current strategy is to start with OpenGL and get stuff working, and then migrate to Vulkan in a second step. Key is to develop a good strategy overall that will be portable.
How to code opengl to be vulkan-friendly:
- https://developer.nvidia.com/opengl-vulkan
- https://www.slideshare.net/CassEveritt/approaching-zero-driver-overhead
- http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-9-vbo-indexing/
- key overall point is to batch as much stuff as possible, combining as much junk into one big vertex and index list, and just using everything as triangles (or trianglestrip -- latter should be more efficient but need to research), using drawelements instead of arrays (i.e., use indexing)
- in vulkan GLSL, all bindings are specified explicitly, but this is not possible in 4.1 which we need to stick with for mac os compatibility. thus, need to abstract over bindings.
-
each program deals with a particular case: opaque, transparent, shadows, etc -- most efficient to batch everything according to these factors. transparent comes last. and within that, faces need to be sorted.
-
shadows etc require multiple programs and steps and sorting..
-
Vertex and Fragment shaders need to use Uniform Buffer Objects (UBO) which can be shared across programs and more quickly updated.
-
in 2D, it was critical to maintain computed bounding boxes to optimize rendering part and event processing -- same principle.
-
while could use GPU to precompute bounding boxes: https://www.gamedev.net/articles/programming/graphics/computation-of-bounding-primitives-on-the-gpu-r2582/ -- typically we won't actually have so many objects, and each object itself can be more complex, so easier just to do it all on the CPU. Mesh has the original bbox info which just needs to be xformed.
-
https://github.com/vulkan-go -- has everything except MoltenVK and SDK
- glfw -- have an update to go-gl/glfw that supports 3.3 pre-version -- need this!
- demos -- work!
- asche -- higher-level api -- need to investigate.
-
vulkan sdk download: https://vulkan.lunarg.com/doc/sdk/1.1.101.0/mac/getting_started.html
- make install:
$ tar -xzf vulkan-sdk.tar.gz
$ cd vulkansdk-macos-1.1.101.0/
$ sudo cp -av MoltenVK/macOS/framework/MoltenVK.framework /Library/Frameworks/
$ sudo cp -av macOS/Frameworks/vulkan.framework /Library/Frameworks/
-
brew install glslang
- not needed: https://github.com/KhronosGroup/glslang/releases/tag/master-tot -- get glslangValidator that compiles glsl shader language in to vulkan SPIRV byte-code
-
MoltenVK maps Vulkan onto Apple's Metal -- just a few things missing.
-
install is a bit lengthy, and no homebrew avail: https://github.com/KhronosGroup/MoltenVK/issues/509
-
brew cask install apenngrace/vulkan/vulkan-sdk fails
-
glfw is often used to create a vulkan window etc: https://www.glfw.org/index.html -- 3.3 is 98% done but not yet..
-
https://github.com/go-gl/glfw wrapper for glfw 3.2.1 is available, but it DOES NOT support vulkan as far as I can tell. updated one in vulkan-go does..