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

原理回顾

透明度测试采用一种“非舍即留”的机制,即,若某片元的透明度不满足条件(通常小于某个阈值),则舍弃;否则就按照不透明物体去处理。也就是说,透明度测试是不关闭深度写入的。它产生的结果要么完全透明,看不到;要么完全不透明,与其他不透明物体一样。通常,使用clip函数在片元着色器中进行透明度测试。clip是CG的一个函数,其参数是裁剪时使用的标量或矢量条件。若,给定参数的任何一个分量是负数,就会舍弃当前像素的输出颜色。

实践运行平台:

Unity 2018.4.2f1 (64-bit)

准备工作在Unity中新建一个场景,命名为Scene_8_3。默认场景中将包含一个摄像机和一个平行光,并使用内置的天空盒子。为便于查看效果,在Window->Rendering->Lighting Seting->Skybox中去掉场景中的天空盒子。

新建Shader(右键Create->Shader->任一个Shader)并命名为AlphaTest;新建材质(右键Create->Material)并命名为AlphaTestMat,将新建的Shader拖拽赋给新建材质。

在场景中创建一个立方体,并拖拽到合适位置,将其材质修改为新建材质。

保存场景。

其他准备:一张透明纹理,其中每个方格的透明度不同(从左到右,从上到下依次是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 culling

Cull off

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

参考

unity 设置image透明度_Unity透明效果-透明度测试相关推荐

  1. html透明度_Unity透明效果-透明度测试

    在之前的记录中已经知道了透明度测试的原理.本节主要就在Unity中通过透明度测试实现透明效果进行实践. 原理回顾 透明度测试采用一种"非舍即留"的机制,即,若某片元的透明度不满足条 ...

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

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

  3. unity 设置图片九宫格_Unity UGUI篇 Image图片

    今天介绍一下 UI 组件之 Image 组件 , Image 用来显示图片的 . 我们从unity 里选取一张图片 , 修改为 sprite格式 然后把图片拖到 Image 组件中的 Source I ...

  4. unity 设置图片九宫格_unity学习5_UGUI_Image_Sprite(2D_and_UI)

    unity学习5_UGUI_Image_Sprite(2D_and_UI) (1)Source Image:资源文件 Unity的image组件需要的Source Image类型为Sprite类型, ...

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

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

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

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

  7. 《Unity着色器和屏幕特效》——2.2 进阶的透明效果

    本节书摘来自华章计算机<Unity着色器和屏幕特效>一书中的第2章,第2.2节,作者[美]杰米·迪恩(Jamie Dean),译 周翀,张薇,更多章节内容可以访问云栖社区"华章计 ...

  8. Unity Shader 之 透明效果

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

  9. unity 透明度算法_unity3D之透明度

    unity3D 之 Transparency 我们讲到在 Shader 的 #pragma 声明中添加 alpha 参数来实现透明效果真的是非常 方便.事实上, Unity 还提供了另一种参数来实现一 ...

  10. Unity Shader透明效果

    在实时渲染中要实现透明效果,通常会在渲染模型时控制他的透明通道.当开启透明混合后,当一个物体被渲染到屏幕上时,每个片元除了颜色值和深度值之外,它还有另一个属性--透明度.当透明度为1时表示该像素是完全 ...

最新文章

  1. pyqt5讲解11:自定义信号和槽
  2. BTrace使用小结
  3. 为什么lamda不能修改外部引用的变量?
  4. patch请求_SpringMVC源码学习(三) 请求处理的流程
  5. WebService学习总结(2)——WebService是什么?
  6. python 如何获取文件夹下所有的目录。
  7. mysql系列之4.mysql字符集
  8. Spring Security 工作原理概览
  9. LeetCode OJ:Maximal Rectangle(最大矩形)
  10. 多屏互动电脑版_手机、电脑屏幕太小怎么办?这4招秒变大屏
  11. SaaSpace:25款最佳免费视频编辑软件工具
  12. SweepProfile for 3dMax石膏线生成插件使用教程
  13. cocos2d-lua 3x 基础概念(包括场景、导演、在屏幕上显示自定义对象等)
  14. 软件测试面试两个月,我是如何进入奇虎360?面试总结分享给大家
  15. 《预训练周刊》第52期:屏蔽视觉预训练、目标导向对话
  16. 信号完整性(SI)电源完整性(PI)学习笔记(二)时域与频域
  17. 泛微E9升级KB包方法
  18. loadrunner--浏览器不支持或禁止了网页脚本,导致您无法正常登录
  19. stm32c8t6+dht11+MQ系列环境检测模块+oled显示屏(基于物联网的家庭环境检测系统设计)
  20. 梦幻仙缘剧情java_梦幻仙缘ios下载-梦幻仙缘苹果版1.0 ios变态版-东坡下载

热门文章

  1. 项目管理的10个经典故事
  2. SSM-Mybatis的Mapper.xml配置文件
  3. Stack的三种含义
  4. 一项采用MasimoO3(R)的前瞻性研究就通气抢救疗法对COVID-19患者脑氧合的效应进行了深入探查
  5. 深度学习在图像处理中的应用(tensorflow2.4以及pytorch1.10实现)
  6. 给定一个数组,求数组的最大连续子数组,使得该子数组的和最大
  7. 论自律对成长的重要性
  8. HTML嵌入百度地图
  9. 开发3dMax插件的方法和应用
  10. Feb14 小白《Linux就该这么学》学习笔记1