当前位置: 首页 > news >正文

【程序化天空盒】过程记录01:日月 天空渐变 大气散射

1 日月 SunAndMoon

昼夜的话肯定少不了太阳和月亮,太阳和月亮实现的道理是一样的,只不过是月亮比太阳多了一个需要控制月牙程度(or添加贴图)的细节~

1.1 Sun

太阳的话很简单,直接在shader里实现一个太阳跟随平行光旋转而旋转的样子就行。实现这个效果需要用到Unity内置变量_WorldSpaceLightPos0获取当前平行光的方向,不要被这个参数名字“lightPos”迷惑了,它实际上就是一个归一化的vector(w=0)。接着用Unity内置的distance函数计算当前uv坐标(i.uv.xyz)到上面那个的距离。

如何理解这个“距离”呢?——我们再来复习一遍图形学基础吧:学习齐次坐标时讲到“点与向量的区别”时,例如vector(a, b, c, 0)和point(a, b, c, 1),我们可以把vector看作这个point挪向无穷远处位置。行,那么我们再来看看这个distance计算出来的结果的几何意义是不是就十分简单了——uv坐标越靠近,代表离这个无穷远处的点越近,于是结果越小。

  • 我们需要的是一个实心圆(模拟“日月”),如果只将distance的结果与_SunColor相乘并作为片元着色器的结果输出,主要代码及效果如下:
float sun = distance(i.uv.xyz, _WorldSpaceLightPos0);
...
fixed4 col = sun * _SunColor;

  • 场景中越靠近远处的“太阳”位置越黑,想要实现一个实心圆就很简单了,补充后代码及效果如下:
float sun = distance(i.uv.xyz, _WorldSpaceLightPos0);
float sunDis = 1 - sun / _sunRadius;
...
fixed4 col = sunDis * _SunColor;

 为了实现控制最大化,加入了_sunRadius参数以控制“太阳”的大小,选择除法的原因也很简单——太阳越大意味着白色部分越大,意味着disatance()函数计算结果的权重更加分散,所以是除法。

  • 到了这一步你会发现,上图还是缺点什么!

【第一】边界有些模糊,我们想实现的效果是轮廓明显的“日月”,这是因为边界的sunDis数值不够大,导致_sunColor相乘混合的颜色“淡”。如何处理?——简单,直接乘上个合适的倍数就行!

【第二】原有的网格不见了,给人一种黑色“笼罩”整个天空盒的错觉。看到这里你似乎会觉得疑惑:“网格不见了”啥意思?我来举个例子,下面是我将sunDis值分别设置为1,0,-1的效果:

2和3看似都是黑色,其实还是有差别的,他会掩盖网格。而且这个sunDis系数最后是跟类型为Color的_SunColor变量相乘,参考光照计算模型,这里理应将该系数也限制在(0, 1),这里用saturate()就行!

考虑了以上两点后最终的代码:

float sun = distance(i.uv.xyz, _WorldSpaceLightPos0);
float sunDis = saturate((1 - sun / _sunRadius) * 50);
...
fixed4 col = sunDis * _SunColor;

最终效果:

1.2 Moon 

太阳做完了,到了月亮部分,它俩一个在光的正方向(太阳)一个在反方向(月亮),这个不难理解吧!所以,关于跟随平行光方向的部分,设置跟Sun一样,只是多了一个负号。

这里我计划实现两种月亮的方法,一种是贴上一个真实的月亮图片,另一个是做一个简单的可以控制的月牙形状。

第一种:月牙

另外,由于月亮是有月牙的~就用两个圆相减的形式做出月牙的效果,相减效果采用给uv.x一个偏移值_CrescentOffset的方法实现的。同样,这里也需要注意只要涉及相减的需要给数值规范到(0, 1)才能确保效果的正确。

下面是月亮部分的代码:

//2.Add Moon
float moon = distance(i.uv.xyz, -_WorldSpaceLightPos0);
float moonDis = saturate((1 - moon / _MoonRadius) * 50);
float crescent = distance(float3(i.uv.x + _CrescentOffset, i.uv.yz), -_WorldSpaceLightPos0);
float crescentDis = saturate((1 - crescent / _MoonRadius) * 50);
moonDis = saturate(moonDis - crescentDis);
fixed4 moonN = moonDis * _MoonColor;

最终效果:

第二种:月亮贴图

贴图主要问题是解决UV坐标系变换问题,因为如果继续用原始的改变光照方向后月亮贴图会变形的问题,我们希望每个角度贴图形状都是圆圆的(参考日常生活中每个角度的月亮都是圆圆的),那么我们就需要一个建立一个4x4的坐标系变换矩阵去实现。

问题又来了:Unity自带的变换矩阵unity_WorldToLight对于平行光是行不通的,只适用于point/spot/烘焙光,所以这里我们需要自己脚本实现变换矩阵。这里我们不难想到shadowmap里也需要求得光源空间的变换矩阵,可以参考我记录的GAMES202作业1中CalcLightMVP()的实现过程去写出这个变换矩阵,还可以跟着这一篇用Unity实现Shadow Map的博客实现这个变换矩阵,道理都是相通的。

更方便的还可以用Unity自带的transform的worldToLocalMatrix获得当前对象的世界空间到local空间的变换矩阵,给场景中的平行光一个子Camera再获取一下这个变换矩阵就行(后面会补充完整脚本内容和shader部分的内容,这里就先放一个效果)。

效果如下,加上了一点后面会做的渐变天空效果:

2 天空主体色 Gradient Sky

1.0版本

完成了日月交替的部分只能说才实现了一小部分,而且天空很单调,为了实现更加酷炫的效果,加点渐变天空颜色。说起渐变,要用上lerp()了!分别给白天天空和晚上天空赋予颜色——基于UV坐标的y 轴值来做天空颜色的渐变,记住还是需要saturate()!最后根据uv坐标(i.uv.y)判断何时昼夜交替。

// 3.gradient sky
fixed3 gradientDay = lerp(_DayBottomColor, _DayTopColor, saturate(i.uv.y));
fixed3 gradientNight = lerp(_NightBottomColor, _NightTopColor, saturate(i.uv.y));
fixed3 gradientSky = lerp(gradientNight, gradientDay, saturate(_WorldSpaceLightPos0.y));

2.0版本

上面的渐变天空简单的lerp做的,很枯燥。参考程序化天空盒实现昼夜变换,我们也来这位大佬的构思思路,做一次分析(毕竟是作品集,所有过程自己实现一遍最好啦!),也天空变化归纳了出来:

参考他提出的思路,地平线渐变用worldPos.y控制,但天空的主体颜色用光方的z和y共同控制,关于天空主体色我的理解:

(纠正一下,感觉早晨不是supper blue而是一种偏绿色的蓝色?颜色可以自行调整的)

即从早晨开始,早晨(非常蓝)-->中午(正常蓝)-->傍晚(紫色)-->深夜(深蓝色),其中,y控制着白天和晚上,z控制白天三种颜色变换、晚上三种颜色交替

白天:

上述思路对应的理解代码为,

// 早午过渡
col = lerp(morningCol, noonCol, smoothstep(0,0.5,z));
// 再把上面的当作午的,进行午傍晚过渡
lerp(col, nightfallCol, smoothstep(0.5,1,z));

同理晚上:

// 早晚过渡
col = lerp(morningCol, nightCol, smoothstep(0,0.5,z));
// 再把上面的当作晚的,进行晚和傍晚的过渡
lerp(col, nightfallCol, smoothstep(0.5,1,z));

再优化一下:我想要清晨和傍晚的颜色持续的少一点,白天的天蓝色维持的久一点,这样就需要更改参数,索性直接多给两个参数,来调节一天内清晨和傍晚的持续时间,最终关于天空颜色早晚变化的参数如下:

3 地平线渐变

跟参考文章不太一样的是,我把渐变天空分为两个部分:半天空渐变色+范围变化的Bloom,虽然这样比较麻烦(叠加了三层orz),但原神有些画面它就是三种颜色叠加的效果,例如下图傍晚的天空:

原神的傍晚天空

索性直接拆成三块做。 

3.1 半天空渐变

半天空渐变色有4种颜色,4个颜色变化的时间刚好跟天空主题渐变色对应,

1 晚上:深蓝色+淡色地平线

早晨:浅蓝色+淡色地平线

中午:天蓝色+浅蓝地平线

傍晚:紫色+淡黄色地平线

由于这个是跟主色叠加,是不是应该在天空主体渐变的基础上修改,达到天空主色渐变的感觉:

好,说做就做,以早晨为例,还需要能控制渐变程度等,最后的参数如下:

整个天空颜色很接近了(斗胆),现在就差地平线附近的Bloom。

3.2 范围变化的Bloom

(做了一下午了,起来活动一下继续,orz,,)

再继续观察:

早->午:红色(小)-->黄色(大)-->白色(小)

傍晚->晚上:黄色(大)-->橙黄色(超大)-->黄色(小)

(补充:既然节点4Mie散射开始,那我们把大部分白色的Bloom都交给Mie散射,假设整个发光到节点4就宣告结束。) 

【空缺了一部分思路,这里做得比较着急没有记录,放个对比图吧之后补充】

日出日落配上天空颜色变化:

emmm配色什么的感觉挺脏的,然后bloom那里需要给参数调整的,做的时候随便选的,先继续进行下面的步骤,最后再优化。 

接下来是加上云、和星空银河,放在下一篇文章吧。

我上面实现渐变天空选择的颜色还是照抄参考里的配色。但是!我认为一个优秀的天空盒,配色一定是要有讲究的!配色的实现方法打算参考这篇文章里提到的将配色数据做成数组形式,像动画关键帧那样呈现出来的方法。

3 大气散射

做的时候没有记录过程,作品搞完后会回来补上。

参考

这里是我搜刮遍了各种网站找到的实现动态天空盒的文章,自己在做的过程中也参考了很多,这里罗列出来希望对看到这篇文章的你有所帮助:

风格化的动态天空球 – WalkingFat

Unity日夜循环天空球(Procedural Skybox) - 知乎

Making a Stylized Skybox Shader

Unity 卡通渲染 程序化天空盒 - 知乎

【unity URP】昼夜循环天空球 - 知乎

程序化天空盒实现昼夜变换 - 知乎 (zhihu.com)

相关文章:

【程序化天空盒】过程记录01:日月 天空渐变 大气散射

1 日月 SunAndMoon 昼夜的话肯定少不了太阳和月亮,太阳和月亮实现的道理是一样的,只不过是月亮比太阳多了一个需要控制月牙程度(or添加贴图)的细节~ 1.1 Sun 太阳的话很简单,直接在shader里实现一个太阳跟随平行光旋…...

无线通信中的轨道角动量

目录 一. 前言 二. 如何传输 三. 如何产生 3.1 螺旋结构器件 (1)螺旋相位板 (2)螺旋抛物面天线 3.2 超表面 3.3 天线阵列 3.3.1 相控阵 3.3.2 时控阵 四. 如何识别 一. 前言 轨道角动量:Orbital Angular M…...

以后更新功能,再也不用App发版了!智能小程序将为开发者最大化减负

在 IoT 时代,越来越多的企业意识到打造自有 App 对于品牌的重要性。作为智能设备不可或缺的控制终端,App 具备连接用户、完善服务、精细化运营用户的独特优势,可帮助企业大大提升品牌竞争力。 为了帮助品牌企业打造更具个性化、差异化的智能…...

C++之类模板全特化和偏特化

类模板类模板是通用类的描述,使用任意类型(泛型)来描述类的定义。使用类模板的时候,指定具体的数据类型,让编译器生成该类型的类定义。注意:函数模板中可以不指定具体数据类型,让编译器自动推到…...

Python 手写数字识别 MNIST数据集下载失败

目录 一、MNIST数据集下载失败 1 失败的解决办法(经验教训): 2 亲测有效的解决方法: 一、MNIST数据集下载失败 场景复现:想要pytorchMINIST数据集来实现手写数字识别,首先就是进行MNIST数据集的下载&am…...

华为机试题:HJ61 放苹果(python)

文章目录博主精品专栏导航知识点详解1、input():获取控制台(任意形式)的输入。输出均为字符串类型。1.1、input() 与 list(input()) 的区别、及其相互转换方法2、print() :打印输出。3、整型int() :将指定进制&#xf…...

【论文速递】ICCV2021 - 基于超相关压缩实现实时高精度的小样本语义分割

【论文速递】ICCV2021 - 基于超相关压缩的小样本语义分割 【论文原文】:Hypercorrelation Squeeze for Few-Shot Segmentation 【作者信息】:Juhong Min Dahyun Kang Minsu Cho 获取地址:https://openaccess.thecvf.com/content/ICCV2021/…...

单例模式(Singleton Pattern)

目录 1.什么是单例模式: 2.单例模式存在的原因: 3.单例模式的优缺点: 4.创建方式: 1. 单线程单例模式立即创建(饿汉式): 2. 单线程单例模式延迟创建(懒汉式)&#xf…...

docker file和compose

文章目录1.dockerfile(单机脚本)1.概念2.原理3.dockerfile核心四步4.命令2.docker compose1.概念2.注意事项3.常用字段4.常用命令1.dockerfile(单机脚本) 1.概念 通过脚本,生成一个镜像,并运行对应的容器…...

如何解决thinkphp验证码不能显示问题?

thinkPHP做验证码这一块,可以使用自带的验证码扩展,具体步骤如下: 一、安装扩展 composer require topthink/think-captcha 二、模版中使用 将原来静态页面的验证码图片替换为{:captcha_img()},这个会自动生成验证码图片。 <div>{:captcha_img()}</div> 或者 &…...

Vue极简使用

Vue安装Vue模板语法安装Vue 安装nodejs 这里我安装的是14.5.4版本 https://nodejs.org/download/release/v14.15.4/解压后配置一下环境变量就行 安装cnpm镜像 (这个安装的版本可能过高&#xff0c;后面安装Vue可能出问题) npm install -g cnpm --registryhttps://registry…...

【Nacos】Nacos配置中心服务端源码分析

上文说了Nacos配置中心客户端的源码流程&#xff0c;这篇介绍下Nacos配置中心服务端的源码。 服务端的启动 先来看服务启动时干了啥&#xff1f; init()方法上面有PostConstruct&#xff0c;该方法会在ExternalDumpService实例化后执行。 com.alibaba.nacos.config.server.s…...

第十五章 栅格数据重分类、栅格计算器、插值分析

文章目录第十五章 栅格数据分析第一章 栅格数据重分类第一节 栅格数据重分类第二节 栅格重分类的使用第三节 重分类的使用中的空值使用第四节 重分类的案例&#xff1a;分类统计面积第五节 坡度矢量分级图生成第二章 栅格计算器第一节 栅格计算器介绍第二节 栅格计算器使用第三…...

CS5260测试版|CS5260demoboard|typec转VGA参考PCB原理图

CS5260测试版|CS5260demoboard|typec转VGA参考PCB原理图 CS5260是一款高度集成的TYPEC转VGA转换方案芯片。 CS5260输出端接口:外接高清VGA设备如:显示器投影机电视带高清的设备&#xff0c;广泛应用于 笔记本Macbook Air 12寸USB3.1输出端对外接高清VGA设备如:显示器投影机电视…...

winform开发心得

最近一直在从事winform的开发&#xff0c;每次都是需要从网上查找资料才能对应具体风格要求&#xff0c;现在总结一下。 ui方面可以使用CSkin对应的一套ui&#xff0c;使用步骤 1.在窗口界面&#xff0c;工具箱空白处点击右键&#xff0c;弹出菜单有个”选择项“&#xff0c;点…...

学习周报-2023-0210

文章目录一 在SUSE11sp3系统中将openssh从6升级到8一 需求二 系统环境三 部署流程1.上传编译安装的软件包2.安装 gcc编译软件3.安装依赖zlib4.安装依赖openssl5.安装openssh二 在CentOS-6.9配置apache服务&#xff08;3&#xff09;---虚拟主机配置一 定义二 系统环境三 基于域…...

百度富文本UE的问题集合

百度富文本编辑能上传视频成功但是在浏览器不能播放、显示的问题百度富文本视频封面空白问题百度富文本编辑器UMEditor 添加视频无法删除百度富文本编辑器结果存数据库取出来到js赋值报错怎么让浏览器重新加载修改过的JS文件&#xff0c;而不是沿用缓存里的百度富文本编辑能上传…...

在Linux上安装node-v14.17.3和npm-6.14.13

记录&#xff1a;374场景&#xff1a;在CentOS 7.9操作系统上&#xff0c;安装node-v14.17.3-linux-x64环境。包括node-v14.17.3和npm-6.14.13。node命令应用和npm命令应用。版本&#xff1a;JDK 1.8 node v14.17.3 npm 6.14.13官网地址&#xff1a;https://nodejs.org/下载地址…...

机器学习框架sklearn之特征降维

目录特征降维概念特征选择过滤式①低方差特征过滤②相关系数③主成分分析特征降维 0维 标量 1维 向量 2维 矩阵 概念 降维是指在某些限定条件下&#xff0c;降低随机变量&#xff08;特征&#xff09;个数&#xff0c;得到一组“不相关”主变量的过程 注&#xff1a;正是…...

java实现二叉树(一文带你详细了解二叉树的)

&#x1f387;&#x1f387;&#x1f387;作者&#xff1a; 小鱼不会骑车 &#x1f386;&#x1f386;&#x1f386;专栏&#xff1a; 《数据结构》 &#x1f393;&#x1f393;&#x1f393;个人简介&#xff1a; 一名专科大一在读的小比特&#xff0c;努力学习编程是我唯一…...

学弟学妹少走弯路,超完整算法刷题路线出炉

大家好&#xff0c;我是帅地。 本篇文章主要讲解下面三个事&#xff1a; 1、自己学习算法的一些经历 2、大家学习算法存在的一些普遍问题 3、给大家规划的算法刷题路线 一、算法学习往事 记得当初学了 C 语言就开始刷题了&#xff0c;刷题倒不是面试&#xff0c;而是为了…...

Windows截取gif动态图的软件 ScreenToGif 的安装、使用教程

一、概述 &#x1f449;GIF&#xff08;Graphics Interchange Format&#xff09;&#xff0c;又称图形交换格式&#xff0c;是一种公用的图像文件格式标准&#xff0c;于1987年由Compu Serve公司成功研发并推出。 &#x1f449;GIF用于以超文本标志语言方式显示索引彩色图像&a…...

C++程序设计——多态:虚函数、抽象类、虚函数表

注&#xff1a;以下示例均是在VS2019环境下 一、多态的概念 通俗来讲&#xff0c;多态就是多种形态&#xff0c;当不同的对象去完成某个行为时&#xff0c;会产生出不同的状态。即不同继承关系的类对象&#xff0c;去调用同一函数时&#xff0c;产生不同的行为。 比如”叫“这…...

OpenMMLab AI实战营 第6课 语义分割与MMSegmentation

第6课 语义分割与MMSegmentation 1. 语义分割简介 任务&#xff1a;将图像按照物体的类别分割成不同的区域&#xff0c;等价于对每个像素进行分类应用 无人驾驶人像分割智能遥感医疗影像分析 语义分割 vs 实例分割 vs 全景分割 语义分割&#xff1a;仅考虑像素的类别&#xf…...

产业互联网是对互联网的衍生和进化,也是一次重塑和再造

互联网并不仅仅只是充当撮合和中介的角色&#xff0c;它应当具备更多的功能和意义。只有这样&#xff0c;它的发展才能够真正全面和完善。产业互联网的衍生和出现&#xff0c;正是在互联网进化的基础之上出现的。这是我们看到之所以会有那么多的互联网玩家投身到产业互联网的浪…...

Shell脚本之——Hadoop3单机版安装

目录 1.解压 2.文件重命名 3.配置环境变量 4.hadoop-env.sh 5.core-site.xml 6. hdfs-site.xml 7. mapred-site.xml 8.yarn-site.xml 9.完整脚本代码(注意修改主机名) 10.重启环境变量 11.初始化 12.启动服务 13.jps查询节点 1.解压 tar -zxf /opt/install/hadoo…...

代码随想录NO39 |0-1背包问题理论基础 416.分割等和子集

0-1背包问题理论基础 分割等和子集1. 0-1背包问题理论基础(二维数组实现)2. 0-1背包问题理论基础 二&#xff08;一维数组实现&#xff09;1. 0-1背包问题理论基础(二维数组实现) 背包问题一般分为这几种&#xff1a; 0-1背包问题&#xff1a;有n件物品和一个最多能背重量为w…...

FITC-PEG-FA,荧光素-聚乙二醇-叶酸,FA-PEG-FITC,实验室科研试剂,提供质量检测

FITC-PEG-FA&#xff0c;荧光素-聚乙二醇-叶酸 中文名称&#xff1a;荧光素-聚乙二醇-叶酸 英文名称&#xff1a;FITC-PEG-FA 英文别名&#xff1a;Fluorescein-PEG-Folic Acid 性状&#xff1a;基于不同的分子量&#xff0c;呈白色/类白色固体&#xff0c;或粘稠液体。 溶…...

简洁易懂:源码+实战讲解Redisson并发锁及看门狗自动续期

1 缘起 有一次同事问Redisson存储的键是否为hash&#xff1f; 我当时&#xff0c;没有看Redisson的相关源码&#xff0c;只知道应用&#xff0c; 所以没有办法回答&#xff0c;于是开始看看Redisson实现的源码&#xff0c; 顺便写了一个单机Redisson测试&#xff0c; 发现Redi…...

TCP 三次握手和四次挥手

✏️作者&#xff1a;银河罐头 &#x1f4cb;系列专栏&#xff1a;JavaEE &#x1f332;“种一棵树最好的时间是十年前&#xff0c;其次是现在” 目录TCP 建立连接(三次握手)为啥不能是 4 次&#xff1f;为啥不能是 2 次&#xff1f;三次握手的意义&#xff1a;TCP 断开连接(四…...

东莞网页制作招聘信息/怎样优化网站

一、 QT内置的ICON资源保存在QStyle类里。 可以通过成员函数 QStyle::standardIcon 来获取。 保存的icon有&#xff1a; enum QStyle::StandardPixmap This enum describes the available standard pixmaps. A standard pixmap is a pixmap that can follow some existing…...

如何建设网站视频/杭州seo泽成

ADC的资源 12位ADC是一种逐次逼近型模拟数字数字转换器。它有多达18个通道,可测量16个外部和2个内部信号源。ADC的输入时钟不得超过14MHZ,它是由PCLK2经分频产生。如果被ADC转换的模拟电压低于低阀值或高于高阀值,AWD模拟看门狗状态位被设置。 ADC使用方法 ADC通常要与DM…...

招聘做微信公众号网站维护/搜索引擎优化结果

纹理单元改进后的优势 纹理单元 另一个重要单元——纹理单元&#xff0c;在每个SM阵列当中均被安置了四个。每个纹理单元在一个时钟周期内能够计算一个纹理地址并获取四个纹理采样。返回的结果可以是经过过滤的也可以是未过滤的。支持的模式包括双线性、三线性以及各向异性过滤…...

wordpress邮件有%3c%3e/关键词有哪些

最近工作中需要监测某个分公司到IDC机房的网络情况&#xff0c;到网络上找了不少软件&#xff0c;发现一款叫smokeping的开源软件还不错&#xff0c;它是rrdtool的作者制作的&#xff0c;在图形显示方面很漂亮&#xff0c;可以用来很好的检测网络状态和稳定性。 下面介绍一下软…...

如何安装wordpress软件/网络营销工资一般多少

02 JVM 线程JVM内存区域JVM运行时内存垃圾回收与算法JAVA四种引用类型GC分代收集算法 VS 分区收集算法GC垃圾收集器JAVA IO/NIOJVM类加载器 03 JAVA集合 接口继承关系和实现LISTSETMAP 04 JAVA多线程并发 JAVA并发知识库JAVA线程实现/创建方式4种线程池线程生命周期&#xf…...

无锡网站推广公司/app制作公司

转载于:https://www.cnblogs.com/nkwy2012/p/7975808.html...