unity源码解析Material

时间:2021-06-17 17:18:38

Material这个需要结合shader来讲,计算机图形学里本身就没有Material这个东西,引擎加入这个其实是在shader和主程序之间搭建了一座桥梁,可以说Material是一个着色器管理器,所以很多接口都是对shader的控制。

using System;
using System.Runtime.CompilerServices;
using UnityEngine.Internal;

namespace UnityEngine
{
    public class Material : Object
    {
        public extern Shader shader
        {
            [WrapperlessIcall]
            [MethodImpl(MethodImplOptions.InternalCall)]
            get;
            [WrapperlessIcall]
            [MethodImpl(MethodImplOptions.InternalCall)]
            set;
        }
//这个是针对该material锁控制的shader中_Color变量操作,获取该颜色或设置该颜色
        public Color color
        {
            get
            {
                return this.GetColor("_Color");
            }
            set
            {
                this.SetColor("_Color",value);
            }
        }
//针对该material锁控制的shader中_MainTex变量操作,获取该纹理或设置该纹理
        public Texture mainTexture
        {
            get
            {
                return this.GetTexture("_MainTex");
            }
            set
            {
                this.SetTexture("_MainTex",value);
            }
        }
//shader中_MainTex的纹理偏移量
        public Vector2 mainTextureOffset
        {
            get
            {
                return this.GetTextureOffset("_MainTex");
            }
            set
            {
                this.SetTextureOffset("_MainTex",value);
            }
        }
//_MainTex的纹理坐标缩放,编辑器上就是对应Tiling这个属性
        public Vector2 mainTextureScale
        {
            get
            {
                return this.GetTextureScale("_MainTex");
            }
            set
            {
                this.SetTextureScale("_MainTex",value);
            }
        }
//shader中pass的数量
        public extern int passCount
        {
            [WrapperlessIcall]
            [MethodImpl(MethodImplOptions.InternalCall)]
            get;
        }
//设置该材质的渲染队列,对应了shader中的Queue,表示unity在什么时候渲染自己,可选值:Background(1000), Geometry(2000), AlphaTest(2450), Transparent(3000), Overlay(4000)
        public extern int renderQueue
        {
            [WrapperlessIcall]
            [MethodImpl(MethodImplOptions.InternalCall)]
            get;
            [WrapperlessIcall]
            [MethodImpl(MethodImplOptions.InternalCall)]
            set;
        }
//这相当于是c语言中的宏定义列表,通过EnableKeyword,DisableKeyword决定使用不使用这些宏来控制shader执行哪部分代码
        public extern string[] shaderKeywords
        {
            [WrapperlessIcall]
            [MethodImpl(MethodImplOptions.InternalCall)]
            get;
            [WrapperlessIcall]
            [MethodImpl(MethodImplOptions.InternalCall)]
            set;
        }
//使用shader里面字符串创建一个材质
        public Material(string contents)
        {
            Material.Internal_CreateWithString(this, contents);
        }
//使用shader创建一个材质
        public Material(Shader shader)
        {
            Material.Internal_CreateWithShader(this, shader);
        }
//深拷贝一个材质
        public Material(Material source)
        {
            Material.Internal_CreateWithMaterial(this, source);
        }
//设置shader中名为propertyName的变量的值
        public void SetColor(string propertyName, Color color)
        {
            this.SetColor(Shader.PropertyToID(propertyName), color);
        }

        public void SetColor(int nameID, Color color)
        {
            Material.INTERNAL_CALL_SetColor(this, nameID,ref color);
        }

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        private static extern void INTERNAL_CALL_SetColor(Material self,int nameID, ref Color color);

        public Color GetColor(string propertyName)
        {
            return this.GetColor(Shader.PropertyToID(propertyName));
        }

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        public extern Color GetColor(int nameID);
//设置shader中名为propertyName的变量的值
        public void SetVector(string propertyName, Vector4 vector)
        {
            this.SetColor(propertyName,new Color(vector.x, vector.y, vector.z, vector.w));
        }

        public void SetVector(int nameID, Vector4 vector)
        {
            this.SetColor(nameID,new Color(vector.x, vector.y, vector.z, vector.w));
        }
//设置shader中名为propertyName的变量的值
        public Vector4 GetVector(string propertyName)
        {
            Color color = this.GetColor(propertyName);
            return new Vector4(color.r, color.g, color.b, color.a);
        }

        public Vector4 GetVector(int nameID)
        {
            Color color = this.GetColor(nameID);
            return new Vector4(color.r, color.g, color.b, color.a);
        }
//设置shader中名为propertyName的变量的值
        public void SetTexture(string propertyName, Texture texture)
        {
            this.SetTexture(Shader.PropertyToID(propertyName), texture);
        }

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        public extern void SetTexture(int nameID, Texture texture);

        public Texture GetTexture(string propertyName)
        {
            return this.GetTexture(Shader.PropertyToID(propertyName));
        }

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        public extern Texture GetTexture(int nameID);

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        private static extern void Internal_GetTextureOffset(Material mat,string name, out Vector2 output);

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        private static extern void Internal_GetTextureScale(Material mat,string name, out Vector2 output);

        public void SetTextureOffset(string propertyName, Vector2 offset)
        {
            Material.INTERNAL_CALL_SetTextureOffset(this, propertyName,ref offset);
        }

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        private static extern void INTERNAL_CALL_SetTextureOffset(Material self,string propertyName, ref Vector2 offset);

        public Vector2 GetTextureOffset(string propertyName)
        {
            Vector2 result;
            Material.Internal_GetTextureOffset(this, propertyName,out result);
            return result;
        }

        public void SetTextureScale(string propertyName, Vector2 scale)
        {
            Material.INTERNAL_CALL_SetTextureScale(this, propertyName,ref scale);
        }

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        private static extern void INTERNAL_CALL_SetTextureScale(Material self,string propertyName, ref Vector2 scale);

        public Vector2 GetTextureScale(string propertyName)
        {
            Vector2 result;
            Material.Internal_GetTextureScale(this, propertyName,out result);
            return result;
        }
//设置shader中名为propertyName的变量的值为矩阵
        public void SetMatrix(string propertyName, Matrix4x4 matrix)
        {
            this.SetMatrix(Shader.PropertyToID(propertyName), matrix);
        }

        public void SetMatrix(int nameID, Matrix4x4 matrix)
        {
            Material.INTERNAL_CALL_SetMatrix(this, nameID,ref matrix);
        }

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        private static extern void INTERNAL_CALL_SetMatrix(Material self,int nameID, ref Matrix4x4 matrix);
//获得shader中名为propertyName的变量的值为矩阵
        public Matrix4x4 GetMatrix(string propertyName)
        {
            return this.GetMatrix(Shader.PropertyToID(propertyName));
        }

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        public extern Matrix4x4 GetMatrix(int nameID);

        public void SetFloat(string propertyName,float value)
        {
            this.SetFloat(Shader.PropertyToID(propertyName),value);
        }

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        public extern void SetFloat(int nameID,float value);

        public float GetFloat(string propertyName)
        {
            return this.GetFloat(Shader.PropertyToID(propertyName));
        }

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        public extern float GetFloat(int nameID);

        public void SetInt(string propertyName,int value)
        {
            this.SetFloat(propertyName, (float)value);
        }

        public void SetInt(int nameID,int value)
        {
            this.SetFloat(nameID, (float)value);
        }

        public int GetInt(string propertyName)
        {
            return (int)this.GetFloat(propertyName);
        }

        public int GetInt(int nameID)
        {
            return (int)this.GetFloat(nameID);
        }

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        public extern void SetBuffer(string propertyName, ComputeBuffer buffer);
//shader是否存在propertyName这个变量
        public bool HasProperty(string propertyName)
        {
            return this.HasProperty(Shader.PropertyToID(propertyName));
        }

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        public extern bool HasProperty(int nameID);

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        public extern string GetTag(string tag, bool searchFallbacks, [DefaultValue("\"\"")]string defaultValue);

        [ExcludeFromDocs]
        public string GetTag(string tag,bool searchFallbacks)
        {
            string empty = string.Empty;
            return this.GetTag(tag, searchFallbacks, empty);
        }

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        public extern void Lerp(Material start, Material end, float t);

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        public extern bool SetPass(int pass);

        [Obsolete("Use the Material constructor instead.")]
        public static Material Create(string scriptContents)
        {
            return new Material(scriptContents);
        }

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        private static extern void Internal_CreateWithString([Writable] Material mono,string contents);

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        private static extern void Internal_CreateWithShader([Writable] Material mono, Shader shader);

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        private static extern void Internal_CreateWithMaterial([Writable] Material mono, Material source);

        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        public extern void CopyPropertiesFromMaterial(Material mat);
//通过EnableKeyword,DisableKeyword决定使用不使用这些宏来控制shader执行哪部分代码
        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        public extern void EnableKeyword(string keyword);
//通过EnableKeyword,DisableKeyword决定使用不使用这些宏来控制shader执行哪部分代码
        [WrapperlessIcall]
        [MethodImpl(MethodImplOptions.InternalCall)]
        public extern void DisableKeyword(string keyword);
    }
}