Unity腳本生成圖片

學習shader,剛開始,記下一些自己的解讀,如果有其它意見或者建議的歡迎交流。


首先先上腳本生成圖片的效果圖:





當然還可以根據參數有所改變。


下面開始逐步分析:

1.線性變化,顏色控制在黑白(y=|1-x|,1>=x>=0)

首先,貼下代碼:

直接看代碼可能不大好理解,下面我們具體化一下:

如上圖所示,這個原理就是以圖片的中心爲原點,圖片的高爲h,0.5h作爲半徑的圓的分部,從圓心到圓周的顏色減暗。

我們代碼一句一句分析,
Vector2 currentposition = new Vector2(x, y)
這一句就是遍歷的圖片大小像素點鐘的任意一點。
float pixeldistance = Vector2.Distance(currentposition, centerPixelPosition) / (widthHeight * 0.5f)
這一句就是圖中表示的Distance/(h*0.5),就是點到圓心的距離除以半徑,圓內的點值是0-1,圓外的大於1,假設這個值爲x
pixeldistance = Mathf.Abs(1 - Mathf.Clamp(pixeldistance, 0f, 1f))
這一句,首先clamp是把x的值控制在0-1內,(1-x)是取相反,爲啥呢,這裏因爲顏色表裏,0代表黑色,1代表白色,圓心距離圓心距離爲0,但是直接給0就是黑色,1-0的話就是白色,這樣圓心就是白色,書中代碼是由abs絕對值的,我認爲沒必要,x在0-1,1-x肯定大於等於0的。
下圖實例,不是1-x的效果,就是直接用x的效果:就是黑變白了
 Color pixelcolor = new Color(pixeldistance, pixeldistance, pixeldistance, 1.0f)
這是設置顏色,顏色rgb值一樣是都是黑白色,這個具體可以看下圖,沿着箭頭那條邊的rgb的三個值都是一樣的,然後看出顯然是黑白色:
proceduralTexture.SetPixel(x, y, pixelcolor)
設置像素點的顏色。

最終運行效果如圖:


2.隨sin週期變化,顏色控制在黑白(y=sin(nx)*x)

首先,貼下代碼:

這個跟1的代碼幾乎一樣,只有一行不同
        pixelDistance = (Mathf.Sin(pixelDistance * 30.0f) * pixelDistance)
這個函數出來的效果就是水波紋,函數圖如圖:
於是顏色就隨圓黑白變化,n越大,白色圈越多
一下是幾個視圖:
n=10:

n=30:
  
      
       n=100:

3.顏色根據方向向量偏移角度控制

首先,貼上代碼:

代碼示意圖如下:

rgb三個值,對應三個方向的夾角值,這樣的話是發散的,中心點出來的同一條線顏色是一樣的。

效果圖如下:


4.顏色根據方向向量和方向軸的數量積

這個跟3很類似,就是把angle換成了dot,就是上面3的夾角的cos值,顏色會比上面的鮮亮點:


最後:粘上總得腳本,大家可以試試,有個條件編譯,改下就好:
#define Case1 //條件編譯

using UnityEngine;
using System.Collections;

public class _ProceduralTexture : MonoBehaviour
{

    public int widthHeight = 512;

    /// <summary>
    /// 生成的圖片
    /// </summary>
    public Texture2D generatedTexture;

    /// <summary>
    /// 當前的材質
    /// </summary>
    private Material currentMaterial;

    /// <summary>
    /// 中心座標
    /// </summary>
    private Vector2 centerPosition;


    // Use this for initialization
    void Start()
    {
        if (!currentMaterial)
        {
            //共享當前物體的材質
            currentMaterial = transform.GetComponent<Renderer>().sharedMaterial;
            if (!currentMaterial)
            {
                Debug.LogWarning("Cannot find a material on:" + transform.name);
            }
        }

        if (currentMaterial)
        {
            centerPosition = new Vector2(0.5f, 0.5f);
            generatedTexture = GenerateParabola();

            //設置當前材質的貼圖爲我們生成的貼圖
            currentMaterial.SetTexture("_MainTex", generatedTexture);
        }
    }

    /// <summary>
    /// 生成貼圖
    /// </summary>
    /// <returns></returns>
    private Texture2D GenerateParabola()
    {
        //新建一張貼圖
        Texture2D proceduralTexture = new Texture2D(widthHeight, widthHeight);

        //中心像素座標
        Vector2 centerPixelPosition = centerPosition * widthHeight;

        //遍歷像素點設置
        for (int x = 0; x < widthHeight; x++)
        {
            for (int y = 0; y < widthHeight; y++)
            {
#if Case1
                #region 顏色控制在黑白,線性變化函數是y=|1-x|,1>=x>=0
                Vector2 currentposition = new Vector2(x, y);
                float pixeldistance = Vector2.Distance(currentposition, centerPixelPosition) / (widthHeight * 0.5f);

                pixeldistance = Mathf.Abs(1 - Mathf.Clamp(pixeldistance, 0f, 1f));

                Color pixelcolor = new Color(pixeldistance, pixeldistance, pixeldistance, 1.0f);
                proceduralTexture.SetPixel(x, y, pixelcolor);
                #endregion

#elif Case2
#region 顏色控制在黑白隨sin週期變化,變化是(2*π)/n,下面的n是30
                Vector2 currentPosition = new Vector2(x, y);
                float pixelDistance = Vector2.Distance(currentPosition, centerPixelPosition) / (widthHeight * 0.5f);
                pixelDistance = Mathf.Abs(1 - Mathf.Clamp(pixelDistance, 0f, 1f));
                pixelDistance = (Mathf.Sin(pixelDistance*30) * pixelDistance);
                Color pixelColor = new Color(pixelDistance, pixelDistance, pixelDistance, 1.0f);
                proceduralTexture.SetPixel(x, y, pixelColor);
#endregion
#elif Case3
#region 顏色根據方向向量偏移角度控制
                Vector2 currentPosition = new Vector2(x, y);
                Vector2 pixelDirection = centerPixelPosition - currentPosition;
                pixelDirection.Normalize();
                float rightDirection = Vector2.Angle(pixelDirection, Vector3.right) / 360;
                float leftDirection = Vector2.Angle(pixelDirection, Vector3.left) / 360;
                float upDirection = Vector2.Angle(pixelDirection, Vector3.up) / 360;
                Color pixelColor = new Color(rightDirection, leftDirection, upDirection, 1.0f);
                proceduralTexture.SetPixel(x, y, pixelColor);
#endregion
#elif Case4

                #region 顏色根據方向向量和方向軸的數量積
                Vector2 currentPosition = new Vector2(x, y);
                Vector2 pixelDirection = centerPixelPosition - currentPosition;
                pixelDirection.Normalize();
                float rightDirection = Vector2.Dot(pixelDirection, Vector3.right);
                float leftDirection = Vector2.Dot(pixelDirection, Vector3.left);
                float upDirection = Vector2.Dot(pixelDirection, Vector3.up);
                Color pixelColor = new Color(rightDirection, leftDirection, upDirection, 1.0f);
                proceduralTexture.SetPixel(x, y, pixelColor);
                #endregion
#endif


            }
        }

        proceduralTexture.Apply();

        return proceduralTexture;
    }
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章