Code Monkey home page Code Monkey logo

pointcloudexporter's Introduction

PointCloudExporter

(This ReadMe was made from a tutorial I've written for Sketchfab.)

Hi! My name is Leon Denise, I’m an independant artist programmer.
I draw comics, make games, code shaders, hug trees and talk to cows.
You can visit my portfolio: leon196.github.io
And my gif gallery: giphy.com/leondenise

In this tutorial, I’m going to explain how I did the Simon Splash.

The point cloud data was made with Agisoft Photoscan.
The mesh was generated with Unity3D.

About the project

The project is a point cloud tool used for generative art. It is a real-time software that generates triangle particles from a point cloud and displace them in a vector field with specific rules for velocity behavior. The tool also export the generated particles into a standard 3d mesh and bake the vertex colors into a map with generated texture coordinates.

The motivation

The motivation came from the fact that point cloud viewers are not very advanced, since point clouds are not the real matter of 3d worlds such as video games. When you zoom in, points stay as dots, it creates to me a frustration that needs to be satisfied.

So I’ve coded a program that generate triangles from the dots, taking position, normal and color. I’m sharing the source code of the program, it’s a simplified version (no GPU particles) of my point cloud engine. For the sake of comprehension and because the advanced version is part of a commercial project.

How to

Export a point cloud

After you have generated a point cloud in your favourite software, export it as PLY format: binary encoding with position, normal and color.

Exemples with Agisoft Photoscan and MeshLab:

My PLY importer C# script is pretty naive and there is chances that it won’t work with a PLY exported from a different software. If you improve the importer script, and like to share, do not hesitate to send a pull request on the git repository.

Start the Unity3D project

Download, install Unity3D and grab the project at: github.com/leon196/PointCloudExporter
If you don’t know how to use git, find the download zip button:

You will find the scripts and shaders used to generate triangle mesh from a point cloud.

If you don’t know about Unity3D, the official documentation is great and there is plenty tutorial resources over the web. To use the tool, open the scene “PointCloudExporter”. Start the play button, select the PointCloud game object in the hierarchy window, so you can adjust parameters in the inspector window.

The main script is PointCloudGenerator.

Change parameters

Load parameters

PointCloudGenerator will load a file in the StreamingAssets folder and automatically adds the .ply extension.
That’s why File Name is just “Simon2”.
You can adjust the Maximum Vertices count to get more details.

Renderer parameters

Size is the radius of the triangle.
Sprite allows you to choose a texture for the triangle.

About the sprite

The texture used for the sprite must have clamp wrap mode and disabling mipmapping give better results. Since we use triangles instead of quads for performance, the UV mapping is sized to cover the triangle.

On the left, sprite with clamp wrap mode. On the right, sprite with repeat wrap mode.

About the shader

You can check the Shader code used to generate triangles. (warning: geometry shader stuff)

If you inspect the “Generate” function in the PointCloudGenerator script, there is a part where it creates mesh with point topology. So the script create a mesh with no triangles, only points. Then a geometry shader is generating triangle from point.

If you change the shader for “Unlit/Color” for example, you will get this render: points.

With the PointCloud shader, you will get this render: triangles with color and direction.

Here is a scary screenshot with hieroglyph characters known as shader language code. That part shows a function that create a triangle from a point: a geometry shader.

The challenge is to display triangles that will face a certain direction. Manipulating vertex in a shader is about parallelism and knowing if a point in space belong to a triangle requires storing data into vertices. I’m using geometry shader mainly because you can not setup custom attributes for vertices in Unity3D. (There are tricks, but let’s keep it simple for this tutorial)

Displace parameters

Should is the ratio that selects which particles should be displaced.
Time is the duration of the displacement.
Speed is the velocity unit.
Noise Scale is the level of details of the Perlin noise.
Noise Speed is the coefficient of the noise offset.
Target Speed is the coefficient of the target offset.
Noisy is like salt, it adds a grain to coefficients.

The displacement behaviour can be found in the “Displace” function. This simple version is about two vectors: a smooth random direction and moving away from a point in space. This is where you can adjust and customize the displacement behaviour.

Baking parameters

Details is a sort of level of details for color.
Circle Radius is the size of the color on the map.
Shader Baked is the shader to use when triangle mesh is generated.

A baked map with 4 as details.

A baked map with 16 as details.

Because you can’t always have custom shader, you can’t set the triangle color from the vertices color attribute. That’s why this tool have a baking map colors, so the mesh can be imported on Sketchfab or any 3d viewer. If you inspect the baked mesh, you will find the generated texture coordinates.

Action buttons

Generate is triggered when pressing start button, and can be used to reload point cloud.
Reset will move the vertices to their original positions.
Displace will start a displacement sequence, with the chosen parameters.
Export will create a mesh ready to be exported. (it does not create a file on the disk)
Save Baked Colors will open a save dialog window, asking where you write the texture file.

To export the model, you have to press the export button. It will create a triangle topology mesh that will replace the point topology mesh. Then you can use the script ExportOBJ from the UnifyCommunity, that is already in the project. It works like this: select any game object, click through File / Export / Wavefron OBJ.

If everything worked out, you should be able to import it in you favourite 3D software, and then share it on Sketchfab!

Voilà !

I hope it will work at the first try for your point cloud data. It’s an open source work in progress project, so there is unstable code, optimizable algorithm and performance issues.
Also after an export, you will have to generate again a point topology mesh, to be able to displace again. There is a lot of things that could be improved.

Thanks for reading through this whole article. You can find more open source resources and personnal projects on my little compilation repository: github.com/leon196/Workshop
Also I’m spamming gifs on Twitter: twitter.com/leondenise

pointcloudexporter's People

Contributors

artcg avatar leon196 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  avatar  avatar  avatar  avatar

pointcloudexporter's Issues

Display PointCloud via code

Hi,

I do now want to import files.

I would like to display a simple list of points via your code using C#.
How can I do it?

Export to obj/ply/webm programatically

I thought to create new instead here
@leon196 not sure about this but how can i programatically (what function to call etc) export to obj (or any format to which it currently can export ) ? without using the unity export menu ? Thank you

Also related , how possible is it to export to .webm format?

[Solved]Problem importing from Photoscan .PLY

I received this error (FormatException: Input string was not in the correct format) with any ply file except Simon2. I've managed to modify the SimpleImporter.cs script but I'm new with GitHub, so I'll post the part that I modified here.
I noticed that the "element vertex" array.Length returns 3 from Simon2, but 9 on my files and the Convert.IntTo32 needed to return 2 (on Simon2 is "Array.Length - 1"), so I added an int to subtract the Array.Length to always return 2. Now it works with all the ply tested by me.

Here is the part of the code, with the int subtractor added by me

`
else if (lineText.Contains ("element vertex")) {

								string[] array = lineText.Split (' ');
								if (array.Length > 0) {
									int subtractor = array.Length - 2;
									vertexCount = Convert.ToInt32 (array [array.Length - subtractor]);
									if (vertexCount > maximumVertex) {
										levelOfDetails = 1 + (int)Mathf.Floor (vertexCount / maximumVertex);
										vertexCount = maximumVertex;
									}
									data.vertexCount = vertexCount;
									data.vertices = new Vector3[vertexCount];
									data.normals = new Vector3[vertexCount];
									data.colors = new Color[vertexCount];
								}`

Normals calculation seems to be wrong

Hello!

I just try to give a try to the project, but I realized that the normals were a bit off, I tried to plot with Gizmoz the normal of a given vertex, and realized an offset between the shader normal and the vertex normal.

Here the black line is the vertex normal, it can be appreciate that does not run across the shader surface.

Do you know what might be causing this?

image

Code used to draw this:

private void OnDrawGizmos()
		{
			int meshInfosIndex = 0;
			for (int meshIndex = 0; meshIndex < meshArray.Length; ++meshIndex)
			{
				Mesh mesh = meshArray[meshIndex];

				Vector3[] vertices = mesh.vertices;
				Vector3[] normals = mesh.normals;

				Matrix4x4 matrixWorld = transform.localToWorldMatrix;
				Matrix4x4 matrixLocal = transform.worldToLocalMatrix;

				for (int vertexIndex = 0; vertexIndex < vertices.Length; ++vertexIndex)
				{
					if (vertexIndex == vertexID)
					{
						Vector3 position = matrixWorld.MultiplyVector(vertices[vertexIndex]) + transform.position;
						Vector3 normal = normals[vertexIndex];

						Gizmos.color = Color.green;
						Gizmos.DrawSphere(position, 0.01f);
						
						Gizmos.color = Color.black;
						Gizmos.DrawLine(normal * -1 + position, normal * 1 + position);
					}
					++meshInfosIndex;
				}
			}

		}

```

Colors missing

Hi ! thanks for the project. Being kind of a newbie in shaders, I tried to launch the project and tweak parameters, even trying with my own ply file. However, I haven't been able to have colors on the point clou (keeps being all flashy purple).
Would you have any clue ?
Thanks !

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.