当前位置:网站首页>Unity uses mesh to realize real-time point cloud (I)
Unity uses mesh to realize real-time point cloud (I)
2022-07-07 09:24:00 【heater404】
Unity Use Mesh Realize real-time point cloud ( One )
One 、 Rendering things
unity Is based on mesh To do the rendering , In other words, I want to unity If you see something in it , Must use mesh. It can come from other software 3D Import the model , It can be generated dynamically with code , It can also be a sprite、UI Elements or particle systems .
mesh It is a framework used by graphics hardware to draw complex things , It contains at least one set of vertices ( These vertices are coordinates in three-dimensional space ) And a set of triangles connecting these points ( The most basic 2D shape ). These triangles together make up any mesh The shape of the surface represented by . Because the triangle is flat , It's the edge of a straight line , So they can be used to perfectly show things that are flat and straight ,unity Zhongmo believes that we have created capsules 、 Cube 、 Sphere and other models , stay scene There is a drop-down menu under the window of Wire frame, You can see the wireframe display , That is to say mesh grid .
If you want to use a GameObject Show me a 3D Model , Then it must have two components :
- mesh filter: It determines which one you want to show mesh
- mesh renderer: It determines how you should render mesh, Like what kind of shaders to use , Whether to receive shadows or projections .
Why? material It's plural ?
mesh renderer There can be multiple materials. This is mainly used to draw a mesh, be called subMesh. these subMesh From the imported 3D Model . No discussion here .
Through adjustment mesh Of material, Can completely change mesh The performance of the ,unity The default material is pure white , You can create a new shader by yourself , And drag it to the GameObject to replace it . The new shader uses unity Standard shaders for , It opens up a set of settings that allow you to adjust different visual effects .
Texture and mesh What does it matter
towards mesh A quick way to add a lot of detail in is to provide a albedo maps. This is a texture map , Used to represent the basic color of a shader , Texture maps are only long and wide 2 Dimensions , and mesh It's often a three-dimensional object , So to achieve this goal , We need to know how to project this texture onto the mesh On the triangle of . This is done by adding two-dimensional texture coordinates to the vertices . The two dimensions of texture space are called u and v, This is why they are called uv coordinate . These coordinates are usually located in (0,0) and (1,1) Between , Covering the entire texture map . Set according to the texture , Coordinates outside this range are either tightened , Or lead to tiled.
Two 、 Custom vertex mesh
Now let's create a simple planar mesh , First create an empty game object and then create a script
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class MyGrid : MonoBehaviour
{
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
RequireComponent The feature will automatically record the corresponding components on the mounted object . And then to mesh renderer Set the material , Give Way mesh filter Keep unreferenced .
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class MyGrid : MonoBehaviour
{
// The size of the rectangular grid The unit is the number of vertices
const int width = 10, height = 5;
private Vector3[] vectices;
private int[] indices;
private Color[] colors;
// Use this for initialization
void Start()
{
vectices = new Vector3[width * height];
indices = new int[width * height];
colors = new Color[width * height];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
vectices[i * width + j] = new Vector3(j, i);
indices[i * width + j] = i * width + j;
colors[i * width + j] = Color.green;
}
}
var mesh = GetComponent<MeshFilter>().mesh;
mesh.vertices = vectices;
mesh.SetIndices(indices,MeshTopology.Points,0);
mesh.colors = colors;
}
}
Here's a detail , Material standard shader The color of vertices will not be displayed , Unless put shader Set to particles One of them .
mesh The basic unit of can be set , We mentioned above that triangles are just one of them , from MeshTopology Enumeration type determines .
although , Our point is Points, But I still want to talk about triangles, Because you can trade by the way uv coordinate .
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class MyGrid : MonoBehaviour
{
// The size of the rectangular grid The unit is the number of vertices
const int width = 10, height = 5;
private Vector3[] vectices;
private int[] indices;
private Color[] colors;
private int[] triangles;
// Use this for initialization
void Start()
{
vectices = new Vector3[width * height];
indices = new int[width * height];
colors = new Color[width * height];
triangles = new int[width * height * 6];// Number of triangles
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
var index = i * width + j;
vectices[index] = new Vector3(j, i);
indices[index] = index;
colors[index] = Color.green;
if (i < height - 1 && j < width - 1)
{
triangles[6 * index] = index;// Vertex Index
triangles[6 * index + 1] = triangles[6 * index + 4] = index + width;
triangles[6 * index + 2] = triangles[6 * index + 3] = index + 1;
triangles[6 * index + 5] = index + width + 1;
}
}
}
var mesh = GetComponent<MeshFilter>().mesh;
mesh.vertices = vectices;
mesh.colors = colors;
mesh.triangles = triangles;
}
}
But then we have a question ? The texture of our material ? It turns out that if you don't provide uv coordinate , Then they are all the default values, that is, zero , Therefore, each vertex color is the color of the pixel whose mapping texture coordinate is zero .
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class MyGrid : MonoBehaviour
{
// The size of the rectangular grid The unit is the number of vertices
const int width = 10, height = 5;
private Vector3[] vectices;
private int[] indices;
private Color[] colors;
private int[] triangles;
private Vector2[] uvs;
// Use this for initialization
void Start()
{
vectices = new Vector3[width * height];
indices = new int[width * height];
colors = new Color[width * height];
triangles = new int[width * height * 6];// Number of triangles
uvs = new Vector2[width * height];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
var index = i * width + j;
vectices[index] = new Vector3(j, i);
indices[index] = index;
colors[index] = Color.green;
uvs[index] = new Vector2(j * 1.0f / (width - 1), i * 1.0f / (height - 1));
if (i < height - 1 && j < width - 1)
{
triangles[6 * index] = index;// Vertex Index
triangles[6 * index + 1] = triangles[6 * index + 4] = index + width;
triangles[6 * index + 2] = triangles[6 * index + 3] = index + 1;
triangles[6 * index + 5] = index + width + 1;
}
}
}
var mesh = GetComponent<MeshFilter>().mesh;
mesh.vertices = vectices;
mesh.colors = colors;
mesh.triangles = triangles;
mesh.uv = uvs;
}
}
If you want to completely cover the texture map mesh On , Just calculate the proportion (uv The coordinate range is [0,1]). Finally, we need to change the material shader Set to standard .
The color is darker because Light Why .
3、 ... and 、 Point cloud
When making point clouds, we usually use MeshTopology.Points, Not a triangle .
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class PointCloud : MonoBehaviour
{
// The size of the rectangular grid The unit is the number of vertices
const int width = 1000, height = 500;
private Vector3[] positions;
private int[] indices;
private Color[] colors;
private Mesh mesh;
// Use this for initialization
void Start()
{
positions = new Vector3[width * height];
indices = new int[width * height];
colors = new Color[width * height];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
var index = i * width + j;
positions[index] = new Vector3(0,0,0);
indices[index] = index;
colors[index] = Color.green;
}
}
mesh = GetComponent<MeshFilter>().mesh;
mesh.vertices = positions;
mesh.colors = colors;
mesh.SetIndices(indices, MeshTopology.Points, 0);
StartCoroutine(UpdatePositions());
}
IEnumerator UpdatePositions()
{
while (true)
{
var a = Random.Range(10, 500);
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
var index = i * width + j;
positions[index] = new Vector3(j - width / 2, i, a * Mathf.Sin((j - width / 2) / 10.0f));
//indices[index] = index;
//colors[index] = Color.green;
//uvs[index] = new Vector2(j * 1.0f / (width - 1), i * 1.0f / (height - 1));
}
}
mesh.vertices = positions;
yield return new WaitForSeconds(1);
}
}
}
because , Want to make a dynamic update , So I wrote a co process interval 1 Update the coordinates in seconds . Then in order to facilitate the rotation of the point cloud , We need to achieve IDragHandler Interface , There are several points to pay attention to when using this interface :
- The camera needs to be mounted PhysicsRaycaster Script
- The scene needs EventSystem object
- The object to mount the script needs a Collider
And because of our point cloud mesh yes Points, It has no triangle structure , So it can't be used as mesh collider Of mesh, We have no choice but to use BoxCollider. Here comes the question ,BoxCollider Of Bounds How much should it be ?
We're customizing mesh You can use it directly mesh.RecalculateBounds(); To refresh mesh Of Bounds, And then through mesh.bounds; Direct access to .
void CalcBoxColliderBounds()
{
mesh.RecalculateBounds();
this.GetComponent<BoxCollider>().center = mesh.bounds.center;
this.GetComponent<BoxCollider>().size = mesh.bounds.size;
}
Then call this method every time you update the vertex coordinates of the point cloud . Finally, you need to implement the interface IDragHandler.
public void OnDrag(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Right)
{
this.transform.Rotate(eventData.delta.y, eventData.delta.x, 0);
}
}
Call this method when the cloud top coordinates . Finally, you need to implement the interface IDragHandler.
public void OnDrag(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Right)
{
this.transform.Rotate(eventData.delta.y, eventData.delta.x, 0);
}
}
But there is a problem , When the vertex refresh rate increases CPU Consumption will rise , So can we be in GPU Update vertex coordinates in ? Then we need to use Shader. Use Mesh Realize real-time point cloud ( Two )
边栏推荐
- Yapi test plug-in -- cross request
- Locust performance test 3 (high concurrency, parameter correlation, assembly point)
- How to use Arthas to view class variable values
- Regular matching starts with XXX and ends with XXX
- MySql数据库-索引-学习笔记
- Add new item after the outbound delivery order of SAP mm sto document is created?
- Postman interface test (II. Set global variables \ sets)
- 数据库多表关联查询问题
- Mysql:select ... for update
- JVM 垃圾回收 详细学习笔记(二)
猜你喜欢
External interrupt to realize key experiment
C language pointer (exercises)
Upgrade Alibaba cloud RDS (relational database service) instance to com mysql. jdbc. exceptions. Troubleshooting of jdbc4.communicationsexception
Huawei HCIP - datacom - Core 03 jours
超十万字_超详细SSM整合实践_手动实现权限管理
Locust performance test 4 (custom load Policy)
H3C vxlan configuration
Serial port experiment - simple data sending and receiving
Jmeters use
Hard core sharing: a common toolkit for hardware engineers
随机推荐
JVM garbage collection detailed learning notes (II)
PMP Exam Preparation experience, seek common ground while reserving differences, and successfully pass the exam
How to use Arthas to view class variable values
JVM 内存结构 详细学习笔记(一)
Huawei hcip datacom core_ 03day
Over 100000 words_ Ultra detailed SSM integration practice_ Manually implement permission management
Data association between two interfaces of postman
E-commerce campaign Guide
正则匹配以XXX开头的,XXX结束的
2021 year end summary
Chaosblade: introduction to chaos Engineering (I)
What is the value of getting a PMP certificate?
Full link voltage test of the e-commerce campaign Guide
C language pointer (Part 1)
Storage of data in memory
flex弹性布局
Locust performance test 2 (interface request)
Idea development environment installation
sqlplus乱码问题,求解答
STM32 serial port register library function configuration method