unity 制作3D等温图
来源:互联网 发布:鲍勃.马利 知乎 编辑:程序博客网 时间:2024/04/28 00:02
3D等温图的制作过程
思路1
动态生成mesh
动态生成texture2D
将texture2D通过uv赋值
思路2
动态生成mesh
通过赋值mesh.color赋值颜色
思路2过于复杂,对于我有点难度,选择1
mesh生成通过贝塞尔曲线使它更加光滑
实现代码如下
private void CreatMeshWithValue() {BezierTerrain bezier = new BezierTerrain(); //va,vb....为vector3[]数组,bezier.CreatPath方法会返回一个贝塞尔曲线的路径 object[] allV = new object[]{bezier.CreatPath(va,6),bezier.CreatPath(vb,6),bezier.CreatPath(vc,6),bezier.CreatPath(vd,6),bezier.CreatPath(ve,6),bezier.CreatPath(vf,6),bezier.CreatPath(vg,6)};float MaxMinValue = 12f;List<object> allC = new List<object>();foreach (Vector3[] v in allV){List<Color> colorArr = new List<Color>();foreach (Vector3 item in v){float value = (item.y / MaxMinValue) * 4 * 255;Color color;if (0f <= value && value < 255){color = new Color(0f, value, 255f);}else if (value >= 255f && value < 510f){color = new Color(0, 255f, 255f - (value - 255f));}else if (value >= 510f && value < 765f){color = new Color((value - 510f), 255f, 0f);}else{color = new Color(255, 255f - (value - 765f), 0f);}colorArr.Add(color);}allC.Add(colorArr.ToArray());}object[] a = allC.ToArray();MeshWithVector3sColors(allV, allC.ToArray());}//meshvoid MeshWithVector3sColors(object[] allV,object[] allC) {MeshFilter meshFilter = this.gameObject.GetComponent<MeshFilter>();Mesh mesh = new Mesh();mesh.name = "ColorMesh";//顶点数量int verticesCount = allV.Length * (allV[0] as Vector3[]).Length;Vector3[] vertices = new Vector3[verticesCount];//三角形数量int triangles_count = (allV.Length - 1) * ((allV[0] as Vector3[]).Length - 1 ) * 2 ;//三角形顶点IDint[] triangles = new int[triangles_count * 3];//Color[] colorCount = new Color[verticesCount];int index_v = 0;//Vector2[] uvs = new Vector2[verticesCount];//vertice colorfor (int i = 0; i < allV.Length; i++) {Vector3[] vi = allV[i] as Vector3[];for (int j = 0; j < (allV[i] as Vector3[]).Length; j++) {vertices[index_v] = vi[j];Color color = (allC[i] as Color[])[j];colorCount[index_v] = new Color(color.r / 255f,color.g / 255f,color.b / 255f,1f);index_v++;}}//trianglesint index_t = 0;for (int i = 0; i < allV.Length - 1; i++){Vector3[] vi = allV[i] as Vector3[];int nW = allV.Length;int nH = vi.Length;for (int j = 0; j < vi.Length - 1; j++){triangles[index_t++] = i * vi.Length + j;triangles[index_t++] = (i + 1) * vi.Length + j;triangles[index_t++] = (i + 1) * vi.Length + j + 1;triangles[index_t++] = i * vi.Length + j;triangles[index_t++] = (i + 1) * vi.Length + j + 1;triangles[index_t++] = i * vi.Length + j + 1;}}//uv贴图与veritces重合便可以将制作的贴图贴上,但是个点的比例要与mesh三角形比例相同,否则无法贴上//List<Vector2> uvV2 = new List<Vector2>();//for (int i = 0; i < allV.Length; i++)//{//for (int j = 0; j < (allV[i] as Vector3[]).Length; j++)//{//Vector2 v = new Vector2((float)j * (1f / (float)((allV[i] as Vector3[]).Length - 1)), (float)i * (1f / ((float)allV.Length - 1)));//uvV2.Add(v);//Debug.Log(v.x + " " + v.y);//countUV++;//}//}//mesh.uv = new Vector2[] { new Vector2 (0,0),new Vector2(0,1),new Vector2(1,1) };mesh.vertices = vertices;mesh.triangles = triangles;mesh.colors = colorCount;mesh.RecalculateNormals();meshFilter.mesh = mesh;}
使用shader,具体的参考
http://blog.csdn.net/qq_29579137/article/details/77854504
参考这个博主的文章,使用里面的shader,当然我还学着写了一个高光的shader,更有立体感
Shader "Volume13/4.Specular" { //------------------------------------【属性值】------------------------------------ Properties { //主颜色 _Color("Main Color", Color) = (1, 1, 1, 1) //镜面反射颜色 _SpecColor("Specular Color", Color) = (1, 1, 1, 1) //镜面反射光泽度 _SpecShininess("Specular Shininess", Range(1.0, 100.0)) = 10.0 } //------------------------------------【唯一的子着色器】------------------------------------ SubShader { //渲染类型设置:不透明 Tags{ "RenderType" = "Opaque" } LOD 200 //--------------------------------唯一的通道------------------------------- Pass { //光照模型ForwardBase Tags{ "LightMode" = "ForwardBase" }Cull OFF //===========开启CG着色器语言编写模块=========== CGPROGRAM //编译指令:告知编译器顶点和片段着色函数的名称 #pragma vertex vert #pragma fragment frag //顶点着色器输入结构 struct appdata { float4 vertex : POSITION;//顶点位置 float3 normal : NORMAL;//法线向量坐标 fixed4 color :COLOR; }; //顶点着色器输出结构 struct v2f { float4 pos : SV_POSITION;//像素位置 float3 normal : NORMAL;//法线向量坐标 float4 posWorld : TEXCOORD0;//在世界空间中的坐标位置 fixed4 color :COLOR; }; //变量的声明 float4 _LightColor0; float4 _Color; float4 _SpecColor; float _SpecShininess; //--------------------------------【顶点着色函数】----------------------------- // 输入:顶点输入结构体 // 输出:顶点输出结构体 //--------------------------------------------------------------------------------- //顶点着色函数 v2f vert(appdata IN) { //【1】声明一个输出结构对象 v2f OUT; //【2】填充此输出结构 //输出的顶点位置为模型视图投影矩阵乘以顶点位置,也就是将三维空间中的坐标投影到了二维窗口 OUT.pos = mul(UNITY_MATRIX_MVP, IN.vertex); //获得顶点在世界空间中的位置坐标 OUT.posWorld = mul(unity_ObjectToWorld, IN.vertex); //获取顶点在世界空间中的法线向量坐标 OUT.normal = mul(float4(IN.normal, 0.0), unity_WorldToObject).xyz; OUT.color = IN.color; //【3】返回此输出结构对象 return OUT; } //--------------------------------【片段着色函数】----------------------------- // 输入:顶点输出结构体 // 输出:float4型的像素颜色值 //--------------------------------------------------------------------------------- fixed4 frag(v2f IN) : COLOR { //【1】先准备好需要的参数 //获取法线的方向 float3 normalDirection = normalize(IN.normal); //获取入射光线的方向 float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz); //获取视角方向 float3 viewDirection = normalize(_WorldSpaceCameraPos - IN.posWorld.xyz); //【2】计算出漫反射颜色值 Diffuse=LightColor * MainColor * max(0,dot(N,L)) float3 diffuse = _LightColor0.rgb * IN.color * max(0.0, dot(normalDirection, lightDirection)); //【3】计算镜面反射颜色值 float3 specular; //若是法线方向和入射光方向大于180度,镜面反射值为0 if (dot(normalDirection, lightDirection) < 0.0) { specular = float3(0.0, 0.0, 0.0); } //否则,根据公式进行计算 Specular =LightColor * SpecColor *pow(max(0,dot(R,V)),Shiness),R=reflect(-L,N) else { float3 reflectDirection = reflect(-lightDirection, normalDirection); specular = _LightColor0.rgb * _SpecColor.rgb * pow(max(0.0, dot(reflectDirection, viewDirection)), _SpecShininess); } //【4】合并漫反射、镜面反射、环境光的颜色值 float4 diffuseSpecularAmbient = float4(diffuse, 1.0) + float4(specular, 1.0) + UNITY_LIGHTMODEL_AMBIENT; //【5】将漫反射-镜面反射-环境光的颜色值返回 return diffuseSpecularAmbient; } //===========结束CG着色器语言编写模块=========== ENDCG } } }这样输入几个vector3[]路径,就可以返回一个3D的等温图了
贝塞尔曲线类的代码是可以参考我过去的博文
http://blog.csdn.net/qq_37240033/article/details/77945599
学习过程中还学会了制作渐变texture2D
具体代码是
Texture2D allTexture(object[] allC,int width,int height){proceduralTexture = new Texture2D(width * ((allC[0] as Color[]).Length - 1), (allC.Length - 1) * height);int j = 0;for (int color_x = 0; color_x < allC.Length - 1; color_x++){int i = 0;Color[] color_0 = allC[color_x] as Color[];Color[] color_1 = allC[color_x + 1] as Color[];for (int color_y = 0; color_y < (allC[color_x] as Color[]).Length - 1; color_y++){CreatMeshItemTexture(color_0[color_y], color_0[color_y + 1], color_1[color_y], color_1[color_y + 1], width, height, i, j);i++;}j++;}proceduralTexture.Apply();return proceduralTexture;}public void CreatMeshItemTexture(Color a1, Color a2, Color a3, Color a4, int width, int height, int coutWidth, int coutHeight){for (int y = 0; y < height; y++){float dr_13 = (a3.r - a1.r) / height;float dg_13 = (a3.g - a1.g) / height;float db_13 = (a3.b - a1.b) / height;Color dx0 = new Color(dr_13 * y + a1.r, dg_13 * y + a1.g, db_13 * y + a1.b);float dr_24 = (a4.r - a2.r) / height;float dg_24 = (a4.g - a2.g) / height;float db_24 = (a4.b - a2.b) / height;Color dx1 = new Color(dr_24 * y + a2.r, dg_24 * y + a2.g, db_24 * y + a2.b);for (int x = 0; x < width; x++){float dr = (dx1.r - dx0.r) / width;float dg = (dx1.g - dx0.g) / width;float db = (dx1.b - dx0.b) / width;Color pixeColor = new Color((dr * x + dx0.r) / 255f , (dg * x + dx0.g) / 255f, (db * x + dx0.b) / 255f);proceduralTexture.SetPixel(x + coutWidth * width, y + coutHeight * height, pixeColor);}}}
最终效果
http://blog.csdn.net/qq_29579137/article/details/77854504
http://blog.csdn.net/nanggong/article/details/54311090
阅读全文
0 0
- unity 制作3D等温图
- Unity 3D mesh制作地形工具
- Unity制作简单3D图表
- Unity制作简单3D图表
- unity制作一个3d旋转菜单
- Unity 3D飞机大战制作心得
- unity 制作2d动画
- Unity 2D游戏制作
- Unity 3D + Vuforia制作AR人物互动
- unity 3d中使用BMFont制作NGUI清晰字体
- 教程:如何使用Unity制作3D版iOS游戏
- unity 3d中使用BMFont制作清晰字体
- unity 3d中使用BMFont制作清晰字体
- unity 3d中使用BMFont制作NGUI清晰字体
- Unity 3D + Vuforia制作AR人物互动
- unity 3d中使用BMFont制作清晰字体
- Unity 偏振3D左右格式画面制作
- ROLL A BALL (Unity 3D 入门) 游戏制作指导
- 关于Bootstrap模态框和table互相传值,以及实现图片上传
- Lucene学习总结之七:Lucene搜索过程解析(2)
- 卷积的输入里串联上标签y
- js 中的数组排序
- eclipse下NDK开发
- unity 制作3D等温图
- 【PAT】【Advanced Level】1118. Birds in Forest (25)
- 360浏览器(极速和兼容模式)
- 通过nginx实现同一ip的多域名绑定
- CentOS 7 源码安装Mysql5.7.19
- 建造者模式(Builder Pattern)
- C++学习笔记(5)-文件和流
- PAT A1120. Friend Numbers (20)
- 算法设计课作业系列2——Kth Largest Element in an Array