• Stars
    star
    350
  • Rank 121,229 (Top 3 %)
  • Language
    C#
  • License
    MIT License
  • Created over 4 years ago
  • Updated 12 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A Unity package to make runtime procedural mesh generation more flexible.

BMeshUnity Logo

BMesh for Unity

This Unity package is a library to make runtime procedural mesh generation as flexible as possible.

The mesh structure is similar to the one used in Blender, and a mechanism for adding arbitrary attributes to vertices/edges/loops/faces is available, for instance for people used to Houdini's wrangle nodes.

Unreal Engine This library has been ported to Unreal Engine by Daniel Amthauer: https://github.com/daniel-amthauer/BMeshUnreal

Getting Started

Installation

This is a standard git-based package:

  1. Open the package manager.

Package Manager

  1. Click on "+" in the upper-left corner of the Package Manager, and chose "Add package from git URL..."

Add package from git URL

  1. In the text field, paste https://github.com/eliemichel/BMeshUnity.git:

Pasting this repos' URL

You should now see the BMesh package in the Package Manager:

BMesh package in the Package Manager

First script

We start with a very simple and detailed example:

  1. Create a new script, we'll call it for instance MyMeshGenerator.cs:

Creating a new script

  1. Create an object on which we will attach the script, take any 3D object, we'll replace its mesh.

Creating a new object

  1. Add the script to the object, make sure you have at least a "MeshFilter", a "MeshRenderer" and your script "MyMeshGenerator" visible in the inspector (if one is missing, just add it).

Components include MeshFilter, MeshRenderer, MyMeshGenerator

  1. In MyMeshGenerator.cs, we write:
using UnityEngine;
using static BMesh; // otherwise you'll have to write "BMesh.Vertex" etc.

public class MyMeshGenerator : MonoBehaviour
{
    void Start()
    {
        // Create a new empty mesh
        BMesh mesh = new BMesh();

        // Add a few vertices
        Vertex v1 = mesh.AddVertex(-1, 0, -1);
        Vertex v2 = mesh.AddVertex( 1, 0, -1);
        Vertex v3 = mesh.AddVertex( 1, 0,  1);
        Vertex v4 = mesh.AddVertex(-1, 0,  1);

        // Add a face using the vertices
        mesh.AddFace(v1, v2, v3, v4);

        // Set the current mesh filter to use our generated mesh
        BMeshUnity.SetInMeshFilter(mesh, GetComponent<MeshFilter>());
    }
}

Don't forget the SetInMeshFilter to make the mesh visible in the game. A BMesh is a mesh optimized for procedural generation and manipulation, but not for rendering. This line converts it to the rendering-oriented mesh structure used by Unity and replace the previous mesh with it in the "MeshFilter" component. You should now see a plane when starting the game:

A plane

At this point, the BMesh structure is destructed as soon as the Start() function is done, so that all we are left is the rendering-oriented Mesh. This is good in general, but for debugging it can quickly become usefull to keep a reference to it, for instance to draw debug information in the viewport:

using UnityEngine;
using static BMesh; // otherwise you'll have to write "BMesh.Vertex" etc.

public class MyMeshGenerator : MonoBehaviour
{
    BMesh mesh; // We keep a reference to the BMesh

    void Start()
    {
        mesh = new BMesh();
        Vertex v1 = mesh.AddVertex(-1, 0, -1);
        Vertex v2 = mesh.AddVertex( 1, 0, -1);
        Vertex v3 = mesh.AddVertex( 1, 0,  1);
        Vertex v4 = mesh.AddVertex(-1, 0,  1);
        mesh.AddFace(v1, v2, v3, v4);

        // Set the current mesh filter to use our generated mesh
        BMeshUnity.SetInMeshFilter(mesh, GetComponent<MeshFilter>());
    }

    // In the editor, draw some debug information about the mesh
    private void OnDrawGizmos()
    {
        if (mesh != null)
        {
        	Gizmos.matrix = transform.localToWorldMatrix;
            BMeshUnity.DrawGizmos(mesh);
        }
    }
}

Thus in the viewport you can now see some debug overlay showing the BMesh' edges, loops, etc. This can be even used for BMeshes that are not yet set in a mesh filter.

A plane gizmo

A sligthly more advanced example

A wave

using UnityEngine;
using static BMesh;

public class MyMeshGenerator : MonoBehaviour
{
    public int width = 15;
    public int height = 15;

    BMesh mesh;

    BMesh GenerateGrid() {
        BMesh bm = new BMesh();
        for (int j = 0; j < height; ++j) {
            for (int i = 0; i < width; ++i) {
                bm.AddVertex(i, 0, j); // vertex # i + j * w
                if (i > 0 && j > 0) bm.AddFace(i + j * width, i - 1 + j * width, i - 1 + (j - 1) * width, i + (j - 1) * width);
            }
        }
        return bm;
    }

    void Start() {
        mesh = GenerateGrid();
        foreach (Vertex v in mesh.vertices) {
            v.point.y = Mathf.Sin(v.point.x + v.point.z); // Vertical displacement
        }
        BMeshUnity.SetInMeshFilter(mesh, GetComponent<MeshFilter>());
    }

    private void OnDrawGizmos() {
        Gizmos.matrix = transform.localToWorldMatrix;
        if (mesh != null) BMeshUnity.DrawGizmos(mesh);
    }
}

Texture coordinates

You can add UVs to the generated mesh using a custom vertex attributes called "uv".

using UnityEngine;
using static BMesh;

public class MyMeshGenerator : MonoBehaviour
{
    void Start()
    {
        // Same beginning as the first example
        BMesh mesh = new BMesh();
        Vertex v1 = mesh.AddVertex(-1, 0, -1);
        Vertex v2 = mesh.AddVertex(1, 0, -1);
        Vertex v3 = mesh.AddVertex(1, 0, 1);
        Vertex v4 = mesh.AddVertex(-1, 0, 1);
        mesh.AddFace(v1, v2, v3, v4);

        // Add UVs
        // First define a vertex attribute called "uv" which is made of 2 floats
        var uv = mesh.AddVertexAttribute("uv", AttributeBaseType.Float, 2);
        
        // Then fill it in in each vertex
        v1.attributes["uv"] = new FloatAttributeValue(0.0f, 0.0f);
        v2.attributes["uv"] = new FloatAttributeValue(1.0f, 0.0f);
        v3.attributes["uv"] = new FloatAttributeValue(1.0f, 1.0f);
        v4.attributes["uv"] = new FloatAttributeValue(0.0f, 1.0f);

        BMeshUnity.SetInMeshFilter(mesh, GetComponent<MeshFilter>());
    }
}

Custom attributes

Custom attributes like UVs can be attached to any of the points, vertices or faces. They may be Float or Int and have an arbitrary size. They may be used for your own generation purposes, but the following ones have a particular meaning when calling SetInMeshFilter():

Attribute Name Attachement Type Interpretation
uv Vertex Float2 Primary texture coordinate
uv2 Vertex Float2 Secondary texture coordinate
normal Vertex Float3 Normal vector at each vertex. If not present, normals are automatically calculated using RecalculateNormals
color Vertex Float3 Vertex color
materialId Face Int1 Index of the material to use in the renderer.materials array

Going further

Now that you know the basics, you can simply look at the source files, they are commented before each function.

Contributing

This library is still young, and far from being a complete toolkit. Whenever you find yourself writing operators that are somehow reusable, you are more than welcome to contribute back, by sending a pull request here for instance. Contribution can also be the identification of weak parts of the current design of the library.

More Repositories

1

MapsModelsImporter

A Blender add-on to import models from google maps
Python
2,414
star
2

LilySurfaceScraper

Import shaders end environments in Blender from a single URL
Cython
596
star
3

LearnWebGPU

Learn to use WebGPU for native graphic applications in C++
C++
383
star
4

WebGPU-Cpp

A single-file zero-overhead C++ idiomatic wrapper for WebGPU native
C++
277
star
5

HoudiniEngineForBlender

Branch of Blender featuring a Houdini Engine based modifier
181
star
6

OpenMfxForBlender

A branch of Blender featuring an OpenMfx modifier
C
176
star
7

DagAmendment

The official implementation of the research paper "DAG Amendment for Inverse Control of Parametric Shapes"
C++
171
star
8

OpenMfx

A low-overhead mesh-processing plug-in API for cross-software procedural effects
C
161
star
9

WebGPU-distribution

Distributions of WebGPU for native and web development, easy to integrate and interchangeable.
CMake
145
star
10

LearnWebGPU-Code

The accompanying code of the Learn WebGPU C++ programming guide
99
star
11

BlenderImgui

Custom GUI for your Blender add-ons using Dear ImGui
Python
94
star
12

glfw3webgpu

An extension for the GLFW library for using WebGPU native.
C
62
star
13

LilyRender360

Lily Render 360 is a tool for rendering a Unity scene into stitch-free equirectangular images
C#
59
star
14

MfxHoudini

A Houdini-Engine based Open Mesh Effect
C
57
star
15

AdvancedBlenderAddon

A starter kit and reference for writing advanced Blender add-ons
Python
39
star
16

Python3dViewer

A simple starter Python code for experimenting 3D graphics
Python
30
star
17

sdl2webgpu

An extension for the SDL2 library for using WebGPU native.
C
25
star
18

MesoGen

The official implementation of MesoGen: Designing Procedural On-Surface Stranded Mesostructures (Siggraph 2023)
C++
24
star
19

RayStep

A real-time 3D distance field modeling software
C++
22
star
20

MapsModelsImporter-samples

Sample file to check MapsModelsImporter installation
20
star
21

LilyImageFromURL

A very very simple Blender add-on to very very quickly import images from URLs.
Python
17
star
22

GrainViewer

The official implementation of the research paper "Real-time multiscale rendering of dense dynamic stackings"
C++
13
star
23

MonumentValley

A little toy reproducing Monument Alley basic mechanism in Unity
C#
12
star
24

MfxVCG

An OpenMfx plug-in providing effects from VCGlib
C++
12
star
25

WebGPU-utils

A bunch of utility functions for WebGPU
C++
11
star
26

WebGPU-AutoLayout

An online utility tool to generate C++ boilerplate binding code by parsing WGSL.
Rust
10
star
27

TownBuilder

This is an experiment around the reproduction of Stalberg's Townscaper
C#
10
star
28

IRL

Inverse Reinforcement Learning
Jupyter Notebook
9
star
29

CodenameGogh

A node-based front-end to ffmpeg
C++
8
star
30

MfxExamples

An example of OpenMfx plug-in using the C++ SDK
C++
7
star
31

ModernGlad

Depreciation warnings to help writing more modern OpenGL using glad
Python
7
star
32

AugenLight

A cross-plateform OpenGL 4.5 starter kit
C++
6
star
33

firefox-webmention-addon

Firefox add-on to send webmentions though context menu
JavaScript
6
star
34

WebGPU-binaries

A CMake-ready binary release of a WebGPU native implementation (wgpu-native)
C
6
star
35

GreaseJs

A little demo of Grease Pencil using ThreeJS
JavaScript
6
star
36

sphinx_literate

An advanced literate programming tool for writing incremental programming courses.
Python
6
star
37

IvyGenerator

Update of Thomas Luft's original
C++
5
star
38

PythonMfx

A Python-based host for running OpenMfx mesh processing plugins
Python
5
star
39

WebGPU-Cpp-WebBackend

This is the backend of the Web service of https://github.com/eliemichel/WebGPU-Cpp
C++
5
star
40

fxos-AlphaRemote

A Firefox OS remote controller for Sony Alpha series cameras
JavaScript
4
star
41

AlignTools

Alignment tools add-on for Blender
Python
4
star
42

BiharmonicCoords

Webpage for the SIGGRAPH 24 paper "Biharmonic Coordinates and their Derivatives for Triangular 3D Cages"
HTML
4
star
43

WebGPU-raii

An RAII wrapper around the objects of the WebGPU native API.
C++
4
star
44

reshade

Fork ReShade adding Remote Control feature
C++
3
star
45

Cooldown

Feed rythm into live-coding tools
Rust
3
star
46

ReACORN

An attempt to reimplement ACORN
Python
3
star
47

WebMfx

A web-based host for OpenMfx using WASM plugins
C
3
star
48

PolyGreenCoords

Public page of "Polynomial 2D Green Coordinates for Polygonal Cages"(Siggraph 2023)
HTML
3
star
49

StatDeps

A lightweight C++ dependency graph library for compile-time dependent resource management.
C++
3
star
50

cartes-electorales

Python
2
star
51

MfxPlugins

Simple Open Mesh Effect plugins
C++
2
star
52

highspeedracer

Online racing game using Blender Game Engine
Python
2
star
53

LilyFuture

A header-only utiliy library to make std:futures fun to use!
C++
2
star
54

todo

A dead simple command line TODO-list manager
Python
2
star
55

Spillr

Mixed GLSL/C++ static C++ processor aiming at reducing boilerplate in shader writing
OCaml
2
star
56

UnitySsPattern

A screen space shader for Unity with object tracking
ShaderLab
2
star
57

SdfManipulation

Public page of "Direct Manipulation of Analytic Implicit Surfaces"(Siggraph Asia 2024)
HTML
2
star
58

webgpu-doc-jam

Set up for an incoming documentation jam of webgpu-headers, stay tuned!
2
star
59

JeuDePresse

Dessins d'actualité interactifs, produits en quelques heures avec MS Paint
JavaScript
2
star
60

irssi-notify

Notifications for Irssi via a simple http server
Python
1
star
61

WorLd

Simple 2D strategy game whom levels are autogenerated based on mathematical assertions
C++
1
star
62

texdown

Extension of markdown to support mathematics. Based on marked and MathJax.
JavaScript
1
star
63

join.js

The smallest JS library to love promises
JavaScript
1
star
64

fake-position

Firefox addon to spoof geolocation using openstreetmap
JavaScript
1
star
65

ColorSpaceViewer

A browser-based tool for visualizing images in color space
JavaScript
1
star
66

fHMM

Project for the lecture of Probabilistic Graphical Models
TeX
1
star
67

MemoryIDF

Code source du jeu Memory pour l'Ile de France, inspiré de la version pour Paris
HTML
1
star
68

OscToSpout

Forward OSC messages to KodeLife using a texture-sharing via Spout
C++
1
star
69

Dawn

Custom branches of Dawn for the Learn WebGPU for C++ guide
C++
1
star
70

PolyworldJs

Low-poly styled dynamic forest in ThreeJS
JavaScript
1
star
71

ZigDawn

Starter C++ project for using WebGPU native
C
1
star