之前在

Unity Mesh(三) Mesh画球

中已经说明了如何画球,现在我们在这个球的基础上贴图。

这里我们有个极坐标和直角坐标的转换,具体我也不是很明白,反正就是拿来用吧,据某位大神讲解,极坐标(球坐标)由球半径,水平角和垂直角决定,我们完全可以理解为三维坐标转换成uv坐标的方程,也就是三维坐标映射到uv坐标上,f(u,v)=[x,y,z]这样的一个映射关系,映射关系取决于函数具体怎么定义的或者这个球是怎么画的,不同的模型有不同的方法,典型的克莱因瓶一个uv完整的模型,它有自己的函数。

好了,楼主还是参考的Jasper Flick的方法,这个大神一直很崇拜。

f(u,v)=[x,y,z]

u=asin(y) / π + ½.

v=atan2(x, z) / -2π

unity自带的球贴图会在两个极点出现扭曲Twisting的现象:

包括我们之前建立的球也没有考虑到这一个点,原因是计算极点的坐标时,极点只有一个坐标,但是极点每个四分之一圆实际上是我们极点四个三角形公用了一个uv坐标,这样就会造成扭曲现象,解决方法是我们把极点的点拆分成四个相同的点,一个面一个。

这样的话,我们之前画球的点稍稍有改动,上下两个极点分别加三个点。

这样这个问题就解决了!

下面我们直接上图:

这个最后的完整代码如下:

using UnityEngine;
using System.Collections;[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class DrawOctahedronSphere : MonoBehaviour
{public Material mat;public int subdivisions;public int radius;private static Vector3[] directions = {Vector3.left,Vector3.back,Vector3.right,Vector3.forward};void Start(){DrawSphere(subdivisions, radius);}public void DrawSphere(int subdivisions = 0, float radius = 1){if (subdivisions > 4){subdivisions = 4;}gameObject.GetComponent<MeshRenderer>().material = mat;Mesh mesh = GetComponent<MeshFilter>().mesh;mesh.Clear();int resolution = 1 << subdivisions;Vector3[] vertices = new Vector3[(resolution + 1) * (resolution + 1) * 4 - 3 * (resolution * 2 - 1)];int[] triangles = new int[(1 << (subdivisions * 2 + 3)) * 3];CreateOctahedron(vertices, triangles, resolution);if (radius != 1f){for (int i = 0; i < vertices.Length; i++){vertices[i] *= radius;}}Vector3[] normals = new Vector3[vertices.Length];Normalize(vertices, normals);Vector2[] uv = new Vector2[vertices.Length];CreateUV(vertices, uv);mesh.vertices = vertices;mesh.triangles = triangles;mesh.normals = normals;mesh.uv = uv;}private static void CreateOctahedron(Vector3[] vertices, int[] triangles, int resolution){int v = 0, vBottom = 0, t = 0;for (int i = 0; i < 4; i++){vertices[v++] = Vector3.down;}for (int i = 1; i <= resolution; i++){float progress = (float)i / resolution;Vector3 from, to;vertices[v++] = to = Vector3.Lerp(Vector3.down, Vector3.forward, progress);for (int d = 0; d < 4; d++){from = to;to = Vector3.Lerp(Vector3.down, directions[d], progress);t = CreateLowerStrip(i, v, vBottom, t, triangles);v = CreateVertexLine(from, to, i, v, vertices);vBottom += i > 1 ? (i - 1) : 1;}vBottom = v - 1 - i * 4;}for (int i = resolution - 1; i >= 1; i--){float progress = (float)i / resolution;Vector3 from, to;vertices[v++] = to = Vector3.Lerp(Vector3.up, Vector3.forward, progress);for (int d = 0; d < 4; d++){from = to;to = Vector3.Lerp(Vector3.up, directions[d], progress);t = CreateUpperStrip(i, v, vBottom, t, triangles);v = CreateVertexLine(from, to, i, v, vertices);vBottom += i + 1;}vBottom = v - 1 - i * 4;}for (int i = 0; i < 4; i++){triangles[t++] = vBottom;triangles[t++] = v;triangles[t++] = ++vBottom;vertices[v++] = Vector3.up;}}private static int CreateVertexLine(Vector3 from, Vector3 to, int steps, int v, Vector3[] vertices){for (int i = 1; i <= steps; i++){vertices[v++] = Vector3.Lerp(from, to, (float)i / steps);}return v;}private static int CreateLowerStrip(int steps, int vTop, int vBottom, int t, int[] triangles){for (int i = 1; i < steps; i++){triangles[t++] = vBottom;triangles[t++] = vTop - 1;triangles[t++] = vTop;triangles[t++] = vBottom++;triangles[t++] = vTop++;triangles[t++] = vBottom;}triangles[t++] = vBottom;triangles[t++] = vTop - 1;triangles[t++] = vTop;return t;}private static int CreateUpperStrip(int steps, int vTop, int vBottom, int t, int[] triangles){triangles[t++] = vBottom;triangles[t++] = vTop - 1;triangles[t++] = ++vBottom;for (int i = 1; i <= steps; i++){triangles[t++] = vTop - 1;triangles[t++] = vTop;triangles[t++] = vBottom;triangles[t++] = vBottom;triangles[t++] = vTop++;triangles[t++] = ++vBottom;}return t;}private static void Normalize(Vector3[] vertices, Vector3[] normals){for (int i = 0; i < vertices.Length; i++){normals[i] = vertices[i] = vertices[i].normalized;}}private static void CreateUV(Vector3[] vertices, Vector2[] uv){float previousX = 1f;for (int i = 0; i < vertices.Length; i++){Vector3 v = vertices[i];if (v.x == previousX){uv[i - 1].x = 1f;}previousX = v.x;Vector2 textureCoordinates;textureCoordinates.x = Mathf.Atan2(v.x, v.z) / (-2f * Mathf.PI);if (textureCoordinates.x < 0f){textureCoordinates.x += 1f;}textureCoordinates.y = Mathf.Asin(v.y) / Mathf.PI + 0.5f;uv[i] = textureCoordinates;}uv[vertices.Length - 4].x = uv[0].x = 0.125f;uv[vertices.Length - 3].x = uv[1].x = 0.375f;uv[vertices.Length - 2].x = uv[2].x = 0.625f;uv[vertices.Length - 1].x = uv[3].x = 0.875f;}
}

Unity Mesh(七) Mesh给球贴图相关推荐

  1. Unity动态构建Mesh来绘制任意多边形(雷达图效果)

    由于很多同学没有做出来,特此补传一个Demo工程 (版本Unity2019.1.8f1) CSDN下载:https://download.csdn.net/download/linxinfa/1195 ...

  2. Unity Mesh(五) Mesh 立方体Cube贴图以及六个面分别贴不同的图片

    在前面的篇章中已经有了怎么Mesh画一个立方体,当时的立方体是按照逆时针的画的,其它大都都是按照顺时针画的,当时一开始画立方体顺时针没画出来,有些面看不到就调换了下顺序,没特别注意方向问题,然而这一篇 ...

  3. unity Text Mesh Pro Sprite Animation 支持动图,动态表情

    unity Text Mesh Pro Sprite Animation 支持动图,动态表情 使用格式 <sprite='assetName' anim='first frame, last f ...

  4. Unity网格篇Mesh(一)

    程序代码实现网格 这里根据CSDNSpring5211的一篇文章,进行网格学习为网格材质合并作为一个基础 本文的目标 创建网格坐标 使用携程计算他们位置 利用三角形确定一个面 自动生成法线 添加纹理坐 ...

  5. Unity学习笔记——Mesh

    Unity学习笔记--Mesh Unity中的Mesh组件是一个很好玩的东西,这次的目标是根据高程图创建出一个平面. 1.用脚本创建一个简单的三角形 新建空的物体,挂上MeshFilter.MeshR ...

  6. Unity使用Skinned Mesh Renederer的BlendShapes时,报错“Platform does not support compute shaders”

    Unity使用Skinned Mesh Renederer的BlendShapes时,报错"Platform does not support compute shaders" 报 ...

  7. Unity优化篇——mesh合并

    一.mesh合并大体分为: 1.合并网格 2.合并贴图 3.附加材质 4.重新计算UV 这里提一下附加材质,附加材质是对合并后的mesh重新赋予了一个material.废话不多说上代码! 备注:代码大 ...

  8. 【Unity】获取模型的材质球贴图中的像素点色值

    获取模型的材质球贴图中的像素点色值,可以计算模型贴图的RGB.或某个色值的占比,也可以动态修改指定像素色值. 方式一: 获取可读的贴图,并遍历像素点:(通过Texture获取Texture2D操作的运 ...

  9. Not allowed to access normals on mesh ‘Combined Mesh (root: scene)‘ (isReadable is false...报错解决方法

      Unity播放时如果出现的"Not allowed to access normals on mesh 'Combined Mesh (root: scene)' (isReadable ...

最新文章

  1. 自然语言推理和数据集
  2. session对象运行机制
  3. LayoutInflater的inflate函数用法详解
  4. 机器人3·15 | 赛迪「机器人国评中心」揭示机器人产品质量6大痛点!
  5. freebsd用户密码文件
  6. .NET Core 2.1预览分层编译特性
  7. [快报][贴图] ANSI Art 的新形式 - CSS-ANSI Art
  8. 数据库、记录、字段、文档
  9. Android 关于“NetworkOnMainThreadException”
  10. 理解Object.defineProperty的作用
  11. mysql给数据量大的表添加索引的办法
  12. ALM 中查看某个 test 的更改 history 历史
  13. Tair持久存储系列技术解读
  14. 人车识别实验丨华为ModelArts VS 百度Easy DL硬核体验
  15. Win32下显示、隐式加载DLL的方法
  16. java 关闭阻塞线程池_如果优雅地关闭ExecutorService提供的java线程池
  17. SharePoint 2010遍历文档库中所有的文件,文件夹
  18. 使用老毛子在腾讯云DNSpod上实现DDNS
  19. Xshell6 Xftp6 官方永久免费版下载
  20. Word 2007文档结构图 大纲视图 目录默认折叠收缩

热门文章

  1. 2021年P气瓶充装最新解析及P气瓶充装考试试卷
  2. transition: background-color 0.5s ease-in 0s
  3. 【SeedLab】BGP Exploration and Attack Lab
  4. 一个查询大学英语四六级的类
  5. CISCO 设备中的 Traceroute 命令
  6. 股票k线图的技巧分析
  7. 如何查看本地电脑ip
  8. android短信转发到微信吗,android 如何将收到的短信转到微信
  9. redis 数据持久化 aof方式
  10. win10系统笔记本电脑如何外接两个屏幕?