一、程式紋理
程式紋理顧名思義就是代碼生成的紋理,好了到此就是程式紋理的全部介紹了……
再細一點講:假設我們想生成一個下面這樣的紋理(白色背景,9給黃色圓圈等距排列),對應的偽代碼就為

定義圓的半徑A = ?
定義第一個圓的圓心B = ?
定義相鄰兩個圓的橫縱距離 = ?
定義每行每列圓的個數 = 3 x 3
定義紋理大小(HxW)= 512 x 512
定義圓的顏色 = yellow
……
for 紋理的每一個像素
if 計算得到當前像素坐標在某個圓的內部
設定當前像素點顏色為黃色
else
設定當前像素點顏色為白色
end
end
輸出這張紋理
完整代碼:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[ExecuteInEditMode]
public class ProceduralTextureGeneration: MonoBehaviour
{
public Material material = null;
#region Material properties
[SerializeField, SetProperty("textureWidth")]
private int m_textureWidth = 512;
public int textureWidth
{
get { return m_textureWidth; }
set { m_textureWidth = value; _UpdateMaterial(); }
}
[SerializeField, SetProperty("backgroundColor")]
private Color m_backgroundColor = Color.white;
public Color backgroundColor {
get { return m_backgroundColor; }
set { m_backgroundColor = value; _UpdateMaterial(); }
}
[SerializeField, SetProperty("circleColor")]
private Color m_circleColor = Color.yellow;
public Color circleColor {
get { return m_circleColor; }
set { m_circleColor = value; _UpdateMaterial(); }
}
[SerializeField, SetProperty("blurFactor")]
private float m_blurFactor = 2.0f;
public float blurFactor {
get { return m_blurFactor; }
set { m_blurFactor = value; _UpdateMaterial(); }
}
#endregion
private Texture2D m_generatedTexture = null;
void Start()
{
if (material == null)
{
Renderer renderer = gameObject.GetComponent<Renderer>();
if (renderer == null)
{
Debug.LogWarning("Cannot find a renderer.");
return;
}
material = renderer.sharedMaterial;
}
_UpdateMaterial();
}
//更新材質紋理
private void _UpdateMaterial()
{
if (material != null)
{
m_generatedTexture = _GenerateProceduralTexture();
material.SetTexture("_MainTex", m_generatedTexture);
}
}
//將兩個顏色按照插值的方法混合
private Color _MixColor(Color color0, Color color1, float mixFactor)
{
Color mixColor = Color.white;
mixColor.r = Mathf.Lerp(color0.r, color1.r, mixFactor);
mixColor.g = Mathf.Lerp(color0.g, color1.g, mixFactor);
mixColor.b = Mathf.Lerp(color0.b, color1.b, mixFactor);
mixColor.a = Mathf.Lerp(color0.a, color1.a, mixFactor);
return mixColor;
}
private Texture2D _GenerateProceduralTexture()
{
Texture2D proceduralTexture = new Texture2D(textureWidth, textureWidth);
//兩個圓的間隔
float circleInterval = textureWidth / 4.0f;
//圓的半徑
float radius = textureWidth / 10.0f;
//模糊因子
float edgeBlur = 1.0f / blurFactor;
for (int w = 0; w < textureWidth; w++)
{
for (int h = 0; h < textureWidth; h++)
{
Color pixel = backgroundColor;
//在紋理上畫圓
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
//得到圓心的位置
Vector2 circleCenter = new Vector2(circleInterval * (i + 1), circleInterval * (j + 1));
//判斷當前紋理像素到圓心的距離
float dist = Vector2.Distance(new Vector2(w, h), circleCenter) - radius;
//得到當前像素的顏色
Color color = _MixColor(circleColor, new Color(pixel.r, pixel.g, pixel.b, 0.0f), Mathf.SmoothStep(0f, 1.0f, dist * edgeBlur));
//再次混合背景色
pixel = _MixColor(pixel, color, color.a);
}
}
//更新當前像素點
proceduralTexture.SetPixel(w, h, pixel);
}
}
//應用
proceduralTexture.Apply();
return proceduralTexture;
}
}
這個代碼報錯(error CS0246: The type or namespace name 'SetProperty' could not be found)?
→ 需要一個開源插件,其下載地址:https://github.com/LMNRY/SetProperty,該插件可以支持在 Unity 面板修改材質屬性:

將上面生成紋理的腳本隨便掛在一個物體下之后,拖入對應的材質球,就可以看到這個材質球的紋理被成功修改:

關于代碼中的 [SerializeField, SetProperty("textureWidth")]、以及上述插件的功能,都屬于 Unity 編輯器的內容,這里就不跑題了
二、紋理生成工具 SubstanceDesigner
- 關于它的教程:https://www.bilibili.com/video/av22746446
- 官網:https://www.substance3d.com/products/substance-designer/
非常棒的紋理制作工具,最終可以得到 .sbsar 為后綴的材質

Unity匯入 .sbsar 材質方法:
對于新版本的 Unity,內部已不再默認支持 .sbsar 材質了,需要手動從 Asset Store 中下載插件 Substance in Unity

如果成功,.sbsar 檔案就能成功被識別,并且可以當作材質球使用:


如果失敗,包括但不限于 .sbsar 識別不出,又或者 Unity 匯入時崩潰,可能需要檢查下 Substance in Unity 插件的版本,最好直接從 AssetStore 上下載
三、.sbsar 檔案面板

- 變體:以支持一個 sbsar 檔案生成數個材質球供不同的物體使用,點擊圖中的 + 號就可以生成一個新的變體
- Graph:在這里調節程式化紋理的引數,在 SD 中曝露的屬性也都會在這個面板顯示出來,可以點擊下面的 Bake textures to folder 按鈕烘培到紋理
- Material:材質球,默認使用的 Shader 為 Standard
- Texture:紋理
關于 .sbsar 檔案的匯出:打開你的 SD,加載你想要匯出的 .sbs 檔案,最后按照下面的步驟就 OK

參考資料:
- https://zhuanlan.zhihu.com/p/99362830?from_voters_page=true
- 《UnityShader入門精要》
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/261084.html
標籤:其他
