前言
开个新坑,用ShaderGraph制作系列的星球,提供该方案的一种思路的参考。
行星渲染如果算原图,法线图,高光图三张的话,文件大小动辄几兆或者十几兆。如果要做多样化行星,需要更多贴图。
为了解决上面问题,本项目完全不采用任何贴图。相对贴图方案,本项目优势有:
1 文件体积非常小
2 不受贴图分辨率影响,高清渲染更好控制
3 变换不同的颜色,不同厚度强度大气效果
感兴趣的朋友可以留下来看看,特别是喜欢科幻或者太空题材的小伙伴。
目录
一、ShaderGraph图示
ShaderGraph就不做介绍了。先上图,再确定是否继续往下看
1.1、实例图
蓝色大气层效果
1.2、全流程图
二、ShaderGraph具体流程
2.1、创建ShaderGraph
选择Lit ShaderGraph
进入后可以看到这个
2.2、vertex 端点
object space 是可以链接物体的入口
position 顶点位置(用于计算物体再空间中的坐标)
normal 顶点法线(用于光照计算和渲染过程中,以模拟光线反射的效果)
tangent 顶点的切线(用于控制顶点切线的方向和位置)
2.3、Fragment 是插值
base color 基础颜色
smoothness 物体表面细节的平滑程度
normal 物体的片段法线(三点为一个面片)
emission 物体自发光效果
ambient occlusion 物体的环境光遮蔽
metallic 物体的金属质感
2.4、法线
- 获取当前表面的法线向量
相当于shader中的
mat3 normalMatrix = transpose(inverse(mat3(modelMatrix)));
vec3 worldNormal = normalMatrix * normal;
- normalize
作用是将一个向量缩放到单位长度(长度为1),同时保持其方向不变
2.5、View Direction
View Direction是一个重要的向量,表示从表面点到摄像机(或视角)的方向。它在光照、反射、菲涅尔效应等计算中起着关键作用
结合法线向量,View Direction 可以用于计算反射向量,实现反射效果
2.6、光晕
- Lerp 在shader中
// 标量
float lerp(float A, float B, float T);
// 向量
vec2 lerp(vec2 A, vec2 B, float T);
vec3 lerp(vec3 A, vec3 B, float T);
vec4 lerp(vec4 A, vec4 B, float T);
当 T = 0 时,输出为 A。
当 T = 1 时,输出为 B。
当 T 介于 0 和 1 之间时,输出是 A 和 B 的混合值
- dot product 在shader中
// 标量点积
float dot(float A, float B);
// 向量点积
float dot(vec2 A, vec2 B);
float dot(vec3 A, vec3 B);
float dot(vec4 A, vec4 B);
Dot Product 用于计算两个向量之间的相似性或夹角。以上A 和 B 是两个向量,类型必须相同,返回值是一个标量
- Power
Power 幂运算是一个内置函数,用于计算一个数的幂
// 标量
float pow(float x, float y);
// 向量
vec2 pow(vec2 x, vec2 y);
vec3 pow(vec3 x, vec3 y);
vec4 pow(vec4 x, vec4 y);
x:底数,可以是标量或向量。
y:指数,类型必须与 x 相同。
调整光晕的过度效果
- Smooth step
Smoothstep 用于在两个值之间进行平滑插值。它生成一个平滑的过渡曲线,通常用于创建柔和的过渡效果、边缘模糊、抗锯齿等
在shader中
// 标量
float smoothstep(float a, float b, float x);
// 向量
vec2 smoothstep(vec2 a, vec2 b, vec2 x);
vec3 smoothstep(vec3 a, vec3 b, vec3 x);
vec4 smoothstep(vec4 a, vec4 b, vec4 x);
a 和 b 是过渡的起点和终点。x 是输入值,
返回值是一个平滑过渡的结果,范围是 [0, 1]
2.7、颜色
填充颜色时,也可以给光晕添加过度色
- Branch
Branch是指根据条件执行不同的代码路径
在shader中分支通常通过 if 语句 或 三元运算符 实现
if (condition) {
// A分支
} else {
// B分支
}
以乘积方式将颜色加入shader中
2.8、坐标
获取模型的物体坐标,制作球体的缩放
- 最终的链接
三、ShaderGraph代码
3.1、变量
ShaderGraph 除了自己定义的变量,如,大气厚度,大气强度,层级颜色参数等。剩下是系统自己生成参数。
Properties
{
[HDR]_MainColor("MainColor", Color) = (0, 8.596079, 16, 0)
_ShapeScale("ShapeScale", Float) = 1.16
_FogScale("FogScale", Float) = 25.6
_FogPower("FogPower", Float) = 9.44
[ToggleUI]_ManyFogsBoolean("ManyFogsBoolean", Float) = 1
_ManyFogs("ManyFogs", Range(-5, 0)) = 0
_FogCenterPower("FogCenterPower", Float) = 4.31
[HideInInspector]_QueueOffset("_QueueOffset", Float) = 0
[HideInInspector]_QueueControl("_QueueControl", Float) = -1
[HideInInspector][NoScaleOffset]unity_Lightmaps("unity_Lightmaps", 2DArray) = "" {}
[HideInInspector][NoScaleOffset]unity_LightmapsInd("unity_LightmapsInd", 2DArray) = "" {}
[HideInInspector][NoScaleOffset]unity_ShadowMasks("unity_ShadowMasks", 2DArray) = "" {}
}
3.2、Tags
Tags
{
"RenderPipeline"="UniversalPipeline"
"RenderType"="Transparent"
"UniversalMaterialType" = "Lit"
"Queue"="Transparent"
"DisableBatching"="False"
"ShaderGraphShader"="true"
"ShaderGraphTargetId"="UniversalLitSubTarget"
}
3.3、Pass
Pass
{
Name "Universal Forward"
Tags
{
"LightMode" = "UniversalForward"
}
// Render State
Cull Back
Blend SrcAlpha OneMinusSrcAlpha, One OneMinusSrcAlpha
ZTest LEqual
ZWrite Off
// Debug
// <None>
// --------------------------------------------------
// Pass
HLSLPROGRAM
// Pragmas
#pragma target 2.0
#pragma multi_compile_instancing
#pragma multi_compile_fog
#pragma instancing_options renderinglayer
#pragma vertex vert
#pragma fragment frag
3.4、引用
// Includes
#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"
#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl"
#include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRendering.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPass.hlsl"
Shader Graph 中引用外部文件夹中的资源或自定义代码
如果有更复杂的需求(如动态加载资源),可以结合 Unity 的脚本功能实现
四、实例图示
五、总结
- Branch它可能会对性能产生显著影响,使用分支时需要特别小心,尤其是在 GPU 上
- 法线向量可以在不同空间中使用,并通过法线贴图等技术增强表面细节。
- 法线向量通常需要经过变换,才能正确使用,如模型空间到世界空间。
写着写着就这么多了,可能不是特别全,不介意费时就看看吧。有时间还会接着更新。