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給球貼圖
之前在 中已經說明了如何畫球,現在我們在這個球的基礎上貼圖。 這裡我們有個極座標和直角座標的轉換,具體我也不是很明白,反正就是拿來用吧,據某位大神講解,極座標(球座標)由球半徑,水平角和垂直角決定,我們完全可以理解為三維座標轉換成uv座標的
unity給按鈕貼圖新增圖片
1.在Assets\Resources目錄新建的兩個資料夾subjectbtn、subjectbtn_highlight,subjectbtn用於存放各個科目按鈕的預設狀態圖片,subjectbtn_highlight用於存放各個科目按鈕的滑鼠滑過或點選時的狀態
unity標準Shader之十種貼圖型別
十種貼圖型別 介紹:標準 Shader 貼圖 標準 Shader 使用的是 PBR 渲染,基於現實物理效果的渲染表現形式。 一個模型能不能使用標準 Shad
MFC對話方塊視窗使用GDI+給按鈕貼圖
最近要做一個有透明效果的按鈕出來,先是大致學了PS教程,製作一個PNG格式的背景透明的按鈕,如圖1所示。然後使用GDI+進行貼圖,最後要達到圖2所示效果。開發環境是VS2010,MFC。 圖1 PS製作的PNG格式按鈕 圖2 效果圖 1、背景填充
【Unity技巧】調整畫質(貼圖)質量
寫在前面 當我們在Unity中,使用圖片進行2D顯示時,會發現顯示出來的畫面有明顯的模糊或者鋸齒,但是美術給的原圖卻十分清晰。 要改善這一狀況實際上很簡單。 造成這樣的原因,是Unity在匯入圖片
Unity 獲得某個物體的主貼圖
獲得物體的貼圖 gameObject.getComponent<MeshRenderer>().material.mainTexture; 預設的圖片型別是Texture2D Text
[Unity3d]如何製作unity能使用的RGBA材質貼圖
最近在研究ui材質問題時,想借用《魔獸世界》裡的Ui材質貼圖,可惜幾經週轉在網上實在找不到我想要的貼圖,大家是不是也有過這樣的經歷,索性我就嘗試自己用PS做了一個,大牛請忽視題主PS的技能~~ 首先我們先了解一下unity類透明的材質的格式資訊。 可以看
【個人Unity筆記】烘焙光照貼圖後保留法線和光探頭
使用的5.34f1版本的unity 有時候為了節省開銷,烘焙光照貼圖是一種很好的辦法,在手機上開發經常會使用到,配合光探頭還可以讓靜態光和非靜態物體產生互動。 首先,把要烘焙的物體全部勾選為靜態(Static)。 然後,把需要烘焙的光的Baking由預
【Unity實用小方法】判斷貼圖是否為透明貼圖
private bool JudgeTransparentPic(TextureFormat format) { //所有貼圖格式帶alpha通道的格式,帶alpha通
Unity Mesh(五) Mesh 立方體Cube貼圖以及六個面分別貼不同的圖片
using UnityEngine; using System.Collections; [RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))] public class Test3D : MonoBehaviour { publi
Unity Mesh(四) Mesh 平面圖形的貼圖
前面都講了怎麼畫,沒有寫怎麼貼圖,上一篇提到了法線,今天這篇會說說平面圖形的貼圖。 為了更好的觀察,我們使用這張圖片來進行貼圖(可以右擊儲存): 一、三角形貼圖 三角形的貼圖是最簡單的,因為我們畫的三角形就簡單,直接根據點來選取: 首先說下貼圖的座標系:如下圖
動態載入烘培貼圖與Terrain轉mesh
前言 unity載入烘培貼圖是需要載入場景才可以使用,但如果專案只使用一個場景或者有許多關卡地形時,明顯通過載入場景來達到更換烘培貼圖的這種做法是不妥當的。而terrain地形在有些安卓機上的支援並不是很好,所以有必要把地形轉為網格。慶幸的是,網上也有這方面的
Unity Mesh(三) Mesh畫球
關於畫球一開始真是一點思路都沒有,樓主也查了好多資料,比較有代表性的是兩篇帖子。 一篇是Jasper Flick的帖子,一個很厲害的人: 這一篇的思路是根據柏拉圖體,正八面體分割成的球。 第二篇是OpenGL或者XNA回答的思路,是根據柏拉圖體正二十面體畫的
FairyGUI UIPanel看不到顯示UI的Mesh和貼圖的問題
初學FairyGUI,看例子,FairyGUI在Editor中顯示UI的時候是先選擇Package名,在選擇Component名,然後在場景裡面就可以顯示包裡面的元件,這時就有一個問題,底層到底做了什麼使得UIPanel能夠顯示Mesh和貼圖? 看了Fairy
初識Unity 3D——認識材質球、貼圖
1、Unity中習慣將材質(Material)成為材質球,因為在U3D引擎中材質的預覽方式為一個球體。 2、材質球的組成又分為貼圖(Texture)和著色器(Shader)。 3、貼圖就是普通的圖片。 4、著色器是一種可以精確的控制材質球的工具。 通過貼
【Unity Shaders】學習筆記之法線貼圖(七)
一、簡介 法線貼圖是凸凹貼圖(Bump mapping)的一種常見應用,簡單說就是在不增加模型多邊形數量的前提下,通過渲染暗部和亮部的不同顏色深度,來為原來的貼圖和模型增加視覺細節和真實效果
Unity Shader 法線貼圖的實現
計算 變換 float minus include 的確 dal 反射 mode 這裏有一個細節,關於法線貼圖是有兩個不同的空間的,如下: 切線空間:法線貼圖顏色為偏藍色 模型空間:法線貼圖顏色為五顏六色 因此根據不同的空間變換位置方便一致計算。 1 // 法
03 傳遞貼圖給著色器
tac cti arc port -- angle span com shader WebGL很容易把圖片傳遞給著色器程序當作貼圖。下面是一些需要註意的地方: 1、貼圖圖片長寬像素必須是2的冪,例如16、32、64、128、256,否則貼圖無法顯示。
unity 貼圖
inf 因此 基礎上 tro 控制 ron lmap 導入 金屬 貼圖的英語 Map 其實包含了另一層含義就是“映射”。其功能就是把紋理通過 UV 坐標映射到3D 物體表面。貼圖包含了除了紋理以外其他很多信息,比方說 UV 坐標、貼圖輸入輸出控制等等。材質是一個數據集,主要
Unity使用腳本進行批量動態加載貼圖
它的 有關 技術 post 應該 而且 下一步 AI 屬性。 先描述一下我正在做的這個項目,是跑酷類音遊。 那麽跑酷類音遊在繪制跑道上的時候,就要考慮不同的磚塊顯示問題。假設我有了一個節奏列表,那麽我們怎麽將不同的貼圖貼到不同的磚塊上去呢? 我花了好幾個小時才搞清楚裏面的門