Chapter8 透明效果——Shader入门精要学习笔记

一、基本概念

  • 在Unity中通常使用两种方法来实现透明效果
    • 透明度测试(无法达到真正的半透明效果)
    • 透明度混合(关闭了深度写入)

透明度测试

  • 基本原理:设置一个阈值,只要片元的透明度小于阈值,就会被舍弃(不会进行任何处理,也不会对颜色缓冲造成影响);否则,就会按照普通的不透明物体来处理(进行深度测试、深度写入等)
  • 效果极端,要么透明,要么完全不透明

透明度混合

  • 基本原理:使用当前片元的透明度作为混合因子,与已经存储在颜色缓冲中的颜色值进行混合,得到新的颜色
  • 需要关闭深度写入,但没有关闭深度测试——深度缓冲是只读的
    • 为什么关闭深度写入:如果开启,半透明物体在不透明物体前面时,半透明物体会挡住不透明物体,实现不了半透明效果
  • 可以实现半透明效果

二、渲染顺序

  • 对于半透明物体和不透明物体,因为关闭了深度写入,所以应该在不透明物体渲染完后再渲染半透明物体
  • 对于两个半透明物体,应该先渲染远处的,再渲染近处的(不准确)

1.渲染引擎的方法

  • 先渲染所有不透明物体,并开启他们的深度测试和深度写入
  • 把半透明物体按他们的距离摄像机的远近进行排序,再按照从后往前的顺序渲染,开启深度测试,关闭深度写入
    • 会有更加复杂的重叠情况,排序困难

2.Unity的渲染顺序

  • 使用SubShader的 Queue 标签来决定我们的模型将归于哪个渲染队列,使用整数索引来表示每个渲染队列,号小的越早被渲染
    在这里插入图片描述
  • 如果想要通过透明度测试来实现效果,代码:
SubShader{Tags{ "Queue" = "AlphaTest"}Pass{...}}
  • 如果想使用透明度混合
SubShader{Tags{ "Queue" = "Transparent"}Pass{ZWrite Off //关闭深度写入...}}

三、透明度测试

  • 基本原理:设置一个阈值,只要片元的透明度小于阈值,就会被舍弃(不会进行任何处理,也不会对颜色缓冲造成影响);否则,就会按照普通的不透明物体来处理(进行深度测试、深度写入等)
  • 通常会在片元着色器中使用 clip函数 进行透明度测试
    • 如果给定参数的任何一个分量是负数,则会舍弃当前像素的输出颜色
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'Shader "Custom/Chapter8-AlphaTest"
{Properties{_Color ("Main Tint", Color) = (1,1,1,1)_MainTex ("Main Tex", 2D) = "white"{}_Cutoff ("Alpha Cutoff", Range(0,1)) = 0.5//用于决定我们调用clip进行透明度测试时使用的判决条件}SubShader{Tags {"Queue" = "AlphaTest" "IgnoreProjector" = "True" "RenderType" = "TransparentCutoff"}Pass{Tags{"LightMode" = "ForwardBase"}CGPROGRAM#pragma vertex vert #pragma fragment frag#include "Lighting.cginc"fixed4 _Color;sampler2D _MainTex;float4 _MainTex_ST;fixed _Cutoff;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);//透明度测试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}}FallBack "Transparent/Cutout/VertexLit"
}
  • _Cutoff (“Alpha Cutoff”, Range(0,1)) = 0.5 用于决定我们调用clip进行透明度测试时使用的判决条件
  • clip(texColor.a - _Cutoff); 做透明度测试,判断texColor.a - _Cutoff是否为负数,负数的纹理颜色为全透明
    在这里插入图片描述

四、透明度混合

  • 基本原理:使用当前片元的透明度作为混合因子,与已经存储在颜色缓冲中的颜色值进行混合,得到新的颜色
  • 需要使用Unity提供的混合命令 Blend
    在这里插入图片描述
  • 本节中使用的是Blend SrcFactor DstFactor来进行混合,将源颜色混合因子SrcFactor设为SrcAlpha,目标颜色混合因子设为OneMinusSrcAlpha
    • 即混合后的新颜色为
    • D s t C o l o r n e w DstColor_{new} DstColornew = SrcAlpha × SrcColor + (1-SrcAlpha) × D s t C o l o r o l d DstColor_{old} DstColorold
  • ZWrite Off 关闭深度写入
Shader "Custom/Chapter8-AlphaBlend"
{Properties{_Color ("Main Tint", Color) = (1,1,1,1)_MainTex ("Main Tex", 2D) = "white"{}_AlphaScale ("Alpha Scale", Range(0,1)) = 1}SubShader{Tags {"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent"}Pass{Tags {"LightMode" = "ForwardBase"}ZWrite OffBlend SrcAlpha OneMinusSrcAlphaCGPROGRAM#pragma vertex vert #pragma fragment frag #include "Lighting.cginc"fixed4 _Color;sampler2D _MainTex;float4 _MainTex_ST;fixed _AlphaScale;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);//透明度混合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, texColor.a * _AlphaScale);}ENDCG}}FallBack "Transparent/VertexLit"
}

在这里插入图片描述

五、开启深度写入的半透明效果

  • 对于复杂网格的半透明处理,避免错误排序
  • 方法:使用 两个Pass 来渲染模型
    • 第一个开启深度写入,但不输出颜色,仅仅为了把该模型的深度值写入深度缓存中
    • 第二个Pass 进行正常的透明度混合,根据第一个Pass,可以进行像素级别的深度排序
    • 缺点是 多个Pass会造成性能的影响
Shader "Custom/Chapter8-AlphaBlend"
{Properties{_Color ("Main Tint", Color) = (1,1,1,1)_MainTex ("Main Tex", 2D) = "white"{}_AlphaScale ("Alpha Scale", Range(0,1)) = 1}SubShader{Tags {"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent"}Pass{ZWrite On ColorMask 0}Pass{Tags {"LightMode" = "ForwardBase"}ZWrite OffBlend SrcAlpha OneMinusSrcAlphaCGPROGRAM#pragma vertex vert #pragma fragment frag #include "Lighting.cginc"fixed4 _Color;sampler2D _MainTex;float4 _MainTex_ST;fixed _AlphaScale;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);//透明度混合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, texColor.a * _AlphaScale);}ENDCG}}FallBack "Transparent/VertexLit"
}
  • 与透明度混合代码几乎一致,只是增加了一个Pass
Pass{ZWrite On ColorMask 0}
  • ZWrite On 打开深度写入,ColorMask 0 意味着Pass不写入任何颜色通道,不会输出任何颜色
    在这里插入图片描述

六、ShaderLab的混合命令

  • 混合与两个操作数有关:源颜色(SourceColor)和目标颜色(DestinationColor)
    • 源颜色指片元着色器产生的颜色 S
    • 目标颜色指从颜色缓冲中读取到的颜色值 D
    • 混合后的颜色 O
    • 包含了 RGBA四个颜色通道

1.混合等式和参数

  • 将S和D进行混合的等式——混合等式,需要两个,一个用于混合RGB,一个用于混合A
  • 设置混合状态时,即设置等式中的 “操作” 和 “因子”
    • 一共有两个等式(分别用于混合RGB和A)
    • 一个等式里有两个因子(一个与S相乘,一个与D相乘)

在这里插入图片描述

  • 第一个命令中只有两个因子——RGB和A通道用相同的两个因子
    在这里插入图片描述
    混合因子可以是哪些值呢?
    在这里插入图片描述

2.混合操作

  • 可以使用 BlendOp BlendOperation命令
    在这里插入图片描述
    在这里插入图片描述
  • 当使用Min和Max操作时,混合因子不起作用的

3.常见的混合类型(效果)

在这里插入图片描述

七、双面渲染的透明效果

  • 观察到其内部结构
  • 可以使用Cull指令来控制需要剔除哪个面的渲染图元
    • Back:背对相机的渲染图元不会被渲染
    • Front:朝向相机的渲染图元不会被渲染
    • Off:关闭剔除功能
Cull Back | Front | Off

1.透明度测试的双面渲染

  • 在Pass中使用 Cull Off 来关闭剔除功能即可
  • 只在 AlphaTest.shader 里Pass中加一句 Cull Off
    在这里插入图片描述

2.透明度混合的双面渲染

  • 因为关闭了深度写入,如果直接加 Cull Off 的话会造成前后面混乱
  • 所以,写了两个Pass (与AlphaBlend.shader一样)
    • 只在Pass中,第一个Pass只渲染背面 ,添加了Cull Front;第二个只渲染正面 添加了Cull Back
    • SubShader是会按照顺序执行Pass
      在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/864274.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全球AI新闻速递7.1

全球AI新闻速递 1.科大讯飞发布讯飞星火 V4.0。 2.成都人形机器人创新中心:基于视觉扩散架构的人形机器人任务生成式模型 R-DDPRM。 3.安徽省人形机器人产业创新中心获批,将打造国内首创、世界领先研究基地。 4.亳州牵手华为打造华佗中医药大模型。 …

[论文精读]Variational Graph Auto-Encoders

论文网址:[1611.07308] Variational Graph Auto-Encoders (arxiv.org) 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎…

DL/T 645与modbus协议是否兼容,有何关系?

不兼容。645是电表协议,modbus是通用控制协议,两个是平行关系,两个协议都可以使用485通信协议(物理接口协议)进行传输,或传输介质与物理接口相同,软件协议不同。 Modbus有以下三种通信模式 在…

ARM功耗管理软件之时钟电源树

安全之安全(security)博客目录导读 思考:功耗管理软件栈及示例?WFI&WFE?时钟&电源树?DVFS&AVS? 目录 一、时钟&电源树简介 二、时钟树示例 三、电源树示例 一、时钟&电源树简介 时钟门控与自…

Victor CMS v1.0 SQL 注入漏洞(CVE-2022-28060)

前言 CVE-2022-28060 是 Victor CMS v1.0 中的一个SQL注入漏洞。该漏洞存在于 /includes/login.php 文件中的 user_name 参数。攻击者可以通过发送特制的 SQL 语句,利用这个漏洞执行未授权的数据库操作,从而访问或修改数据库中的敏感信息。 漏洞详细信…

论文阅读_优化RAG系统的检索

英文名称: The Power of Noise: Redefining Retrieval for RAG Systems 中文名称: 噪声的力量:重新定义RAG系统的检索 链接: https://arxiv.org/pdf/2401.14887.pdf 作者: Florin Cuconasu, Giovanni Trappolini, Federico Siciliano, Simone Filice, Cesare Campag…

App测试技术(纯理论)

之前我们也学习过一些普通用例的设计, 如功能, 性能, 安全性, 兼容性, 易用性, 界面的测试用例设计, 之前我们讲的基本都是对于Web应用而言的, 这里我们来讲一下移动端的App测试用例设计. 功能方面 安装&卸载测试 这是只属于App的一类测试, 再平常我们使用移动设备(手机…

【第11章】MyBatis-Plus条件构造器(上)

文章目录 前言一、功能详解1. allEq2. eq3. ne4. gt5. ge6. lt7. le8. between9. notBetween10. like11. notLike12. likeLeft13. likeRight14. notLikeLeft15. notLikeRight16. isNull17. in18. notIn19. inSql20. notInSql21. eqSqlSince 3.5.622. gtSql Since 3.4.3.223. ge…

Linux4(Docker)

目录 一、Docker介绍 二、Docker结构 三、Docker安装 四、Docker 镜像 五、Docker 容器 六、Docker 安装nginx 七、Docker 中的MySQL部署 一、Docker介绍 Docker:是给予Go语言实现的开源项目。 Docker的主要目标是“Build,Ship and Run Any App,Anywhere” 也…

类和对象【上】【C++】

P. S.:以下代码均在VS2019环境下测试,不代表所有编译器均可通过。 P. S.:测试代码均未展示头文件stdio.h的声明,使用时请自行添加。 博主主页:LiUEEEEE                        …

依托天拓四方工业智能网关实现CNC数控机床的远程运维

随着工业4.0时代的到来,智能制造和工业互联网成为了推动制造业转型升级的重要力量。CNC数控机床作为制造业的核心设备,其运行效率与稳定性直接关系到企业的生产效益。因此,实现CNC数控机床的远程运维,对于提升企业竞争力、降低运营…

安装 Docker 环境(通过云平台创建一个实例实现)

目录 1. 删除原有 yum 2. 手动配置 yum 源 3. 删除防火墙规则 4. 保存防火墙配置 5. 修改系统内核。打开内核转发功能。 6. 安装 Docker 7. 设置本地镜像仓库 8.重启服务 1. 删除原有 yum rm -rfv /etc/yum.repos.d/* 2. 手动配置 yum 源 使用 centos7-1511.iso 和 Xi…

Java [ 基础 ] 方法引用 ✨

✨探索Java基础✨ Java基础:方法引用 方法引用是Java 8中引入的一种新特性,它使得代码更加简洁和易读。方法引用提供了一种可以直接引用已有方法作为Lambda表达式的替代方案。本文将深入介绍方法引用的基本概念、使用方法、具体实例及其在实际开发中的…

【深入浅出 】——【Python 字典】——【详解】

目录 1. 什么是 Python 字典? 1.1 字典的基本概念 1.2 字典的用途 1.3 字典的优势 2. 字典的基本特点 2.1 键的唯一性 2.2 可变性 2.3 无序性 3. 如何创建字典? 3.1 使用 {} 符号 3.2 使用 dict() 工厂方法 3.3 使用 fromkeys() 方法 4. 字…

[工业网络][2] 安全背景知识

安全背景知识 物理、网络和人员安全 在考虑企业和工业的安全性时,安全从业人员传统上将自己划分为三个专业领域。我们借助于安全中经常使用的两个术语来描述这三个领域 业内人士。属于您的设施的人员,包括员工和受邀承包商,访客或交付和服…

K8s的基本使用和认识

目录 介绍 控制端 Node(节点) 控制端与节点的关系图 基本使用 创建和运行资源 查找和参看资源 修改和删除资源 介绍 控制端 api-server(api)是集群的核心是k8s中最重要的组件,因为它是实现声明式api的关键 kubernetes api-server的核心功能是提供了Kubernetes各类资…

应用监控SkyWalking调研

参考: 链路追踪( Skyworking )_skywalking-CSDN博客 企业级监控项目Skywalking详细介绍,来看看呀-CSDN博客 SkyWalking 极简入门 | Apache SkyWalking 使用 SkyWalking 监控 ClickHouse Server | Apache SkyWalking https://zhuanlan.zhihu.com/p/3…

Linux应急响应靶机 2

一、靶机介绍 应急响应靶机-Linux2 前景需要:看监控的时候发现webshell告警,领导让你上机检查你可以救救安服仔吗!! 1,提交攻击者IP 2,提交攻击者修改的管理员密码(明文) 3,提交第一次Webshell的连接URL(http://xxx.xxx.xxx.…

【每日刷题】Day78

【每日刷题】Day78 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 1608. 特殊数组的特征值 - 力扣(LeetCode) 2. 1385. 两个数组间的距离值 - …

R可视化:好看的气泡图

加载R包 library(tidyverse) library(camcorder)gg_record(dir "tidytuesday-temp", device "png", width 8, height 8, units "in", dpi 320)导入数据 team_results <- readr::read_csv(https://raw.githubusercontent.com/rfordata…