Giter Site home page Giter Site logo

computemarchingcubes's Introduction

ComputeMarchingCubes

gif gif

ComputeMarchingCubes is a Unity sample project that reconstructs isosurfaces of scalar volume data using a compute shader and the new mesh API graphics buffer direct access).

It uses the classic marching cubes algorithm for isosurface reconstruction. The implementation is based on Paul Bourke's article but partially modified for GPU optimization.

System requirements

  • Unity 2021.2.0 a19 or later
  • Compute shader capable system

What's inside

This project contains two sample scenes:

Note that the configuration of the volume data is hardcoded in the sample script/shader. You have to implement a data parser to support a specific volume data format.

computemarchingcubes's People

Contributors

keijiro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

computemarchingcubes's Issues

Work on Hololens or VR devices?

Dear Keijiro,

Do you know if this would work on Hololens 2 or VR devices?
Thank you for sharing your knowledge!

Kind Regards!

How Do I Add A Collider?

This may be a silly question, but I was wondering how to add a collider to a mesh that has been marched by the compute shader.
For example, in NoiseFieldVisualizer.cs, I tried adding an extra line for defining the collider's sharedMesh as follows.

GetComponent<MeshFilter>().sharedMesh = _builder.Mesh;
GetComponent<MeshCollider>().sharedMesh = _builder.Mesh; // added by me

But this causes Unity to crash when I press the Play button.

Crash Log
Obtained 37 stack frames.
#0  0x007f4a04b39980 in funlockfile
#1  0x005635ccce1e2a in WeldVertexArray(dynamic_array<Vector3f, 0ul>&, dynamic_array<BoneWeights4, 0ul>&, dynamic_array<unsigned int, 0ul>&, dynamic_array<unsigned int, 0ul>&)
#2  0x005635ccce1eb3 in WeldVertexArray(dynamic_array<Vector3f, 0ul>&, dynamic_array<unsigned int, 0ul>&, dynamic_array<unsigned int, 0ul>&)
#3  0x005635ccf02b3d in ExtractDataFromMesh(Mesh&, dynamic_array<Vector3f, 0ul>&, dynamic_array<unsigned int, 0ul>&, dynamic_array<unsigned int, 0ul>&, bool)
#4  0x005635ccef3565 in CookAnyPhysicsMeshInAnyMode(Mesh*, bool, MeshColliderCookingOptions, Matrix4x4f const&, TransformType, MemoryStream*)
#5  0x005635ccef33a3 in CreatePxMeshFromUnityMesh(Mesh*, bool, MeshColliderCookingOptions, Matrix4x4f const&, TransformType)
#6  0x005635ccee9bf2 in CollisionMeshData::GetSharedNxMesh(Mesh&)
#7  0x005635ccf3a64e in MeshCollider::ExtractMeshGeometry(Vector3f&, bool&)
#8  0x005635ccf3aa23 in MeshCollider::Create(Rigidbody const*)
#9  0x005635cc5a64b9 in MeshCollider_Set_Custom_PropSharedMesh(ScriptingBackendNativeObjectPtrOpaque*, ScriptingBackendNativeObjectPtrOpaque*)
#10 0x0000004112ab2c in (wrapper managed-to-native) UnityEngine.MeshCollider:set_sharedMesh (UnityEngine.MeshCollider,UnityEngine.Mesh)
#11 0x007f487bb01228 in mono_get_runtime_build_info
#12 0x007f487bc9ff0e in mono_runtime_invoke
#13 0x007f487bc9fe58 in mono_runtime_invoke
#14 0x005635cd07ee63 in scripting_method_invoke(ScriptingMethodPtr, ScriptingObjectPtr, ScriptingArguments&, ScriptingExceptionPtr*, bool)
#15 0x005635cd07a9a7 in ScriptingInvocation::Invoke(ScriptingExceptionPtr*, bool)
#16 0x005635cd0207ec in MonoBehaviour::CallMethodIfAvailable(int)
#17 0x005635cd02065f in MonoBehaviour::CallUpdateMethod(int)
#18 0x005635ccab816c in void BaseBehaviourManager::CommonUpdate<BehaviourManager>()
#19 0x005635ccab7f88 in BehaviourManager::Update()
#20 0x005635ccce4f2b in InitPlayerLoopCallbacks()::UpdateScriptRunBehaviourUpdateRegistrator::Forward()
#21 0x005635cccd7c97 in ExecutePlayerLoop(NativePlayerLoopSystem*)
#22 0x005635cccd7c53 in ExecutePlayerLoop(NativePlayerLoopSystem*)
#23 0x005635cccd7fc8 in PlayerLoop()
#24 0x005635ce1c5bee in EditorPlayerLoop::Execute()
#25 0x005635ce1c63dd in PlayerLoopController::UpdateScene(bool)
#26 0x005635ce1c6d19 in PlayerLoopController::EnterPlayMode()
#27 0x005635ce1be62b in PlayerLoopController::SetIsPlaying(bool)
#28 0x005635ce1bc7e1 in Application::TickTimer()
#29 0x005635ce259d5a in MainMessageIteration(void*)
#30 0x007f4a05aac3a5 in g_main_context_dispatch
#31 0x007f4a05aac770 in g_main_context_dispatch
#32 0x007f4a05aaca82 in g_main_loop_run
#33 0x007f4a06ab3a25 in gtk_main
#34 0x005635ce258f17 in main
#35 0x007f4a04757c87 in __libc_start_main
#36 0x005635cc441029 in _start

Obviously this isn't the intended use case, but I just want to know what would need to be done in order to get it to work.
I'm not quite sure what's going on, but it looks we're not able to correctly extract the mesh data in order to create the mesh collider like this.
Do I need to move the mesh data to the CPU somehow? If so, how do I do that?
I'm new to Compute Shaders, so a detailed explanation would be greatly appreciated.

Custom Volume Data Format Parser

First of all, great implementation!

I am using my custom volume data format want to parse it as stanford's but found nothing about data shape/format in the link that you attached in the readme. Or we can leave aside my data format, simply I have Texture3D with RGBA32 colors, I just want to save this as the stanford's. Do you have any advice?

How would you implement a grid resolution factor?

Hello @keijiro !

Thank you for this amazing implementation. One question arose while we've tried it, how would you implement a grid resolution parameter as in Paul Bourke's article to steer the resolution of the mesh? By just increasing sampling distances in the volume?

Greetings

Dominique

PS: Talking about this
image

My first guess would be the increase the sampling in the MeshConstruction shader from:

[numthreads(4, 4, 4)]
void MeshReconstruction(uint3 id : SV_DispatchThreadID)
{
    // Boundary check
    if (any(id + 1 >= Dims.xyz)) return;

    // Voxel samples at each cube vertex
    float4 samples[8];
    for (uint i = 0; i < 8; i++)
        samples[i] = VoxelValueWithGradient(id + CubeVertex(i));

// ...
}

to something like

uint samplingDistance;

[numthreads(4, 4, 4)]
void MeshReconstruction(uint3 id : SV_DispatchThreadID)
{
    id = id * samplingDistance;
    // Boundary check
    if (any(id + 1 >= Dims.xyz)) return;

    // Voxel samples at each cube vertex
    float4 samples[8];
    for (uint i = 0; i < 8; i++)
        samples[i] = VoxelValueWithGradient(id + CubeVertex(i));

// ...
}

and modifying the threadgroups by this samplingDistance:

   int samplingDistance = 1;
    void RunCompute(ComputeBuffer voxels, float target, float scale)
    {
        _counterBuffer.SetCounterValue(0);

        var downSampledGrids = new Vector3Int(_grids.x / samplingDistance, _grids.y / samplingDistance, _grids.z / samplingDistance);

        // Isosurface reconstruction
        _compute.SetInt("samplingDistance", samplingDistance);
        _compute.SetInts("Dims", downSampledGrids );
        _compute.SetInt("MaxTriangle", _triangleBudget);
        _compute.SetFloat("Scale", scale);
        _compute.SetFloat("Isovalue", target);
        _compute.SetBuffer(0, "TriangleTable", _triangleTable);
        _compute.SetBuffer(0, "Voxels", voxels);
        _compute.SetBuffer(0, "VertexBuffer", _vertexBuffer);
        _compute.SetBuffer(0, "IndexBuffer", _indexBuffer);
        _compute.SetBuffer(0, "Counter", _counterBuffer);
        _compute.DispatchThreads(0, downSampledGrids );

        // Clear unused area of the buffers.
        _compute.SetBuffer(1, "VertexBuffer", _vertexBuffer);
        _compute.SetBuffer(1, "IndexBuffer", _indexBuffer);
        _compute.SetBuffer(1, "Counter", _counterBuffer);
        _compute.DispatchThreads(1, 1, 1, 1);

        // Bounding box
        var ext = new Vector3(_grids.x, _grids.y, _grids.z) * scale;
        _mesh.bounds = new Bounds(Vector3.zero, ext);
    }

error CS1061: 'Mesh' does not contain a definition for 'indexBufferTarget' and no accessible extension method 'indexBufferTarget'

Go the following error when using 2021.1.11f1 version

Assets\MarchingCubes\Script\MeshBuilder.cs(102,15): error CS1061: 'Mesh' does not contain a definition for 'indexBufferTarget' and no accessible extension method 'indexBufferTarget' accepting a first argument of type 'Mesh' could be found (are you missing a using directive or an assembly reference?)

is there a specific version to open the project?

best

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.