【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
}

在这里插入图片描述

全局雾效

从代码上看来其实就是对原来的雾效后处理进行了一个噪声纹理贴图的采样。

此处就不展开了


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

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

相关文章

亮相CCIG2024,合合信息文档解析技术破解大模型语料“饥荒”难题

近日,2024中国图象图形大会在古都西安盛大开幕。本届大会由中国图象图形学学会主办,空军军医大学、西安交通大学、西北工业大学承办,通过二十多场论坛、百余项成果,集中展示了生成式人工智能、大模型、机器学习、类脑计算等多个图…

Compose第一弹 可组合函数+Text

目标: 1.Compose是什么?有什么特征? 2.Compose的文本控件 一、Compose是什么? Jetpack Compose 是用于构建原生 Android 界面的新工具包。 Compose特征: 1)声明式UI:使用声明性的函数构建一…

opencascade 快速显示AIS_ConnectedInteractive源码学习

AIS_ConcentricRelation typedef PrsDim_ConcentricRelation AIS_ConcentricRelation AIS_ConnectedInteractive 简介 创建一个任意位置的另一个交互对象实例作为参考。这允许您使用连接的交互对象,而无需重新计算其表示、选择或图形结构。这些属性是从您的参考对…

蓝桥杯嵌入式国赛笔记(4):多路AD采集

1、前言 蓝桥杯的国赛会遇到多路AD采集的情况,这时候之前的单路采集的方式就不可用了,下面介绍两种多路采集的方式。 以第13届国赛为例 2、方法一(配置通道) 2.1 使用CubeMx配置 设置IN13与IN17为Single-ended 在Parameter S…

今日好料推荐(大数据湖体系规划)

今日好料推荐(大数据湖体系规划) 参考资料在文末获取,关注我,获取优质资源。 大数据湖体系规划 一、大数据湖简介 大数据湖(Data Lake)是一个集中式的存储库,用于存储来自各种来源的结构化和…

蓝桥杯杨辉三角

PREV-282 杨辉三角形【第十二届】【蓝桥杯省赛】【B组】 (二分查找 递推): 解析: 1.杨辉三角具有对称性: 2.杨辉三角具有一定规律 通过观察发现,第一次出现的地方一定在左部靠右的位置,所以从…

快速下载极客时间课程

仅供学习,切勿商用 1. 下载 下载geektime-downloader,安装到指定文件夹,注意路径尽量不要出现汉字 不想去github上下载的可以直接下载文章顶部的软件安装包。 2. 执行命令 在安装geektime-downloader目录下,点击鼠标右键&…

Spring和Servlet的整合

Servlet对象是谁创建的? 由服务器端创建的 程序启动调用加载spring配置文件代码 Web应用程序启动也需要加载Spring配置文件 Web开发中有三大组件: 1、servlet 2、filter 3、listener(request,session,application&…

在docker中运行SLAM十四讲程序

《十四讲》的示例程序依赖比较多,而且系统有点旧。可以在容器中运行。 拉取镜像 docker pull ddhogan/slambook:v0.1这个docker对应的github:HomeLH/slambook2-docker 拉下来之后,假如是Windows系统,需要使用XLaunch用于提供X11…

无人机操作界面来了,起点就很高呀。

无人机操作界面设计需要考虑以下几个方面: 易用性:无人机操作界面应该简单直观,易于操作和理解。操作按钮和控键应该布局合理,易于触摸或点击。重要的操作功能应该易于找到和使用,避免用户迷失或困惑。实时反馈&#…

jupyter notebook更改位置

1.找到jupyer的配置文件 一般在c盘用户的.jupter文件夹下 2. 用记事本打开这个配置文件,定位到c.NotebookApp.notebook_dir /path_to_your_directory 替换你的位置 3.找到jupyer图标的位置,打开属性 添加要存放的位置在目标文件的末尾,重新…

9.3 Go语言入门(变量声明和函数调用)

Go语言入门(变量声明和函数调用) 目录二、变量声明和函数调用1. 变量声明1.1 使用 var 关键字声明1.2 简短声明1.3 零值1.4 常量 2. 函数调用2.1 函数定义2.2 多个返回值2.3 命名返回值2.4 可变参数2.5 匿名函数和闭包 目录 Go 语言(Golang&a…

Unity射击游戏开发教程:(28)敌人被摧毁时掉落的能量提升

在这篇文章中,我将介绍如何在敌人被摧毁时产生能量提升。 首先,有一个生成管理器,负责生成敌人和能量提升。我正在对其进行转换,以便当敌人被摧毁时,有可能会掉落能量。本文将仅介绍当敌人被摧毁时掉落的能量道具。我将介绍为电源添加一个平衡的生成系统。 Spawn Manager…

XXE漏洞详解——进阶篇

读取文件时有特殊符号 在读取文件时&#xff0c;文件中包含"<,>,&"等这些特殊符号时&#xff0c;会被xml解析器解析&#xff0c;报错从而导致读取失败&#xff0c;例如尝试读取以下文件 C:\test.txt 内容&#xff1a; <Baize Sec> payload: <…

内网安全--隧道技术-MSF上线本地

免责声明:本文仅做技术交流与学习... 不得不说,小白最近也是用上了viper,这里要特别感谢一下my bro 北岭敲键盘的荒漠猫 MSF--viper: --生成马子-->上线 --进入meterpreter. 1-查看路由,添加路由. 查看路由信息 : run autoroute -p run post/multi/manage/autoroute 添加…

登峰造极,北斗相伴——纪念人类首次登顶珠穆朗玛峰71周年

71年前的今天&#xff0c;1953年5月29日11时30分&#xff0c;人类实现了一个伟大的壮举&#xff1a;首次登上了珠穆朗玛峰&#xff0c;这座海拔8848.86米的世界最高峰。这是一次充满了艰辛、勇气和智慧的探险&#xff0c;也是一次改变了人类历史和文化的探险。 自那以后&#…

Java集合—TreeSet和TreeMap

一、TreeSet 1.当使用无参构造器&#xff0c;创建TreeSet时&#xff0c;仍然是无序的。 2.若希望添加的元素有序&#xff0c;需要使用TreeSet提供的构造器,传入一个比较器。 该比较器是一个接口&#xff0c;里面有一个方法叫compare()&#xff0c;传入一个实现该接口的类(匿名内…

Linux文件管理

Linux系统中&#xff0c;文件以树状图形式存储&#xff0c;即单根文件系统&#xff0c;以用户为分支分别存储文件。 文件操作 相对路径表示方法&#xff0c;.当前目录&#xff0c;..上层目录&#xff0c;~家目录&#xff0c;也可以使用绝对路径/的表示方法&#xff0c;其他常…

面试问到Spring中的@Autowired注解,可以这样答

前言 在Spring框架中&#xff0c;依赖注入是一个核心概念&#xff0c;它允许将一个对象的依赖关系外部化并由Spring容器来管理。Autowired注解是实现这一点的关键工具之一。当然&#xff0c;这块知识也是面试官们老生常谈的问题。 下面就跟着博主的步伐&#xff0c;一起来探讨…

动手学深度学习24 AlexNet

动手学深度学习24 AlexNet 1. AlexNet传统机器学习AlexNet 2. 代码3. QA 1. AlexNet 传统机器学习 AlexNet AlexNet & LeNet对比 加了三层隐藏层&#xff0c;通道数和全连接层单元数更多 计算需要的浮点数&#xff0c;10亿次浮点数计算。 2. 代码 import torch fro…