【UnityShader入门精要学习笔记】第十五章 使用噪声
本系列为作者学习UnityShader入门精要而作的笔记,内容将包括:
- 书本中句子照抄 + 个人批注
- 项目源码
- 一堆新手会犯的错误
- 潜在的太监断更,有始无终
我的GitHub仓库
总之适用于同样开始学习Shader的同学们进行有取舍的参考。
文章目录
- 使用噪声
- 上节补充:smoothstep
- 消融效果
- 水波效果
- 全局雾效
使用噪声
在有些时候,向规则的事物里面添加一些杂乱无章的效果,往往会有奇效。而这些杂乱无章的效果的来源就是噪声。在本章中我们将学习如何使用噪声来模拟一些特效。
上节补充:smoothstep
这篇文章很好的描述了smoothstep实现了什么样的效果。实际实现了对一个圆形范围的边缘模糊Shader实验室: smoothstep函数
消融效果
消融效果往往使用在角色死亡,地图烧毁等现象上。消融的效果往往是从不同区域开始,然后往看似随机的方向扩散,最后整个物体消失不见。
Shader
Shader "Custom/Dissolve_Copy"
{Properties{_BurnAmount ("Burn Amount", Range(0.0, 1.0)) = 0.0// _LineWidth代表了周边延申的效果线_LineWidth("Burn Line Width", Range(0.0, 10)) = 0.1_MainTex ("Base (RGB)", 2D) = "white" {}_BumpMap ("Normal Map", 2D) = "bump" {}_BurnFirstColor("Burn First Color", Color) = (1, 0, 0, 1)_BurnSecondColor("Burn Second Color", Color) = (1, 0, 0, 1)_BurnMap("Burn Map", 2D) = "white"{}}SubShader{Tags { "RenderType"="Opaque" "Queue"="Geometry"}Pass {Tags { "LightMode"="ForwardBase" }// 不要剔除背面,不然裁剪面片时会发现没有背面Cull OffCGPROGRAM#include "Lighting.cginc"#include "AutoLight.cginc"#pragma multi_compile_fwdbase#pragma vertex vert#pragma fragment fragfixed _BurnAmount;fixed _LineWidth;sampler2D _MainTex;sampler2D _BumpMap;fixed4 _BurnFirstColor;fixed4 _BurnSecondColor;sampler2D _BurnMap;float4 _MainTex_ST;float4 _BumpMap_ST;float4 _BurnMap_ST;struct a2v {float4 vertex : POSITION;float3 normal : NORMAL;float4 tangent : TANGENT;float4 texcoord : TEXCOORD0;};struct v2f {float4 pos : SV_POSITION;float2 uvMainTex : TEXCOORD0;float2 uvBumpMap : TEXCOORD1;float2 uvBurnMap : TEXCOORD2;float3 lightDir : TEXCOORD3;float3 worldPos : TEXCOORD4;SHADOW_COORDS(5)};v2f vert(a2v v) {v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.uvMainTex = TRANSFORM_TEX(v.texcoord, _MainTex);o.uvBumpMap = TRANSFORM_TEX(v.texcoord, _BumpMap);o.uvBurnMap = TRANSFORM_TEX(v.texcoord, _BurnMap);TANGENT_SPACE_ROTATION;o.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex)).xyz;o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;TRANSFER_SHADOW(o);return o;}fixed4 frag(v2f i) : SV_Target {// 对噪声纹理进行采样fixed3 burn = tex2D(_BurnMap, i.uvBurnMap).rgb;// 根据_BurnAmount来clip像素,保留白色去除黑色clip(burn.r - _BurnAmount);float3 tangentLightDir = normalize(i.lightDir);fixed3 tangentNormal = UnpackNormal(tex2D(_BumpMap, i.uvBumpMap));fixed3 albedo = tex2D(_MainTex, i.uvMainTex).rgb;fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(tangentNormal, tangentLightDir));// 对裁剪掉的部分进行混合颜色渲染fixed t = 1 - smoothstep(0.0, _LineWidth, burn.r - _BurnAmount);// 这一部分渲染的颜色是根据smoothstep获取的形状渲染的,// 被裁剪部分=0,因此经过smoothstep后周边模糊区域会保留,中心区域裁剪,渲染范围是裁剪部分区域 + _LineWidth// 而越靠近裁剪部分的像素渲染越接近firstColorfixed3 burnColor = lerp(_BurnFirstColor, _BurnSecondColor, t);// 深化颜色,看起来亮一点burnColor = pow(burnColor, 5);UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);// 最终再混合光照和燃烧特效色fixed3 finalColor = lerp(ambient + diffuse * atten, burnColor, t * step(0.0001, _BurnAmount));return fixed4(finalColor, 1);}ENDCG}// Pass to render object as a shadow casterPass {Tags { "LightMode" = "ShadowCaster" }CGPROGRAM#pragma vertex vert#pragma fragment frag#pragma multi_compile_shadowcaster#include "UnityCG.cginc"fixed _BurnAmount;sampler2D _BurnMap;float4 _BurnMap_ST;struct v2f {V2F_SHADOW_CASTER;float2 uvBurnMap : TEXCOORD1;};v2f vert(appdata_base v) {v2f o;TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)o.uvBurnMap = TRANSFORM_TEX(v.texcoord, _BurnMap);return o;}fixed4 frag(v2f i) : SV_Target {fixed3 burn = tex2D(_BurnMap, i.uvBurnMap).rgb;// 对阴影也需要剔除clip(burn.r - _BurnAmount);SHADOW_CASTER_FRAGMENT(i)}ENDCG}}FallBack "Diffuse"
}
例如火焰焚毁效果
发现配合不同的噪声贴图可以实现很多有意思的效果,例如扫描线重建
或者这样的沙化效果,总而言之只要是类似的随时间渐变效果应当都是能够使用噪声贴图实现的,只是需要充分发挥想象力
水波效果
在模拟实时水面的时候,我们往往也会使用噪声纹理作为高度图,不断修改水面的法线方向,以模拟水不断流动的效果。我们会使用和时间相关的变量来对噪声纹理进行采样,当得到法线信息后再进行正常的反射 + 折射运算,得到最终的水面波动效果
在之前我们写过一个实现了菲涅尔反射的玻璃效果,现在我们想要实现水波,自然也要使用菲涅尔反射,此外为了实现水面的波动效果,我们可以用一张噪声贴图,并不断进行偏移采样来模拟水面的随机波动。以实现波光粼粼的效果。
Shader "Custom/WaterWave_Copy"
{Properties{_Color ("Main Color", Color) = (1,1,1,1)_MainTex ("Base Tex", 2D) = "white" {}_WaveMap ("Wave Map",2D) = "bump"{}_Cubemap ("Environment Cubemap", Cube) = "_Skybox" {}_WaveXSpeed ("Wave Horizontal Speed", Range(-0.1, 0.1)) = 0.01_WaveYSpeed ("Wave Vertical Speed", Range(-0.1, 0.1)) = 0.01_Distortion ("Distortion", Range(0, 100)) = 10}SubShader{Tags { "Queue"="Transparent" "RenderType"="Opaque" }// 抓取不透明物体渲染后的缓存,并保存到_RefractionTex纹理中// 此处GrabPass在渲染水面纹理之前,因此抓取的是未渲染水面时的场景画面GrabPass { "_RefractionTex" }Pass{Tags{ "LightMode"="ForwardBase" }CGPROGRAM#include "UnityCG.cginc"#include "Lighting.cginc"#pragma multi_compile_fwdbase#pragma vertex vert#pragma fragment fragfixed4 _Color;sampler2D _MainTex;float4 _MainTex_ST;sampler2D _WaveMap;float4 _WaveMap_ST;samplerCUBE _Cubemap;fixed _WaveXSpeed;fixed _WaveYSpeed;float _Distortion; sampler2D _RefractionTex;float4 _RefractionTex_TexelSize;struct a2v {float4 vertex : POSITION;float3 normal : NORMAL;float4 tangent : TANGENT; float4 texcoord : TEXCOORD0;};struct v2f {float4 pos : SV_POSITION;float4 scrPos : TEXCOORD0;float4 uv : TEXCOORD1;float4 TtoW0 : TEXCOORD2; float4 TtoW1 : TEXCOORD3; float4 TtoW2 : TEXCOORD4; };v2f vert(a2v v) {v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.scrPos = ComputeGrabScreenPos(o.pos);o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex);o.uv.zw = TRANSFORM_TEX(v.texcoord, _WaveMap);// 用于计算光照模型(菲涅尔反射)。需要用到世界空间下的切线方向float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; fixed3 worldNormal = UnityObjectToWorldNormal(v.normal); fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz); fixed3 worldBinormal = cross(worldNormal, worldTangent) * v.tangent.w; o.TtoW0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x); o.TtoW1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y); o.TtoW2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z); return o;}fixed4 frag(v2f i) : SV_Target {float3 worldPos = float3(i.TtoW0.w, i.TtoW1.w, i.TtoW2.w);fixed3 viewDir = normalize(UnityWorldSpaceViewDir(worldPos));// 计算水波纹理在uv上的采样速度float2 speed = _Time.y * float2(_WaveXSpeed, _WaveYSpeed);// 对法线纹理采样并将法线纹理转换回切线空间// 此处为了模拟水波的不规则运动,bump1边对speed正方向采样,bump2对负方向采样,并将两种法线纹理采样都应用上去fixed3 bump1 = UnpackNormal(tex2D(_WaveMap, i.uv.zw + speed)).rgb;fixed3 bump2 = UnpackNormal(tex2D(_WaveMap, i.uv.zw - speed)).rgb;fixed3 bump = normalize(bump1 + bump2);// 将场景的像素与法线进行混合以实现水面波动和场景画面的颜色值的混合// _Distortion越大,水体背后的物体看起来变形程度越大float2 offset = bump.xy * _Distortion * _RefractionTex_TexelSize.xy;// 对z坐标进行相乘,以模拟深度越大,折射程度越大的效果i.scrPos.xy = offset * i.scrPos.z + i.scrPos.xy;fixed3 refrCol = tex2D( _RefractionTex, i.scrPos.xy/i.scrPos.w).rgb;// 将采样法线贴图计算的切线空间坐标变换到世界空间下bump = normalize(half3(dot(i.TtoW0.xyz, bump), dot(i.TtoW1.xyz, bump), dot(i.TtoW2.xyz, bump)));// 采样主纹理并计算菲涅尔反射fixed4 texColor = tex2D(_MainTex, i.uv.xy + speed);fixed3 reflDir = reflect(-viewDir, bump);fixed3 reflCol = texCUBE(_Cubemap, reflDir).rgb * texColor.rgb * _Color.rgb;fixed fresnel = pow(1 - saturate(dot(viewDir, bump)), 4);fixed3 finalColor = lerp(refrCol,reflCol,fresnel);//fixed3 finalColor = reflCol * fresnel + refrCol * (1 - fresnel);return fixed4(finalColor, 1);}ENDCG}}// 不投射阴影FallBack Off
}
全局雾效
从代码上看来其实就是对原来的雾效后处理进行了一个噪声纹理贴图的采样。
此处就不展开了
相关文章:

【UnityShader入门精要学习笔记】第十五章 使用噪声
本系列为作者学习UnityShader入门精要而作的笔记,内容将包括: 书本中句子照抄 个人批注项目源码一堆新手会犯的错误潜在的太监断更,有始无终 我的GitHub仓库 总之适用于同样开始学习Shader的同学们进行有取舍的参考。 文章目录 使用噪声上…...
C++ ─── string的完整模拟实现
本博客实现了string的常见接口实现 下面是用到的一些函数,供大家回顾复习 string.h #define _CRT_SECURE_NO_WARNINGS 1 #pragma once #include<iostream> #include<assert.h> using namespace std;namespace bit {class string{public:typedef char*…...
安卓中的图片压缩
安卓中如何进行图片压缩? 在安卓中进行图片压缩通常有以下几种方法: 质量压缩: 通过降低图片的质量来减小文件大小。这可以通过Bitmap的compress()方法实现,其中可以设置压缩质量(0-100)。 ByteArrayOutputStream baos…...
centOS7.9 DNS配置
1.DNS规划 dns.sohu.com192.168.110.111Awww.sohucom192.168.110.112Aoa.sohu.com 192.168.110.113A 2.安装 bind yum install -y bind bind-utils 3. 编辑主配置文件 vim /etc/named.conflisten- on port 53 { any; }; allow- query { any; }; 4.配置区域文件 …...

设计模式20——职责链模式
写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用,主要是下面的UML图可以起到大作用,在你学习过一遍以后可能会遗忘,忘记了不要紧,只要看一眼UML图就能想起来了。同时也请大家多多指教。 职责链模式(Chain …...
android13 差分包制作命令
./out/host/linux-x86/bin/ota_from_target_files -v -iCode/SourceCode/android13/ntls/userdebug/hpg2_24-target_files-38.zip --block -p ./out/host/linux-x86 Code/SourceCode/android13/ntls/userdebug/hpg2_24-target_files-39.zip update_ud.zip 脚本命令行参数 命令…...

Flink-cdc更好的流式数据集成工具
What’s Flink-cdc? Flink CDC 是基于Apache Flink的一种数据变更捕获技术,用于从数据源(如数据库)中捕获和处理数据的变更事件。CDC技术允许实时地捕获数据库中的增、删、改操作,将这些变更事件转化为流式数据,并能够…...
C++|设计模式(三)|抽象工厂模式
抽象工厂模式仍然属于创建型模式,我们在【简单工厂和工厂方法模式】这篇文章中,描述了简单工厂和工厂方法模式,并在文末,简单介绍了工厂方法模式的局限性。 本文将通过汽车工厂的例子继续来阐述使用抽象工厂模式相比较于工厂方法…...

AVB协议分析(一) FQTSS协议介绍
FQTSS协议介绍 一、AVB整体架构二、概述三、协议作用及作用对象四、协议的实现五、参考文献: 一、AVB整体架构 可见FQTSS位于MAC层的上面,代码看不懂,咱们就从最底层开始,逐层分析协议,逐个击破,慢就是快。…...
一个程序员的牢狱生涯(44)询问
星期一 询 问 在号子里开始了下午坐班的时候,过道内的大铁栅栏被管教打开,我听到开锁的声音后,心里变得激动起来。盼望着脚步声能停在我们的号子门口,然后打开铁门,喊一声“眼镜,出来!”。 通道内这次进来的是秦所,但他并没有在我们号子门口停留,只是在走过的时候,低…...

刷爆leetcode第六期
题目一 用队列实现栈 请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。 实现 MyStack 类: void push(int x) 将元素 x 压入栈顶。 int pop() 移除…...

汇舟问卷:国外问卷调一天900
大家好,我是汇舟问卷,专注于国外问卷调查互联网项目。夏天已经来临,您是否在三伏天顶着大太阳上班,汗水浸湿了衣襟,却依然要面对繁琐的工作和无尽的压力? 在这个炎热的季节里,我们都渴望找到一…...
openresty完美替代nginx
OpenResty相较于Nginx,其优势主要体现在以下几个方面: 1、Lua脚本支持:OpenResty内置了LuaJIT(Lua的即时编译器),使得用户可以直接在Nginx配置文件中使用Lua脚本,这样可以实现更复杂的业务逻辑…...
深入解析:Element Plus 与 Vite、Nuxt、Laravel 的结合使用
在现代前端开发中,选择合适的工具和框架来提高开发效率和应用性能是至关重要的。 Element-Plus 是一个基于 Vue.js 3.0 的流行 UI组件库,它可以与多种前端和后端框架结合使用,如 Vite、Nuxt 和 Laravel。本文将深入探讨这三者与 Element Plus…...
使ssh连接Linux服务器一直不掉线
怎么可以使ssh连接Linux服务器一直不掉线 解决方法: vim /etc/profile在/etc/profile中的TMOUT改为0 export TMOUT0最后 source /etc/profile就可以了...

2024-05-29 blue-VH-driver-对外接口的并行调用-设计与思考
摘要: VH的driver的对外接口, 要做到可以并行,也就是两个不同的线程,分别调用,不能互相阻塞。 本文记录对其的思考和设计。 上下文: 2024-05-28 blue-VH-driver-需求分析及问题分析-CSDN博客 2024-05-27 blue-vh-问题点-CSDN博客 2024-05…...

ubuntu安装
1.下载镜像文件 2.打开VMware并新建虚拟机 版本选择Ubuntu 64位 磁盘容量改为40GB 点击自定义硬件,点击新CD/DVD(SATA),连接选择ISO映像文件,找到之前下载的Ubuntu镜像文件,然后关闭选项卡。 3.开启虚拟机…...
Rosetta PyRosetta 源码包 安装包 下载
--- pyrosetta_src.zip包含以下包: | --- PyRosetta4.Debug.python27.ubuntu.release-185.tar.bz2 | --- PyRosetta4.Release.python27.linux.release-215.tar.bz2 | --- PyRosetta4.Release.python38.ubuntu.release-349.tar.bz2 --- pyrosetta_whl.zip包含…...

C++ 进阶(3)虚函数表解析
个人主页:仍有未知等待探索-CSDN博客 专题分栏:C 请多多指教! 目录 一、虚函数表 二、单继承(无虚函数覆盖) 继承关系表: 对于实例:derive d 的虚函数表: 对于实例:b…...

2024年新算法-秘书鸟优化算法(SBOA)优化BP神经网络回归预测
2024年新算法-秘书鸟优化算法(SBOA)优化BP神经网络回归预测 亮点: 输出多个评价指标:R2,RMSE,MSE,MAPE和MAE 满足需求,分开运行和对比的都有对应的主函数:main_BP, main_SBOA, main_BPvsBP_SB…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践
前言:本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中,跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南,你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案,并结合内网…...

rm视觉学习1-自瞄部分
首先先感谢中南大学的开源,提供了很全面的思路,减少了很多基础性的开发研究 我看的阅读的是中南大学FYT战队开源视觉代码 链接:https://github.com/CSU-FYT-Vision/FYT2024_vision.git 1.框架: 代码框架结构:readme有…...
Three.js进阶之粒子系统(一)
一些特定模糊现象,经常使用粒子系统模拟,如火焰、爆炸等。Three.js提供了多种粒子系统,下面介绍粒子系统 一、Sprite粒子系统 使用场景:下雨、下雪、烟花 ce使用代码: var materialnew THRESS.SpriteMaterial();//…...

MQTT协议:物联网时代的通信基石
MQTT协议:物联网时代的通信基石 在当今快速发展的物联网(IoT)时代,设备之间的通信变得尤为重要。MQTT(Message Queuing Telemetry Transport)协议作为一种轻量级的消息传输协议,正逐渐成为物联…...
Fetch API 使用详解:Bearer Token 与 localStorage 实践
Fetch API:现代浏览器内置的用于发送 HTTP 请求的 API,Bearer Token:一种基于令牌的身份验证方案,常用于 JWT 认证,localStorage:浏览器提供的持久化存储方案,用于在客户端存储数据。 token是我…...