之前写功能对ui的default shader做了修改,然后遇到一些问题,记录一下(代码可以在下载unity自选的built-in shaders 里面找到)
如何去写自定义shader
想要重写unity的ui材质必须要包含一些固有的参数类型
1.模板缓冲的一堆参数,对unity的mask生效,(我觉得既然作为ui就要遵守ui的模板,不加没有问题,但是我看到过使用自定义材质导致的奇怪的问题,都是不注意细节,比如z-Test默认是开启的,等等)
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.默认的shader会有两个宏
#pragma multi_compile __ UNITY_UI_CLIP_RECT
#pragma multi_compile __ UNITY_UI_ALPHACLIP
目的是对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
实现原理其实很简单
inline float UnityGet2DClipping (in float2 position, in float4 clipRect)
{
// 判断当前点是否在矩形中,返回inside.x * inside.y 如果有任意一点不在那么返回值为0
float2 inside = step(clipRect.xy, position.xy) * step(position.xy, clipRect.zw);
return inside.x * inside.y;
}
clip对gpu并行化处理影响比较大,所以一般都不勾上这个UNITY_UI_ALPHACLIP宏
所以看你的需求,如果需要rectMask2d的矩形裁剪 ,那么就加上,如果不需要,就删掉,~宏我觉得是没必要加上了,没有必要为你重写的这个shader增加3个变体,是吧
3.关于gpu instancing
你会发现默认的shader带了两个函数接口
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
第一个就是我想解释一下的gpu instancing,听起来还蛮高大上的
GPU Instancing是指由GPU和图形API支持的,用一个Draw Call同时绘制多个Geometry相同的物体的技术。
通过降低dc来降低gpu的开销
第2个是给vr用的,3dxxxx 所以一般游戏也不需要
比较 dynamic batch和 gpu instancing 区别
降低dc的办法嘛,各有
dynamic batch:
unity自己合并网格的一种方式,是合并顶点数,vertex buffer合并传递一个比较大的顶点数量来解决问题的(没有法线uv的情况下应该支持900一下顶点数的object),cpu处做的优化,条件:mesh可以不同,但材质必须相同(同一份)。
gpu instancing:
是基于图形api来实现的,传递相同的vertex buffer, mesh必须是相同的,但是一些(比如位置信息,旋转,颜色等等)是可以通过property block传递给gpu去改变的
附上很不错的教程链接供参考
没有他写得好 就不多废话了 = =
网友评论