unity3d shader控制渲染顺序,Queue,ZWrite,ZTest
2018-02-22 14:31
441 查看
Queue渲染队列:
按照渲染顺序,从先到后进行排序,队列数越小的,越先渲染,队列数越大的,越后渲染。Background(1000) 最早被渲染的物体的队列。
Geometry (2000) 不透明物体的渲染队列。大多数物体都应该使用该队列进行渲染,也是Unity Shader中默认的渲染队列。
AlphaTest (2450) 有透明通道,需要进行Alpha Test的物体的队列,比在Geomerty中更有效。
Transparent(3000) 半透物体的渲染队列。一般是不写深度的物体,Alpha Blend等的在该队列渲染。
Overlay (4000) 最后被渲染的物体的队列,一般是覆盖效果,比如镜头光晕,屏幕贴片之类的。
ZTest深度测试:
就是针对当前对象在屏幕上(更准确的说是frame buffer)对应的像素点,将对象自身的深度值与当前该像素点缓存的深度值进行比较,如果通过了,本对象在该像素点才会将颜色写入颜色缓冲区,否则否则不会写入颜色缓冲。ZTest提供的状态较多。ZTest Less(深度小于当前缓存则通过, ZTest Greater(深度大于当前缓存则通过),ZTest LEqual(深度小于等于当前缓存则通过),ZTest GEqual(深度大于等于当前缓存则通过),ZTest Equal(深度等于当前缓存则通过),ZTest NotEqual(深度不等于当前缓存则通过),ZTest Always(不论如何都通过)。注意,ZTest Off等同于ZTest Always,关闭深度测试等于完全通过。ZWrite深度写入
ZWrite On(开启深度写入)和ZWrite Off(关闭深度写入)。当我们开启深度写入的时候,物体被渲染时针对物体在屏幕(更准确地说是frame buffer)上每个像素的深度都写入到深度缓冲区;反之,如果是ZWrite Off,那么物体的深度就不会写入深度缓冲区。但是,物体是否会写入深度,除了ZWrite这个状态之外,更重要的是需要深度测试通过,也就是ZTest通过,如果ZTest都没通过,那么也就不会写入深度了。就好比默认的渲染状态是ZWrite On和ZTest LEqual,如果当前深度测试失败,说明这个像素对应的位置,已经有一个更靠前的东西占坑了,即使写入了,也没有原来的更靠前,那么也就没有必要再去写入深度了。系统中存在一个颜色缓冲区和一个深度缓冲区,分别存储颜色值和深度值,来决定画面上应该显示什么颜色。
深度值是物体在世界空间中距离摄像机的远近。距离越近,深度值越小;距离越远,深度值越大。
如果我们硬要远处的红块遮挡住近处的蓝块,很显然,我们应该改变或关闭深度测试,或者关闭深度写入(关闭了深度测试或者深度写入之后,物体颜色的遮挡关系就会和渲染队列一致,即排在后面的会挡住前面的)。
现在处理世界ui与模型之间的渲染顺序
世界ui显示在模型之前
如图所示模型中间插入一个世界ui
最后游戏画面只显示了ui部分,模型的一半并没有挡住世界ui
使用如下shader
Shader "CustomUI/FirstImg" { Properties { [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {} _Color("Tint", Color) = (1,1,1,1) } SubShader { Tags { "Queue" = "Overlay" "IgnoreProjector" = "True" "RenderType" = "Transparent" "PreviewType" = "Plane" "CanUseSpriteAtlas" = "True" } Cull Off Lighting Off ZWrite Off ZTest Always Fog{ Mode Off } Blend SrcAlpha OneMinusSrcAlpha //ColorMask[_ColorMask] Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata_t { float4 vertex : POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; fixed4 color : COLOR; half2 texcoord : TEXCOORD0; }; fixed4 _Color; v2f vert(appdata_t IN) { v2f OUT; OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex); OUT.texcoord = IN.texcoord; #ifdef UNITY_HALF_TEXEL_OFFSET OUT.vertex.xy += (_ScreenParams.zw - 1.0)*float2(-1,1); #endif OUT.color = IN.color * _Color; return OUT; } sampler2D _MainTex; fixed4 frag(v2f IN) : SV_Target { half4 color = tex2D(_MainTex, IN.texcoord) * IN.color; return color; } ENDCG } } }
模型显示在世界ui之前
如图所示模型在世界ui的后面
最终游戏场景
世界ui类似天空盒一样显示在最后,即最先被渲染
使用shader
Shader "CustomUI/BgImg" { Properties { [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {} _Color("Tint", Color) = (1,1,1,1) } SubShader { Tags { "Queue" = "Background" "IgnoreProjector" = "True" "RenderType" = "Transparent" "PreviewType" = "Plane" "CanUseSpriteAtlas" = "True" } Cull Off Lighting Off ZWrite Off ZTest[unity_GUIZTestMode] Fog{ Mode Off } Blend SrcAlpha OneMinusSrcAlpha //ColorMask[_ColorMask] Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata_t { float4 vertex : POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; fixed4 color : COLOR; half2 texcoord : TEXCOORD0; }; fixed4 _Color; v2f vert(appdata_t IN) { v2f OUT; OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex); OUT.texcoord = IN.texcoord; #ifdef UNITY_HALF_TEXEL_OFFSET OUT.vertex.xy += (_ScreenParams.zw - 1.0)*float2(-1,1); #endif OUT.color = IN.color * _Color; return OUT; } sampler2D _MainTex; fixed4 frag(v2f IN) : SV_Target { half4 color = tex2D(_MainTex, IN.texcoord) * IN.color; return color; } ENDCG } } }
相关文章推荐
- Unity3d shader中Queue 使用渲染队列进行深度排序
- Unity3D - Shader - Unity Shader 的渲染顺序
- Unity3D中UGUI控制渲染顺序
- 【小松教你手游开发】【unity实用技能】控制renderQueue解决NGUI与Unity3D物体渲染顺序问题
- Unity3D shader(16)——“Queue”、“IgnoreProjector”、"RenderType"、Ztest、Zwrite、cull
- Unity3D 渲染顺序统一解决方案(主要是2D游戏)
- Unity3D 渲染物体世界坐标 WorldPosition Shader
- 在Unity3D中的渲染优化-优化Shader
- Unity3D 使用“Shift+Tab”和“Tab”键 上下切换 UGUI下 Dropdown和inputfield等控件的控制顺序
- Unity3d中shader属性的控制
- 【游戏渲染】【译】Unity3D Shader 新手教程(2/6) —— 积雪Shader
- Unity Shaders and Effects Cookbook (6-3) 修改渲染队列Queue 来 修改渲染顺序
- Unity3d shader编程 Forward渲染路径
- 详解Unity3D Shader开发之渲染管线
- python unittest控制用例的执行顺序
- 详解Unity3D Shader开发之渲染管线
- Unity3D - Shader - 渲染过程
- 【游戏渲染】【译】Unity3D Shader 新手教程(1/6)
- Unity3D教程:教你如何利用Shader来进行3D角色的渲染 |
- unity3d 双面渲染shader的编写