在之前的记录中已经知道了透明度测试的原理。本节主要就在Unity中通过透明度测试实现透明效果进行实践。

原理回顾

透明度测试采用一种“非舍即留”的机制,即,若某片元的透明度不满足条件(通常小于某个阈值),则舍弃;否则就按照不透明物体去处理。也就是说,透明度测试是不关闭深度写入的。它产生的结果要么完全透明,看不到;要么完全不透明,与其他不透明物体一样。

通常,使用clip函数在片元着色器中进行透明度测试。clip是CG的一个函数,其参数是裁剪时使用的标量或矢量条件。若,给定参数的任何一个分量是负数,就会舍弃当前像素的输出颜色。

实践

  • 运行平台:Unity 2018.4.2f1 (64-bit)
  • 项目地址:
    Unity_Shader_GetIn

准备工作

  1. 在Unity中新建一个场景,命名为Scene_8_3。默认场景中将包含一个摄像机和一个平行光,并使用内置的天空盒子。为便于查看效果,在Window->Rendering->Lighting Seting->Skybox中去掉场景中的天空盒子。
  2. 新建Shader(右键Create->Shader->任一个Shader)并命名为AlphaTest;新建材质(右键Create->Material)并命名为AlphaTestMat,将新建的Shader拖拽赋给新建材质。
  3. 在场景中创建一个立方体,并拖拽到合适位置,将其材质修改为新建材质。
  4. 保存场景。

其他准备:一张透明纹理,其中每个方格的透明度不同(从左到右,从上到下依次是80%,70%,60%,50%)

Shader实现:

打开新建的AlphaTest,删除所有已有代码并写入如下代码:

Shader "Custom/AlphaTest" {Properties {_Color ("Color Tint", Color) = (1, 1, 1, 1)_MainTex ("Main Tex", 2D) = "white" {}//声明控制透明度测试时使用的阈值,其范围为[0,1]_Cutoff ("Alpha Cutoff", Range(0, 1)) = 0.5}SubShader {Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}//RenderType标签可以让这个Unity把这个Shader归入到提前定义的组中//通常,使用透明度测试的shader都应该在SubShader中设置这三个标签Pass {Tags { "LightMode"="ForwardBase" }CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"fixed4 _Color;sampler2D _MainTex;float4 _MainTex_ST;fixed _Cutoff;//由于其范围是[0,1],所以可以用fixed精度来存储struct a2v {float4 vertex : POSITION;float3 normal : NORMAL;float4 texcoord : TEXCOORD0;};struct v2f {float4 pos : SV_POSITION;float3 worldNormal : TEXCOORD0;float3 worldPos : TEXCOORD1;float2 uv : TEXCOORD2;};v2f vert(a2v v) {v2f o;o.pos = UnityObjectToClipPos(v.vertex);//在顶点着色器中计算出世界空间下的法线方向和顶点位置以及变换后的坐标o.worldNormal = UnityObjectToWorldNormal(v.normal);o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);return o;}fixed4 frag(v2f i) : SV_Target {fixed3 worldNormal = normalize(i.worldNormal);fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));fixed4 texColor = tex2D(_MainTex, i.uv);// Alpha test 若texColor.a小于_Cutoff,则物体完全透明clip (texColor.a - _Cutoff);fixed3 albedo = texColor.rgb * _Color.rgb;fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, worldLightDir));return fixed4(ambient + diffuse, 1.0);}ENDCG}} //使用内置VertexLit来回调shader,不仅可以保证在我们编写的SubShader无法在当前显卡上工作时可以有合适的替代shader,还可以保证使用透明度测试的物体可以正确的向其他物体投射阴影FallBack "Transparent/Cutout/VertexLit"
}

保存返回后,使用之前准备的透明纹理,并调节cutoff参数可以得到如下效果:

从图中可以看出,透明度测试得到的透明效果很“极端”,随着Alpha cutoff参数的增大,更多的像素由于不满足透明度测试条件而被剔除,其效果就像不透明物体上出现了空洞。而且边缘处层次不齐有锯齿。

因而下一部分将使用一种更为柔和的方式——透明度混合来实现透明效果~

双面渲染

在现实生活中,若一个物体是透明的,意味着我们不仅可以透过它看到其他物体的样子,也应该可以看到它内部的结构。但在之前实现的透明度测试中,无法得到这样的效果,导致物体看起来只有半个。这是因为默认情况下渲染引擎剔除了物体背面的渲染图元。若要得到双面渲染的效果,可以使用Cull指令来控制需要剔除哪个面的渲染图元。

Unity中Cull指令的语法如下:
​ Cull Back/Front/Off
设置为Back则背面不渲染,其他同理。需要注意的是设置为 Off时,渲染图元数目会成倍增加,因此通常情况下不会设置为 Off

那么如何实现呢?

很简单,只需新建一个AlphaTestBothSideMat和对应的AlphatTestBothSide Shader的代码并复制粘贴AlphaTest代码,在pass中添加一行:

Pass {Tags { "LightMode"="ForwardBase"}//Turn off cullingCull off

此时我们可以透过镂空区域看到立方体内部的结构,效果如下:

参考

Unity_Shaders_Book : https://github.com/candycat1992/Unity_Shaders_Book

Unity Scripting Reference : https://docs.unity3d.com/ScriptReference/index.html

Unity Manual: https://docs.unity3d.com/Manual/TextureTypes.html

html透明度_Unity透明效果-透明度测试相关推荐

  1. unity 2d摄像机类型_Unity透明效果-开启深度写入的半透明效果实现

    上一部分中提到了由于关闭深度写入而产生的遮挡问题,本小节将进行一种解决上述问题的实践--开启深度写入的两个Pass的透明效果实现. 基本思想 使用两个Pass进行渲染: 第一个Pass开启深度写入,但 ...

  2. 透明效果(六)--透明测试

    [本系列文章系学习 唐福幸<Unity ShaderLab 新手宝典>的笔记,包含个人理解,如有错误欢迎批评指出 透明效果 7.4 透明测试 7.4.1透明测试 7.2抗锯齿 一句话总结: ...

  3. 透明效果 -- Shader入门精要学习(7)

    透明效果 对于不透明的物体,不考虑其渲染顺序也能得到正确的结果,这是由于强大的深度缓冲的存在 几个概念: 深度缓冲(z-buffer):用于解决可见性问题,它可以决定哪个物体的哪些部分会被渲染在前面, ...

  4. 透明度--设置透明、半透明等效果

    设置透明效果 大概有三种. 1.用android系统的透明效果: android:background="@android:color/transparent" 例如 设置按钮 & ...

  5. Shader-透明效果-透明度测试

    深度缓冲: 渲染每个物体,会将深度值写入深度缓冲. ZWrite: Controls whether pixels from this object are written to the depth ...

  6. Flutter透明度渐变动画Opacity实现透明度渐变动画效果

    题记 -- 执剑天涯,从你的点滴积累开始,所及之处,必精益求精,即是折腾每一天. ** 你可能需要 CSDN 网易云课堂教程 掘金 EDU学院教程 知乎 Flutter系列文章 在Flutter 中实 ...

  7. Flutter透明度渐变动画FadeTransition实现透明度渐变动画效果

    题记 -- 执剑天涯,从你的点滴积累开始,所及之处,必精益求精,即是折腾每一天. ** 你可能需要 CSDN 网易云课堂教程 掘金 EDU学院教程 知乎 Flutter系列文章 在Flutter 中实 ...

  8. Android控件入门-动画效果(透明度动画)

    透明度动画(alpha): 第一种方式: xml: <Buttonandroid:id="@+id/btn_alpha"android:layout_width=" ...

  9. Unity Shader 之 透明效果

    本文引用 Unity Shader入门精要 开启透明混合后,一个物体被渲染到屏幕上时,每个片元除了颜色值和深度值外,还有--透明度.透明度为1,则完全不透明,透明度为0,则完全不会显示. 在Unity ...

最新文章

  1. IT巨头混战平板市场三大系统争霸格局初现
  2. 20162309单步追踪数组及查找课下补分博客
  3. linux自动化安装oracle,ftp的客户端软件 Linux环境一键自动化安装oracle软件的构想(附she...
  4. Generic 打印ID对应的object type的工具
  5. php网页 安装插件,插件安装流程
  6. linux设置开机自启 etc rt.d,Linux下禁止服务开机自启动
  7. Java消息中间件--JMS规范
  8. win7 nginx php 环境,win7下docker环境搭建nginx+php-fpm+easyswoole+lavarel开发环境
  9. 华为防火墙USG6320透明模式配置
  10. 机器学习--支持向量机(五)核函数详解
  11. awd赛题的flag是什么意思_记一次AWD自动获取flag并提交
  12. 丹东思凯公司承担的吉林水务集团同城联网及银行代缴平台系统项目正式运行...
  13. hget和get redis_Redis Hash 的 HSET、HGET、HMSET、HMGET 性能测试
  14. 《设计模式》学习笔记——开闭原则
  15. 禁止从终端服务器复制文件
  16. Word 域嵌套太深弹窗,更新域卡顿,解决办法
  17. python微妙级sleep
  18. HTML5、CSS3应用教程之 跟DIV说Bey!Bey!
  19. 黑鹰红客基地VIP美工教程系列
  20. Python自动化学习笔记(八)——接口开发、发送网络请求、发送邮件、写日志...

热门文章

  1. Unix域socketpair函数使用
  2. 利器 | 测试必会之 Linux 三剑客 ( grep / awk / sed )
  3. 《圈子圈套》作者今天中午关于卖什么样的产品和在什么样的公司做销售比较“好”?主题的在线聊天纪录
  4. IDL 一维数组的Sen斜率实现
  5. 树形dp讲解(你不会后悔点进来)
  6. iphone开发导航控制器的使用
  7. 每周全球科技十大新闻(2021.6.14-6.20)美国核能开放支持“矿工”
  8. IT分销渠道的增值管理
  9. 网络安全-HSRP协议
  10. 哈利波特魔法觉醒把戏坊烟花盒怎么用