前言
想着做好看的场景 好看的天空是第一步 首先来做一个程序化动态天空盒
由于笔者自己还是初学者 所以在制作过程中也做了很多参考 部分自己编写的效果并不那么完备 也有设计不周全的部分在 后期改进可以二编
找个基础
首先拿到unity内置的Procedure skybox查看一下实现原理
可以看到在官方给出的源码中 已经包括大气的散射和太阳的绘制 这是一个很好的开始 可以该基础上进行改动
首先看到在shader中存在三种模式 没有太阳、简单的太阳、高质量太阳 既然目标是好看的天空 直接选取_SUNDISK_HIGH_QUALITY相关代码
#pragma multi_compile_local _SUNDISK_NONE _SUNDISK_SIMPLE _SUNDISK_HIGH_QUALITY
展示一下官方给的天空盒效果
天空的颜色(白天)
天空盒颜色的绘制大体分为两部分 即天空和地面 在这个shader里面可以看到具体的颜色计算在vert函数中进行 而在frag函数中lerp一下划定天空和地面的范围(通过天空盒的法线方向)
//vert
OUT.groundColor = _Exposure * (cIn + COLOR_2_LINEAR(_GroundColor) * cOut);
OUT.skyColor = _Exposure * (cIn * getRayleighPhase(_WorldSpaceLightPos0.xyz, -eyeRay));
//frag
col = lerp(IN.skyColor, IN.groundColor, saturate(y));//天空和地面的颜色范围控制
在对官方天空盒进行调参时发现了改变天空颜色时出现了类似黎明/黄昏的效果(注意参数栏中的颜色)
所以直接定义了一个参数a来控制
float a=1-abs(dot(_WorldSpaceLightPos0.xyz,float3(0,1,0)));
可以看到a的作用是光线越接近水平 a越接近于1 也就是模拟出了黄昏/黎明的效果
天空的颜色(夜晚)
在原shader中当y轴光线方向向上即夜晚时整个天空和地面是不接收光照的 但这明显不符合现实 为了让夜晚的天空不是一片纯黑 需要引入“月光”的照明
这里仿照白天的颜色渲染调整参数即可(注意 大气厚度和地面颜色是通用的)
加上一个太阳
太阳直接采用官方代码的写法就可以了
//太阳范围的定义
half calcSunAttenuation(half3 lightPos, half3 ray,half SizeConvergence,half size){
half focusedEyeCos = pow(saturate(dot(lightPos, ray)), SizeConvergence);//兰伯特...穿个马甲我就不认识你了吗
return getMiePhase(-focusedEyeCos, focusedEyeCos * focusedEyeCos,size);}
//ray
half3 ray = normalize(IN.vertex.xyz);//法线方向的反方向
一通看发现 这不就是个兰伯特吗 也是遇上老熟人了
当然还要记得乘上太阳的颜色
OUT.sunColor = kHDSundiskIntensityFactor * saturate(cOut) * _LightColor0.xyz / lightColorIntensity;
注意这里太阳的颜色并不是用户传入的 而是通过计算得出的
加上一个月亮
月亮其实是最后写的 那个贴图的uv想想就头疼
【Unity URP】Unity Procedural Skybox Shader - Sand and Foam - FlowingCrescent's Blog
参照的是这位大佬的写法
//shader
float2 moonUV =mul(float3(-IN.texcoord.x,-IN.texcoord.y,IN.texcoord.z),_LToW)*9;
moonUV+=float2(0.5,0.5);
half3 moonCol=tex2D(_MoonTex,moonUV).rgb;
//C#
material.SetMatrix("_LToW",this.transform.worldToLocalMatrix);
找了个月亮贴图一采样还挺像那么回事
这里一定要注意了 找的这个贴图模式记得改成clamp 边框不能有白边
看时间长了总感觉不对味 感觉月亮扁扁的 没有“皎洁”的感觉 (月亮长这样 估计没有嫦娥奔月的故事了)
于是又给加了一圈柔光 这下高兴了:
这么多的星星!
做星星又开始找参考了 又说实时生成噪声的 有说SD拿个噪声图色阶处理一下遮罩的
我都试了...放在电脑上效果都很奇怪 这个实时生成的“星星”静态很不错 但是一旦视角动起来会剧烈闪动 sd做的图放到unity里面能看到有一部分的星星并不是完美的小圆点 而是矩形的(应该是我的噪声图不好加上分辨率的问题)
做了一下午 最后决定ps手点了 然后放到SD里面tilling一下也是张不错的星星遮罩
星星扰动的噪声图给放到了star图的g通道 减少采样开销
最后的效果(uv流动稍微快了点 这样看的清楚)
漂亮的银河
银河希望的效果是在深夜时出现,黎明之前就要全部消失 利用方向光的角度进行控制
half b=smoothstep(0.6,1,max(0,dot(_WorldSpaceLightPos0.xyz,float3(0,-1,0))));
银河的噪声扰动还没做 这里就是放了一张贴图(后续扰动补上)
云朵(卷云+积云)
云朵的制作思路参考这位大佬
做了两层云相对慢速旋转 最终效果还不错
最终效果
需要改进的地方 慢慢填坑吧
添加镜头光晕
星河扰动
云的出现以及消散(SDF)
depthfade
月相的变化
日月与地平线的depthfade