马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
透明度测试
1、透明测试是用于处置惩罚哪种透明需求
在游戏开辟中对象的某些部位完全透明而其他部位完全不透明,这种透明需求通常不须要半透明结果,相对比力极度,只有看得见和看不见之分好比树叶、草、栅栏等等。(即一张图除了紧张物体有颜色,其他地域都为透明)
2、透明测试的根本原理
根本原理:通过一个阈值来决定哪些像素应该被保存,哪些应该被抛弃
详细实现:片元携带的颜色信息中的透明度(A值),不满意条件时(通常是小于某个阈值),该片元就会被舍弃,被舍弃的片元不会在举行任那边理,不会对颜色缓冲区产生任何影响;满意条件时(通常是大于即是某个阈值),该片元会按照不透明物体的处置惩罚方式来处置惩罚
阈值判断使用的方法:使用CG中的内置函数:clip(参数)
该函数有重载,参数范例可以是 float4 float3 float2 float 等等,如果传入的参数任何一个分量是负数就会舍弃当前片元它的内部实现会用到一个 discard 指令,代表剔除该片元 不再到场渲染
- void clip(float4 x) {
- if (any(x < 0))
- discard;
- }
复制代码 3、透明测试实现
- 复制颜色纹理联合光照模子的Shader
- 在属性中加一个阈值_Cutoff,取值范围为0~1,用来设定用来判断的阈值。并在CG中添加属性的映射成员
- 将渲染队列设置为AlphaTest,并共同IgnoreProjector和RenderType一起设置
- 在片元着色器中获取了颜色贴图颜色后,就举行阈值判断
注意:透明度测试不须要关闭深度写入
选用下面这张各个地域透明度差别的纹理图片

- Shader "ShaderProj/3/TransparentTest"
- {
- Properties
- {
- _MainTex("MainTex", 2D) = ""{}
- _MainColor("MainColor", Color) = (1,1,1,1)
- _SpecularColor("SpecularColor", Color) = (1,1,1,1)
- _SpecularNum("SpecularNum", Range(0,20)) = 15
- _CutOff("CutOff", Range(0,1)) = 0 // 透明度测试阈值
- }
- SubShader
- {
- Tags{
- "Queue"="Transparent"
- "IgnoreProjector"="True"
- "RenderType"="TransparentCutout"
- }
- Pass
- {
- Tags { "LightMode"="ForwardBase" }
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- #include "UnityCG.cginc"
- #include "Lighting.cginc"
- sampler2D _MainTex;
- float4 _MainTex_ST;
- fixed4 _MainColor;
- fixed4 _SpecularColor;
- float _SpecularNum;
- fixed _CutOff;
- struct v2f
- {
- float4 pos:SV_POSITION;
- float2 uv:TEXCOORD0;
- float3 wNormal:NORMAL;
- float3 wPos:TEXCOORD01;
- };
- fixed3 getLambertColor(float3 normal, float3 lightDir, fixed3 albedo)
- {
- fixed3 color = _LightColor0 * albedo * max(0, dot(lightDir, normal));
- return color;
- }
- fixed3 getSpecularColor(float3 worldPos, float3 normal, float3 lightDir)
- {
- //float3 viewDir = normalize(_WorldSpaceCameraPos - worldPos);
- float3 viewDir = normalize(UnityWorldSpaceViewDir(worldPos));
- float3 halfAngle = normalize(viewDir + lightDir);
- fixed3 color = _LightColor0 * _SpecularColor * pow(max(0, dot(normal, halfAngle)), _SpecularNum);
- return color;
- }
-
- v2f vert (appdata_base v)
- {
- v2f data;
- data.pos = UnityObjectToClipPos(v.vertex);
- data.wNormal = UnityObjectToWorldNormal(v.normal);
- data.wPos = mul(unity_ObjectToWorld, v.vertex);
- data.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
- //data.uv = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
- return data;
- }
- fixed4 frag (v2f i) : SV_Target
- {
- // 透明度测试
- fixed4 texColor = tex2D(_MainTex, i.uv);
- clip(texColor.a - _CutOff);
- fixed3 albedo = texColor.rgb * _MainColor.rgb;
- float3 lightDir = normalize(_WorldSpaceLightPos0);
- fixed3 lambertColor = getLambertColor(i.wNormal, lightDir, albedo);
- fixed3 specularColor = getSpecularColor(i.wPos, i.wNormal, lightDir);
- fixed3 color = lambertColor + specularColor + UNITY_LIGHTMODEL_AMBIENT.rgb * albedo;
- return fixed4(color, 1);
- }
- ENDCG
- }
- }
- }
复制代码 透明度肴杂
1、透明度肴杂是用来处置惩罚哪种需求
透明度测试,并不能用于实现半透明结果,它只存在看得见和完全看不见两种状态,一样寻常用来处置惩罚镂空结果,透明度肴杂紧张就是用来实现半透明结果的
2、透明度肴杂的根本原理
根本原理:关闭深度写入,开启肴杂,让片元颜色和颜色缓冲区中颜色举行肴杂盘算
3、透明度肴杂实现
- 我们复制 Lesson50 中颜色纹理联合光照模子的Shader(由于我们的测试资源没有法线贴图等数据)
- 在属性中加一个阈值_AlphaScale
|