本系列主要参考《Unity Shaders and Effects Cookbook》一书(感谢原书作者),同时会加上一点个人理解或拓展。

这里是本书所有的插图。这里是本书所需的代码和资源(当然你也可以从官网下载)。

========================================== 分割线 ==========================================

写在前面

从这篇开始是一个全新的章节:透明效果(Transparency)。之前在制作LOGO闪光效果的时候就一直调不出来背景透明,就是那个时候决定要学一下Shader的基础知识,不求成为多么厉害的大神,只望对渲染的内部原理有些许了解~

开始正文。

在我们学习如何编写透明的Surface Shader的开始,我们需要理解应该包含哪些代码使得我们可以开启透明效果。Unity再一次慷慨地为我们提供了一些内置参数,我们可以通过包含这些参数来快速得到透明效果。

这是通过在Shader的#pragma声明中添加alpha参数来实现的。这句话告诉Unity我们想要在Shader中使用透明度。但当我们在创建透明Shaders时,需要仔细考虑一些事情,那就是代码中元素的绘制顺序。这篇文章将会讲述一些基本问题,来得到一个非常简单的透明物体。在下面的章节中,将会讲解其他有关透明度的问题。

准备工作

和以前一样,我们需要创建一个新的场景。

  1. 创建一个新的场景,添加一个平行光以及一个球体(Sphere)。
  2. 创建一个新的Shader和新的Material,可以命名为SimpleAlpha。把Shader赋给Material后,再把该Material赋给第一步中的球体。
  3. 最后,我们需要一张贴图作为控制隐私,来控制哪些部分是透明的,哪些部分是不透明的。
下图是我们用到的贴图。这张贴图仅包含单纯的RGB和白色(自带资源中没有,可以自己画,很简单)。我们使用它的RGB通道作为一个取值为0或1的透明度值。

实现

这篇Shader非常简单。
  1. 在Properties块中添加一个新的property,这使得我们可以全局控制透明度。
    	Properties {
    _MainTex ("Base (RGB)", 2D) = "white" {}
    _TransVal ("Transparency Value", Range(0,1)) = 0.5
    }
  2. 改变渲染队列:
    Tags { "Queue"="Transparent" }

    解释:这一步很重要,原书中没有添加这一句实际是错误的。

  3. 然后,我们在#pragma声明中添加一个新的参数:alpha参数。
    		CGPROGRAM
    #pragma surface surf Lambert alpha

    解释:再解释一遍上面这句声明的意思。使用名为surf的Surface Function,使用内置的Lambert光照函数,开启透明通道。

  4. 最后,在surf()函数中添加控制透明度的代码。
    		void surf (Input IN, inout SurfaceOutput o) {
    half4 c = tex2D (_MainTex, IN.uv_MainTex);
    o.Albedo = c.rgb;
    o.Alpha = c.b * _TransVal;
    }
完整代码如下:
Shader "Custom/SimpleAlpha" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_TransVal ("Transparency Value", Range(0,1)) = 0.5
}
SubShader {
Tags { "RenderType"="Opaque" "Queue"="Transparent"}
LOD 200 CGPROGRAM
#pragma surface surf Lambert alpha sampler2D _MainTex;
float _TransVal; struct Input {
float2 uv_MainTex;
}; void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.b * _TransVal;
}
ENDCG
}
FallBack "Diffuse"
}
如果没有透明效果,如下所示:
最后效果如下(从左到右分别对应了o.Alpha = c.r * _TransVal, o.Alpha = c.g * _TransVal, o.Alpha = c.b * _TransVal):

解释

你可以看到,使用Unity的Surface Shaders得到透明效果是非常容易的。这类Shader依赖三个元素:正确设置Shader渲染队列,#pragma声明中的alpha参数,以及在SurfaceOutput结构体中的Alpha值。
Tags { "Queue"="Transparent" }一步将决定半透明物体和不透明物体之间正确的渲染关系,如果没有正确设置,那么很有可能就会出现后面的物体跑到了透明物体的前面。具体解释可以参见这篇文章
一旦我们在#pragma声明中添加了alpha参数,这就告诉了Unity:嘿,接下来你要允许我渲染一个透明的surface。然后,我们就仅仅需要逐像素地使用一个取值范围为0到1的值来填充SurfaceOutput结构体中的O.Alpha值。从颜色角度讲(这里的颜色指一个灰度值,因为透明度可以用一个单通道的灰度值来表示),一个为1的透明度,即白色,将会产出一个完全不透明的效果。而0值,即黑色,表示一个完全透明的效果。
这就解释了上述的效果。例如,当我们使用如下语句控制透明度:
o.Alpha = c.r * _TransVal

则贴图中除了红色部分以及白色部分(白色的RGB通道值均为1)其R通道的值为1,其余(绿色和蓝色部分)均为0。因此只有红色和白色的部分才不透明。

尽管关于透明度有很多东西,但我们要知道,上述是其最基本的实现。在下面的章节中,我们将开始如何在实时渲染中使用alpha通道或者半透明的Shader。

【Unity Shaders】Transparency —— 使用alpha通道创建透明效果的更多相关文章

  1. Unity3D ShaderLab 使用alpha参数创建透明效果

    Unity3D ShaderLab 使用alpha参数创建透明效果 其实Unity为了方便我们的工作,为我们内置了很多参数.比如马上用到的透明功能. 准备场景新建Shader Material ,一张 ...

  2. Unity 游戏开发技巧集锦之创建透明的材质

    Unity 游戏开发技巧集锦之创建透明的材质 Unity创建透明的材质 生活中不乏透明或者半透明的事物.例如,擦的十分干净的玻璃,看起来就是透明的:一些塑料卡片,看起来就是半透明的,如图3-23所示. ...

  3. Unity如何播放带有alpha 通道的视频

    问题: 当使用Video Player播放带有alpha 通道的视频时带有黑色背景 解决方式: 使用文件格式为WEBM的视频,对视频文件进行的修改 在RawImage中,将New Render Tex ...

  4. 【计算机视觉】OPENCV对于有alpha通道的透明背景图片的读取和图片叠加

    这个是我自己做的粗略的螺旋丸的图,导出为png并带有alpha通道. 最后和一只狗合成成这个样子. 效果还是可以的. 为了实现这个效果,首先我们要明白具有透明通道的图片的OpenCV的读取方式.在Op ...

  5. Unity中播放带有alpha通道格式为Mp4的视频

    问题: Unity中实现播放透明的MP4视频时出现黑点 解决办法:    使用Unity自带的shader去除黑点 1:shader代码如下所示 Shader "Unlit/NewUnlit ...

  6. Unity Shader入门精要学习笔记 - 第8章 透明效果

    转载自 冯乐乐的 <Unity Shader入门精要> 透明是游戏中经常要使用的一种效果.在实时渲染中要实现透明效果,通常会在渲染模型时控制它的透明通道.当开启透明混合后,当一个物体被渲染 ...

  7. 【Unity Shaders】Transparency —— 透明的cutoff shader

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  8. 【Unity Shaders】Transparency —— 使用渲染队列进行深度排序

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  9. 关于Unity中混合模式、Alpha测试、深度测试、通道遮罩、面剔除的使用----渲染通道通用指令(二)

    混合模式 着色完成后,需要把颜色混合到帧缓冲区里面,涉及到源和目标. 1:在所有计算完成后,决定当前的计算结果输出到帧缓冲区时,如何混合源和目标,通常用来绘制半透明的物体;2: Blend Off 关 ...

随机推荐

  1. curl支持HTTP和https

    设计流程 基于curl工具实现https/http,设计初步流程为:linux平台验证→→交叉移植arm板. linux系统下调试http和https 1.1 Linux安装curl 输入命令:sud ...

  2. Exchange Server 2010升级到Exchange Server 2016

    Hello各位小伙伴们,失踪人口回归啦~~~这次和大家分享Exchange Server 2010升级到Exchange Server 2016的方法.正式开始前先啰嗦几句,为什么我要写这篇文章呢?一 ...

  3. Python小代码_3_购物车

    product_list = [ ('MacBook', 9000), ('kindle', 500), ('tesla', 900000), ('book', 100), ('bike', 2000 ...

  4. No package tomcatX available. 解决办法

    当一个新的linux系统到手时,就要开始部署相关软件等等,有时候可能遇到无法安装的情况. 例如yum install tomcat7,在centos下无法安装,因为tomcat不再yum里面,怎么办呢 ...

  5. JConsole/JvisualVM 远程连接失败处理

    今天在使用JConsole进行远程连接时,发现IP和端口在Windows下是可以远程telnet的,但是,使用JConsole时却无法连接. 我的环境如下: Windows下运行JConsole,准备 ...

  6. swing JTable 更新数据

    rowData 是将要更新的表格内数据,coloumnName是将要更新的表头数据. table是原本的table对象,更新数据的时候要用 DefaultTableModel 类~ /*更新table ...

  7. 让你的代码量减少3倍!使用kotlin开发Android(二) --秘笈!扩展函数

    本文承接上一篇文章:让你的代码量减少3倍!使用kotlin开发Android(一) 创建Kotlin工程 本文同步自博主的私人博客wing的地方酒馆 上一节说到,kotlin可以省去getter,se ...

  8. linux:如何指定进程运行的CPU

    coolshell最新的文章<性能调优攻略>在"多核CPU调优"章节,提到"我们不能任由操作系统负载均衡,因为我们自己更了解自己的程序,所以,我们可以手动地为 ...

  9. Spring MVC 实践 - Component

    Spring MVC 实践 标签 : Java与Web Converter Spring MVC的数据绑定并非没有任何限制, 有案例表明: Spring在如何正确绑定数据方面是杂乱无章的. 比如: S ...

  10. 深度学习与计算机视觉系列(3)_线性SVM与SoftMax分类器

    作者: 寒小阳 &&龙心尘 时间:2015年11月. 出处: http://blog.csdn.net/han_xiaoyang/article/details/49949535 ht ...