登录 用户中心() [退出] 后台管理 注册
   
您的位置: 首页 >> SoftHub关联区 >> 主题: [u3d][五星推荐]Mesh网格编程(一) 流体[zt 有非常多的知识点]     [回主站]     [分站链接]
[u3d][五星推荐]Mesh网格编程(一) 流体[zt 有非常多的知识点]
clq
浏览(631) - 2020-01-30 23:33:36 发表 编辑

关键字: u3d

[2020-01-31 00:02:32 最后更新]
[u3d][五星推荐]Mesh网格编程(一) 流体[zt 有非常多的知识点]

这些知识点其实也可以应用到别的 3d 引擎中。

--------------------------------------------------
很重要的知识点为:
1.物体变形方法关键是动态修改 GetComponent().mesh
2.物体曲面光滑的主要方面是计算法线(实际上应该是法线和切线,法线垂直于平面,切线又与法线垂直)
3.大多数情况下可以使用 mesh.RecalculateNormals(); 自动计算法线,似乎这个函数能自动计算出平滑度。

参考 https://www.cnblogs.com/naterliu/articles/4580218.html
Unity3D —— model文件平滑方法
通过maya设计的3D模型,往往都有很多菱角,为了让模型更加圆滑、自然、流畅,可以设置模型的Model属性面板,将Normals & Tangents下的Normals设置为Calculate,Tangents也设为Calculate,再讲Smoothing Angle设为180即可。

参考 http://blog.sina.com.cn/s/blog_427cf00b0102vqwe.html
"
unity3d 与3dmaxs多边形平滑组的关系
总结:​​
1. 在3d maxs中,选中所有的面,然后进行平滑组光滑,你会发现,虽然经过平滑,但是顶点和面数都没有变化​
2. 如果不经过平滑,模型导入unity后,棱角很尖锐,经过平滑后,模型导入unity后,会变得很平滑​
温馨提示:​
如果棱角过硬,shader不容易表现​
棱角平滑,shader容易表现,主要是在平滑倒角的地方,有高光出现,立体感很强​
"

https://zhuanlan.zhihu.com/p/103546030?utm_source=qq
这个讲解了很多法线的概念。法线只是一个方向,一般最大值就取 1 ,然后按角度算出其他的小数这样的。

参考 https://www.cnblogs.com/answer-yj/p/11295175.html
有一个非常复杂有用的圆柱网道计算方法。
大多数情况下可以使用 mesh.RecalculateNormals(); 自动计算法线,似乎这个函数能自动计算出平滑度。
"切记别忘了重新计算法线mesh.RecalculateNormals();这才出预期效果。"


--------------------------------------------------
https://blog.csdn.net/m0_37283423/article/details/70749579

Mesh网格编程(一) 流体水

通过Mesh网格随Sin函数实时变化模拟液体的流动,从而达到动态水的效果。
效果图:

Mesh网格编程步骤:
一:确定数量
确定该几何图形应有多少个三角形面,顶点坐标、顶点序列、UV贴图、法线向量皆为三角形面数的三倍。
二:根据三角形面确定顶点坐标
这里我习惯把一个面的顶点确定好之后再去找下一个面,这样做可以是法线和顶点序列确定起来很容易。但是要注意的是在确定顶点时要按照顺时针顺序确定,否则会导致三角形面相反。
三:确定法线
法线大致分为两种:
其一是棱角分明的几何体,这种几何体的法线可以用确定好的顶点坐标两两相减,得到的向量做叉乘并赋值给三个顶点上的法线。
其二是圆滑的几何体,这种几何体需要求出该点在曲面上的切线,从而确定垂直于切线的法线。如果是圆形。可以使用顶点减圆心所得的向量。
此外,求得的法线尽量单位化,否则可能出现一个面上的颜色不同。
四:确定顶点序列
若三角形顶点按照面数去确定,顶点序列就会变得非常简单,按顺序赋值即可。
五:确定UV贴图
根据所做几何体的不同,贴图左边也会有所改变,并不固定。
六:创建网格

实现代码如下:
[csharp] view plain copy

using UnityEngine;
using System.Collections;

public class Water : MonoBehaviour {

Mesh mesh;

public int tier = 10; //长度分段
private float length = 10; //长
private int width = 3; //宽
private int hight = 10; //高

private Vector3[] vs; //顶点坐标
private int[] ts; //顶点序列
private Vector2[] newUVs; //UV贴图
private Vector3[] newNormals; //法线

void Update () {

int temp = ((tier + 1) * 8 + 4) * 3; //确定顶点数量

vs = new Vector3[temp];
ts = new int[temp];
newUVs = new Vector2[temp];
newNormals = new Vector3[temp];

float dis = 2 * Mathf.PI / tier; //两段之差的横坐标

int count = 0;
for (int i = 0; i < tier; i++) {

float pos1 = i * length / tier - length / 2;
float pos2 = (i + 1) * length / tier - length / 2;
//顶面顶点坐标
vs[count] = new Vector3(pos1,Mathf.Sin(Time.time + i * dis), width);
vs[count + 1] = new Vector3(pos2,Mathf.Sin(Time.time + (i + 1) * dis), -width);
vs[count + 2] = new Vector3(pos1,Mathf.Sin(Time.time + i * dis), -width);

vs[count + 3] = new Vector3(pos1,Mathf.Sin(Time.time + i * dis), width);
vs[count + 4] = new Vector3(pos2,Mathf.Sin(Time.time + (i + 1) * dis), width);
vs[count + 5] = new Vector3(pos2,Mathf.Sin(Time.time + (i + 1) * dis), -width);
//顶面法线
newNormals[count] = Vector3.Normalize(new Vector3(1,Mathf.Cos(Time.time + i * dis), 0));
newNormals[count + 1] = Vector3.Normalize(new Vector3(1,Mathf.Cos(Time.time + (i + 1) * dis), 0));
newNormals[count + 2] = Vector3.Normalize(new Vector3(1,Mathf.Cos(Time.time + i * dis), 0));

newNormals[count + 3] = Vector3.Normalize(new Vector3(1,Mathf.Cos(Time.time + i * dis), 0));
newNormals[count + 4] = Vector3.Normalize(new Vector3(1,Mathf.Cos(Time.time + (i + 1) * dis), 0));
newNormals[count + 5] = Vector3.Normalize(new Vector3(1,Mathf.Cos(Time.time + (i + 1) * dis), 0));

//前面顶点坐标
vs[count + 6] = new Vector3(pos1,Mathf.Sin(Time.time + i * dis), -width);
vs[count + 7] = new Vector3(pos2,-hight, -width);
vs[count + 8] = new Vector3(pos1,-hight, -width);

vs[count + 9] = new Vector3(pos1,Mathf.Sin(Time.time + i * dis), -width);
vs[count + 10] = new Vector3(pos2,Mathf.Sin(Time.time + (i + 1) * dis), -width);
vs[count + 11] = new Vector3(pos2,-hight, -width);
//前面法线
for (int j = 0; j < 6; j++) {
newNormals[count + 6 + j] = Vector3.back;
}
//后面顶点坐标
vs[count + 12] = new Vector3(pos1,Mathf.Sin(Time.time + i * dis), width);
vs[count + 13] = new Vector3(pos1,-hight, width);
vs[count + 14] = new Vector3(pos2,-hight, width);

vs[count + 15] = new Vector3(pos1,Mathf.Sin(Time.time + i * dis), width);
vs[count + 16] = new Vector3(pos2,-hight, width);
vs[count + 17] = new Vector3(pos2,Mathf.Sin(Time.time + (i + 1) * dis), width);
//后面法线
for (int j = 0; j < 6; j++) {
newNormals[count + 12 + j] = Vector3.forward;
}
//下面顶点坐标
vs[count + 18] = new Vector3(pos1,-hight, width);
vs[count + 19] = new Vector3(pos1,-hight, -width);
vs[count + 20] = new Vector3(pos2,-hight, -width);

vs[count + 21] = new Vector3(pos1,-hight, width);
vs[count + 22] = new Vector3(pos2,-hight, -width);
vs[count + 23] = new Vector3(pos2,-hight, width);
//下面法线
for (int j = 0; j < 6; j++) {
newNormals[count + 18 + j] = Vector3.down;
}

count += 24;
}

//两侧顶点坐标及法线
vs [vs.Length - 12] = new Vector3 (-length / 2, Mathf.Sin (Time.time), width);
vs [vs.Length - 11] = new Vector3 (-length / 2, -hight, -width);
vs [vs.Length - 10] = new Vector3 (-length / 2, -hight, width);

vs [vs.Length - 9] = new Vector3 (-length / 2, Mathf.Sin (Time.time), width);
vs [vs.Length - 8] = new Vector3 (-length / 2, Mathf.Sin (Time.time), -width);
vs [vs.Length - 7] = new Vector3 (-length / 2, -hight, -width);

for (int j = 0; j < 6; j++) {
newNormals[vs.Length - 12 + j] = Vector3.left;
}

vs [vs.Length - 6] = new Vector3 (length / 2, Mathf.Sin (Time.time + tier * dis), width);
vs [vs.Length - 5] = new Vector3 (length / 2, -hight, width);
vs [vs.Length - 4] = new Vector3 (length / 2, -hight, -width);

vs [vs.Length - 3] = new Vector3 (length / 2, Mathf.Sin (Time.time + tier * dis), width);
vs [vs.Length - 2] = new Vector3 (length / 2, -hight, -width);
vs [vs.Length - 1] = new Vector3 (length / 2, Mathf.Sin (Time.time + tier * dis), -width);

for (int j = 0; j < 6; j++) {
newNormals[vs.Length - 6 + j] = Vector3.right;
}

for (int i = 0; i < ts.Length; i++) { //顶点序列赋值
ts[i] = i;
}

mesh = new Mesh();
GetComponent().mesh = mesh;
mesh.vertices = vs;
mesh.uv = newUVs;
mesh.triangles = ts;
mesh.normals = newNormals;
}
}


注:波浪上方的面为曲面,故使用切线求法线。其他面很有规则,并没有使用叉乘的方法。
几何体没有使用UV贴图,newUVs没有赋值。



[图片]

总数:0 页次:1/0 首页 尾页  
总数:0 页次:1/0 首页 尾页  


所在合集/目录
u3d平滑 更多



发表评论:
文本/html模式切换 插入图片 文本/html模式切换


附件:



NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.

Copyright © 2005-2020 clq, All Rights Reserved
版权所有
桂ICP备15002303号-1