之前寫功能對(duì)ui的default shader做了修改,然后遇到一些問題,記錄一下(代碼可以在下載unity自選的built-in shaders 里面找到)
如何去寫自定義shader
想要重寫unity的ui材質(zhì)必須要包含一些固有的參數(shù)類型
1.模板緩沖的一堆參數(shù),對(duì)unity的mask生效,(我覺得既然作為ui就要遵守ui的模板,不加沒有問題,但是我看到過使用自定義材質(zhì)導(dǎo)致的奇怪的問題,都是不注意細(xì)節(jié),比如z-Test默認(rèn)是開啟的,等等)
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
2.默認(rèn)的shader會(huì)有兩個(gè)宏
#pragma multi_compile __ UNITY_UI_CLIP_RECT
#pragma multi_compile __ UNITY_UI_ALPHACLIP
目的是對(duì)unity的rect mask 2d 裁剪生效
#ifdef UNITY_UI_CLIP_RECT
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
#endif
#ifdef UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif
實(shí)現(xiàn)原理其實(shí)很簡(jiǎn)單
inline float UnityGet2DClipping (in float2 position, in float4 clipRect)
{
// 判斷當(dāng)前點(diǎn)是否在矩形中,返回inside.x * inside.y 如果有任意一點(diǎn)不在那么返回值為0
float2 inside = step(clipRect.xy, position.xy) * step(position.xy, clipRect.zw);
return inside.x * inside.y;
}
clip對(duì)gpu并行化處理影響比較大,所以一般都不勾上這個(gè)UNITY_UI_ALPHACLIP宏
所以看你的需求,如果需要rectMask2d的矩形裁剪 ,那么就加上,如果不需要,就刪掉,~宏我覺得是沒必要加上了,沒有必要為你重寫的這個(gè)shader增加3個(gè)變體,是吧
3.關(guān)于gpu instancing
你會(huì)發(fā)現(xiàn)默認(rèn)的shader帶了兩個(gè)函數(shù)接口
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
第一個(gè)就是我想解釋一下的gpu instancing,聽起來還蠻高大上的
GPU Instancing是指由GPU和圖形API支持的,用一個(gè)Draw Call同時(shí)繪制多個(gè)Geometry相同的物體的技術(shù)。
通過降低dc來降低gpu的開銷
第2個(gè)是給vr用的,3dxxxx 所以一般游戲也不需要
比較 dynamic batch和 gpu instancing 區(qū)別
降低dc的辦法嘛,各有
dynamic batch:
unity自己合并網(wǎng)格的一種方式,是合并頂點(diǎn)數(shù),vertex buffer合并傳遞一個(gè)比較大的頂點(diǎn)數(shù)量來解決問題的(沒有法線uv的情況下應(yīng)該支持900一下頂點(diǎn)數(shù)的object),cpu處做的優(yōu)化,條件:mesh可以不同,但材質(zhì)必須相同(同一份)。
gpu instancing:
是基于圖形api來實(shí)現(xiàn)的,傳遞相同的vertex buffer, mesh必須是相同的,但是一些(比如位置信息,旋轉(zhuǎn),顏色等等)是可以通過property block傳遞給gpu去改變的
附上很不錯(cuò)的教程鏈接供參考
沒有他寫得好 就不多廢話了 = =