Unity Android透明效果实现与一面透明处理


Unity 中实现透明效果一般有两种方法

透明度测试(Alpha Test)

原理:只要片元的透明度不符合要求就直接舍弃


登录后复制

Shader "AlphaTest"{
    Properties{
        _MainTex ("Main Tex", 2D) = "white" {}
        _Color ("Color", Color) = (1, 1, 1, 1)
        _Cutoff ("Alpha Cutoff", Range(0, 1)) = 0.5 //控制剔除的阈值
    }
    SubShader
    {
        Tags { "Queue"="AlphaTest" "IgnoreProjection"="True" "RanderType"="TransparentCutout"}

        Pass{
            Tags { "LightMode"="ForwardBase" } 
            
            Cull Off	//用于双面渲染,不剔除背对摄像机的图元
            
            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag

            #include "Lighting.cginc"

            struct appdata{
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal : NORMAL;
            };

            struct v2f{
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                float3 worldPos : TEXCOORD1;
                float3 worldNormal : TEXCOORD2;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed _Cutoff;
            fixed4 _Color;

            v2f vert (appdata v){
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                o.worldNormal = UnityObjectToWorldNormal(v.normal);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target{
                float3 worldNormal = normalize(i.worldNormal);
                float3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));

                float4 texColor = tex2D(_MainTex, i.uv);
                clip(texColor.a - _Cutoff);
                //Equal to
                //if( (texColor.a - _Cutoff) < 0.0 ){
                //  discard;    
                //}
                float3 albedo = texColor.rgb * _Color.rgb;

                float3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;

                float3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, worldLightDir));

                return fixed4(ambient + diffuse, 1.0);
            }
            ENDCG
        }
    }
    FallBack "Transparent/Cutout/VertexLit"
}

透明度测试可以用于消解动画效果的实现

android unity3d 透明 unity有一面呈现透明_android unity3d 透明

android unity3d 透明 unity有一面呈现透明_android unity3d 透明_02

透明度混合(Alpha Blending)

原理:当前片元的透明度作为混合参数与颜色缓冲中的颜色值混合

关闭深度写入,但不关闭深度测试



关闭深度写入将导致渲染顺序变得非常重要

一般做法:

  1. 先渲染所有不透明物体,同时开启深度写入和深度测试
  2. 半透明物体按距离远近排序,然后从后往前渲染,开启深度测试,关闭深度写入

由于排序是对于物体来说的,当物体间循环重叠时就需要用分割物体、分割网格的方法来解决

  • 尽可能让模型是凸面体
  • 让透明通道更柔和,难以分辨
  • 使用开启深度写入的半透明效果近似物体半透明



对于双面渲染的透明度混合,由于关闭了深度写入,在渲染时需要控制渲染顺序

登录后复制


SubShader {
	Tags {"Queue"="Transparent" "IgnoreProjection"="True" "RanderType"="Transparent"}
	
	ZWrite Off
    Blend SrcAlpha OneMinusSrcAlpha //开启混合模式,设定混合因子
    
	Pass {
		...
		Cull Front	//剔除正面,渲染背面
		...
	}
	Pass {
		...
		Cull Back	//提出背面,渲染正面
		...
	}
}

android unity3d 透明 unity有一面呈现透明_Blend_03

半透明物体的阴影没了,暂时不知道原因

深度写入的半透明效果

使用两个 Pass

  • 第一个开启深度写入但不输出颜色
  • 第二个进行透明度混合

由于深度信息是对像素来说的,所以如果单个模型本身存在自我遮挡,那么被遮挡部分就直接舍弃了

ColorMask RGB | A | 0 | ...表示当前 Pass 写入的颜色通道

Unity预定义渲染队列

SubShaderQueue标签定义:Tags { "Queue"="AlphaTest" }


名称索引号描述
Background1000最先开始渲染的队列,一般用于绘制于背景上的物体
Geometry2000默认队列,不透明物体
AlphaTest2450透明度测试,在不透明物体之后渲染可以更高效
Transparent3000透明度混合,从后往前的顺序进行渲染
Overlay4000用于最后渲染的物体,实现一些叠加效果

索引号越小越早被渲染

混合

混合不可编程但高度可配置

混合源颜色(当前片元)和目标颜色(颜色缓冲)

  • Blend SrcFactor DstFactor: 只混合rgb通道
  • Blend SrcFactor DstFactor,SrcFactorA DstFactorA: 上面的基础上,再混合 a 通道

例子:

Blend SrcAlpha OneMinusSrcAlpha:开启混合,并且混合结果是 \(Src.a * Src.rgb + (1-Src.a)*Des.rgb\)



还可以配置混合操作

BlendOp BlendOperation

即改变源颜色和目标颜色最后的混合方式,默认为 Add


操作描述
Add加法
Sub减法
RevSub交换减法
Min取各分量的最小值
Max取各分量的最大值



同时使用上面两种方法可设定混合类型


类型描述
正常Blend SrcAlpha OneMinusSrcAlpha
柔和相加Blend OneMinusDstAlpha One
正片叠底Blend DstColor Zero
两倍相乘Blend DstColor SrcColor
变暗BlendOp Min Blend One One
变亮BlendOp Max Blend One One
滤色Blend OneMinusDstColor One
线性减淡Blend One One

   

 

免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空