【Unity3D】Shader Graph节点

1 前言

        Shader Graph 16.0.3 中有 208 个 Node(节点),本文梳理了 Shader Graph 中大部分 Node 的释义,官方介绍详见→Node-Library。

        Shader Graph 通过图像的形式表达了顶点变换和片元着色流程,其背后都是一些列的数学理论支撑着,为更好地理解 Shader Graph 中的 Node,推荐读者学习以下内容。

  • 渲染管线

  • 空间和变换

  • Shader常量、变量、结构体、函数

  • 法线贴图和凹凸映射

  • 屏幕深度和法线纹理简介

  • Shader Graph简介

2 Artistic(美术)

        Artistic 官方介绍详见→Artistic Nodes。

2.1 Adjustment(颜色调整)

        1)Channel Mixer(通道混合)

        Channel Mixer 节点用于通道混合,根据混合权重对每个通道进行混合,_ChannelMixer_Red、_ChannelMixer_Green、_ChannelMixer_Blue 分别为红色、绿色、蓝色通道的权重向量。

void ChannelMixer(float3 In, float3 _ChannelMixer_Red, float3 _ChannelMixer_Green, float3 _ChannelMixer_Blue, out float3 Out) {
    Out = float3(dot(In, _ChannelMixer_Red), dot(In, _ChannelMixer_Green), dot(In, _ChannelMixer_Blue));
}

        2)Contrast(调整对比度)

        Contrast 节点用于调整对比度。 

void Contrast(float3 In, float Contrast, out float3 Out) {
    float midpoint = pow(0.5, 2.2); // 约等于0.217638
    Out = (In - midpoint) * Contrast + midpoint;
}

        说明:midpoint = pow(0.5, 2.2) 是对 0.5 进行了伽马编码(详见伽马校正),解决亮度异常问题。

        3)Hue(调整色相)

         Hue 节点用于调整色相,其实现见→Hue Node。

void Hue(float3 In, float Offset, out float3 Out)

        说明:色相调整有 2 种模式:Degrees、 Normalized。在可视化界面中,色相的调整一般通过色相环实现,offset 就对应色相环中的角度,在 Degrees 模式下,offset 取值范围是 0 ~ 360°,在 Normalized 模式下,offest 取值范围是 0 ~ 1。

        4)Invert Colors(反转颜色)

        Invert Colors 节点用于反转颜色。  

void InvertColors(float4 In, float4 InvertColors, out float4 Out) {
    Out = abs(InvertColors - In);
}

        5)Replace Color(替换颜色)

        Replace Color 节点用于替换颜色,如果输入颜色与 From 颜色比较接近,就将输入颜色替换为 To 颜色,Range 是输入颜色被替换的边界,Fuzziness 是模糊系数。  

void ReplaceColor(float3 In, float3 From, float3 To, float Range, float Fuzziness, out float3 Out) {
    float Distance = distance(From, In);
    Out = lerp(To, In, saturate((Distance - Range) / max(Fuzziness, 1e-5))); // 1e-5=0.00001, 避免Fuzziness为0时除数为0
}

        6)Saturation(调整饱和度)

         Saturation 节点用于调整饱和度。

void Saturation(float3 In, float Saturation, out float3 Out) {
    float luma = dot(In, float3(0.2126729, 0.7151522, 0.0721750));
    Out =  luma.xxx + Saturation.xxx * (In - luma.xxx);
}

        7)White Balance(调整白平衡)

        White Balance 节点用于调整白平衡,其实现见→White Balance Node,Temperature 用于调整色温,Tint 用于调整色调。

void WhiteBalance(float3 In, float Temperature, float Tint, out float3 Out)

2.2 Blend(颜色混合)

        Blend 节点用于混合两种颜色。 

         Mode 取值有:Burn、Darken、Difference、Dodge、Divide、Exclusion、Hard Light、Hard Mix、Lighten、Linear Burn、Linear Dodge、Linear Light、Linear Light Add Sub、Multiply、Negation、Overlay(默认值)、Pin Light、Screen、Soft Light、Subtract、Vivid Light、Overwrite。不同 Mode 对应的混合函数详见→Blend Node。

2.3 Filter(滤波器)

        Filter 里只有一个 Node:Dither,它用于模拟颜色随机振动,它通过一个 4 x 4 的矩阵模拟伪随机振动,这个矩阵的每一行和每一列都呈波浪状(一大一小交错排列)。

void Dither(float4 In, float4 ScreenPosition, out float4 Out) {
    float2 uv = ScreenPosition.xy * _ScreenParams.xy;
    float DITHER_THRESHOLDS[16] = {
        1.0 / 17.0,  9.0 / 17.0,  3.0 / 17.0, 11.0 / 17.0,
        13.0 / 17.0,  5.0 / 17.0, 15.0 / 17.0,  7.0 / 17.0,
        4.0 / 17.0, 12.0 / 17.0,  2.0 / 17.0, 10.0 / 17.0,
        16.0 / 17.0,  8.0 / 17.0, 14.0 / 17.0,  6.0 / 17.0
    };
    uint index = (uint(uv.x) % 4) * 4 + uint(uv.y) % 4;
    Out = In - DITHER_THRESHOLDS[index];
}

        说明:对于 ScreenPosition 的取值,用户可以自己输入,也可以使用 Unity 自带的取值,主要有:Default、Raw、Center、Tiled。

2.4 Mask(遮罩)

        1)Channel Mask(通道遮罩)

        Channel Mask 节点用于遮罩通道,将被遮罩的通道置为 0,如下是将 RG 通道遮罩的代码逻辑。

void ChannelMask_RedGreen(float4 In, out float4 Out) {
    Out = float4(0, 0, In.b, In.a);
}

        2)Color Mask(颜色遮罩)

        Color Mask 节点用于颜色遮罩,计算输入颜色与目标颜色的近似程度,比较接近就输出 1,偏移比较大就输出 0。

void ColorMask(float3 In, float3 MaskColor, float Range, float Fuzziness, out float4 Out) {
    float Distance = distance(MaskColor, In);
    Out = saturate(1 - (Distance - Range) / max(Fuzziness, 1e-5)); // 1e-5=0.00001, 避免Fuzziness为0时除数为0
}

2.5 Normal(法线)

        1)Normal Blend(法线混合)

        Normal Blend 有 2 种模式:Default、Reoriented。

void NormalBlend(float3 A, float3 B, out float3 Out) { // Default模式
    Out = normalize(float3(A.rg + B.rg, A.b * B.b));
}

void NormalBlend_Reoriented(float3 A, float3 B, out float3 Out) { // Reoriented模式
    float3 t = A.xyz + float3(0.0, 0.0, 1.0);
    float3 u = B.xyz * float3(-1.0, -1.0, 1.0);
    Out = (t / t.z) * dot(t, u) - u;
}

        2)Normal From Height(由高度值转换为法线纹理)

        Normal From Height 节点用于将输入的高度值转换到法线纹理中。Output Space(输出空间)有:Tangent(切线空间)、World(世界空间)。源码详见→Normal From Height Node,它通过对 Position、In 求 ddx 和 ddy 等运算得到法线值。

void NormalFromHeight(float In, out float3 Out)

        3)Normal From Texture(由高度纹理转换为法线纹理)

        Normal From Texture 节点用于将高度纹理转换为法线纹理。Offset 为高度采样 uv 偏移量,Strength 用于调整法线强度(物体表面凹凸程度)。

void NormalFromTexture(Texture texture, SamplerState Sampler, float2 UV, float Offset, float Strength, out float3 Out) {
    Offset = pow(Offset, 3) * 0.1;
    float2 offsetU = float2(UV.x + Offset, UV.y);
    float2 offsetV = float2(UV.x, UV.y + Offset);
    float normalSample = Texture.Sample(Sampler, UV);
    float uSample = Texture.Sample(Sampler, offsetU);
    float vSample = Texture.Sample(Sampler, offsetV);
    float3 va = float3(1, 0, (uSample - normalSample) * Strength); // 切线(高度图1m一个像素)
    float3 vb = float3(0, 1, (vSample - normalSample) * Strength); // 切线(高度图1m一个像素)
    Out = normalize(cross(va, vb)); // 通过2条切线向量叉乘得到法线向量
}

        4)Normal Reconstract Z(法线重构)

        Normal Reconstract Z 节点用于重构法线向量,原来的 z 分量被抛弃,由 x、y 分量推导出,再对法线向量进行归一化。

void NormalReconstructZ(float2 In, out float3 Out) {
    float reconstructZ = sqrt(1.0 - saturate(dot(In.xy, In.xy)));
    float3 normalVector = float3(In.x, In.y, reconstructZ);
    Out = normalize(normalVector);
}

        5)Normal Strength(调整物体表面凹凸程度)

        Normal Strength 节点用于调整法线强度(物体表面凹凸程度,案例见→法线贴图和凹凸映射)。注意,调整法线向量后需要归一化法线向量。

void NormalStrength(float3 In, float Strength, out float3 Out) {
    Out = {precision}3(In.rg * Strength, lerp(1, In.b, saturate(Strength)));
}

        说明:"{precision}3" 是一个类似于构造函数的语法,用于构建一个包含 3 个分量的向量。

        6)Normal Unpack(由法线纹理解码法线向量)

        Normal Unpack 节点用于从法线纹理中解码法线向量。Output Space(输出空间)有:Tangent(切线空间)、Object(模型空间)。

void NormalUnpack(float4 In, out float3 Out) { //Tangent
    Out = UnpackNormalmapRGorAG(In);
}

void NormalUnpackRGB(float4 In, out float3 Out) { // Object
    Out = UnpackNormalmapRGB(In);
}

2.6 Utility(实用工具)

        Utility 中只有 Colorspace Conversion 节点,用于进行 RGB、Linear、HSV 颜色空间之间的相互转换,源码详见→Colorspace Conversion Node。

3 Channel(通道)

        Channel 官方介绍详见→Channel Nodes。

        1)Combine(合并通道)

        Combine 节点用于合并通道。 

void Combine(float R, float G, float B, float A, out float4 RGBA, out float3 RGB, out float2 RG) {
    RGBA = float4(R, G, B, A);
    RGB = float3(R, G, B);
    RG = float2(R, G);
}

        2)Flip(翻转通道)

        Flip 节点用于翻转通道,即相应通道数值取反,Flip 取值为 0(未激活)或 1(激活)。  

void Flip(float4 In, float4 Flip, out float4 Out) {
    Out = (Flip * -2 + 1) * In;
}

        3)Split(分离通道)

        Split 节点用于分离通道,以下是输入为 2 维的情况,如果输入维数低于输出维数,高维通道补零输出。

void Split(float2 In, out float R, out float G, out float B, out float A) {
    R = In[0];
    G = In[1];
    B = 0;
    A = 0;
}

        4)Swizzle(交换通道)

        Swizzle 节点用于交换通道,根据 Mask 中通道的顺序重组通道。如下是其中一种交换方式。

float4 _Swizzle_Out = In.xzyw;

4 Input(输入)

        Input 官方介绍详见→Input Nodes。

4.1 Basic(基础变量)

        Basic 中是一些基础的变量节点,如:Boolean、Constant、Float、Integer、Slider、Time、Color、Vector2、Vector3、Vector4。

4.2 Geometry(顶点几何属性)

        Geometry 中提供了访问顶点或片元几何属性的节点,如:Position、Screen Position、UV、Vertex Color、Tangent Vector、Bitangent Vector、Normal Vector、View Direction、View Vector。

  • Position:顶点或片元的坐标,Space 取值有:Object(模型空间)、World(世界空间)、View(观察空间)、Tangent(切线空间)、Absolute World(绝对世界空间)。对于所有可编程渲染管线,Absolute World 选项始终返回对象在场景中的绝对世界位置,World 选项返回所选的可编程渲染管线的默认世界空间。HDRP(高清渲染管线)使用 Camera Relative 作为默认世界空间,URP(通用渲染管线)使用 Absolute World 作为默认世界空间。
  • Screen Position:顶点或片元的屏幕坐标,Mode 取值有:Default、Raw、Center、Tiled。
  • UV:顶点或片元的 UV 坐标。
  • Vertex Color:顶点或片元的颜色。
  • Tangent Vector:顶点或片元的切线向量,Space 取值有:Object(模型空间)、World(世界空间)、View(观察空间)、Tangent(切线空间)。
  • Bitangent Vector:顶点或片元的副切线向量,Space 取值有:Object(模型空间)、World(世界空间)、View(观察空间)、Tangent(切线空间)。
  • Normal Vector:顶点或片元的法线向量,Space 取值有:Object(模型空间)、World(世界空间)、View(观察空间)、Tangent(切线空间)。
  • View Direction:顶点或片元的观察向量(顶点指向相机,已归一化),Space 取值有:Object(模型空间)、World(世界空间)、View(观察空间)、Tangent(切线空间)。
  • View Vector:顶点或片元的观察向量(顶点指向相机,未归一化),Space 取值有:Object(模型空间)、World(世界空间)、View(观察空间)、Tangent(切线空间)。

        Screen Position 不同模式下的实现如下。

// Default, 归一化的设备坐标(NDC), x、y值域: [0, 1]
float4 Out = float4(IN.NDCPosition.xy, 0, 0);
// Raw, 屏幕坐标, x值域: [0, w], y值域: [0, w]
float4 Out = IN.ScreenPosition;
// Center, 标准化的设备坐标, x、y值域: [-1, 1]
float4 Out = float4(IN.NDCPosition.xy * 2 - 1, 0, 0);
// Tiled, x值域: [-screenWidth/screenHeight, screenWidth/screenHeight], y值域: [-1, 1]
float4 Out = frac(float4((IN.NDCPosition.x * 2 - 1) * _ScreenParams.x / _ScreenParams.y, IN.{0}.y * 2 - 1, 0, 0));
// Pixel, 像素坐标, x值域: [0, screenWidth], y值域: [0, screenHeight]
float4 Out = float4(IN.PixelPosition.xy, 0, 0);

4.3 Gradient(渐变颜色)

        Blackbody、Gradient、Sample Gradient 节点都是用于生成渐变颜色。 

        1) Blackbody(黑体辐射渐变采样)

        Blackbody 节点通过模拟黑体辐射渐变采样得到渐变颜色,其实现见→Blackbody Node,它基于 Mitchell Charity 收集的数据,输出线性 RGB 空间的颜色,并使用一个 D65 白点和一个 CIE 1964 10 度的颜色空间执行转换,Temperature 为采样的温度或温度贴图(以开尔文为单位)。

void Blackbody(float Temperature, out float3 Out)

        2)Gradient(生成渐变对象)

        Gradient 节点用于生成 Gradient 渐变对象,它通过 2 个 Color 和 2 个 Alpha 参数计算得到,实现见→Gradient Node。

        3)Sample Gradient(渐变采样)

        Sample Gradient 节点用于对 Gradient 进行渐变采样,其实现见→Sample Gradient Node,Time 为采样渐变的时间点 (0.0–1.0)。

void SampleGradient(float4 Gradient, float Time, out float4 Out)

4.4 Lighting(光照)

        1)Ambient(环境光)

        Ambient 节点用于获取环境光颜色。

float3 _Ambient_ColorSky = SHADERGRAPH_AMBIENT_SKY;
float3 _Ambient_Equator = SHADERGRAPH_AMBIENT_EQUATOR;
float3 _Ambient_Ground = SHADERGRAPH_AMBIENT_GROUND;

        2)Baked GI(烘焙的全局光照)

        Baked GI 节点用于获取烘焙的全局光照颜色,Position 为顶点坐标(世界空间),Normal 为顶点法线(世界空间)、StaticUV 为静态 lightmap 的纹理坐标、DynamicUV 为动态 lightmap 的纹理坐标。

void BakedGI(float3 Position, float3 Normal, float2 StaticUV, float2 DynamicUV, out float Out) {
    Out = SHADERGRAPH_BAKED_GI(Position, Normal, StaticUV, DynamicUV, false);
}

        3)Reflection Probe(反射探针)

         Reflection Probe 节点用于获取反射探针颜色。ViewDire 为顶点的坐标(模型空间),Normal 为顶点的法线向量(模型空间)。

void ReflectionProbe(float3 ViewDir, float3 Normal, float LOD, out float3 Out) {
    Out = SHADERGRAPH_REFLECTION_PROBE(ViewDir, Normal, LOD);
}

        4)Main Light Direction

        Main Light Direction 节点用于获取顶点指向光源的单位方向向量(世界空间)。Shader Graph 13.1.9(2022.1+)版本才开始出现 Main Light Direction 节点。如果用户的 Shader Graph 版本较低,可以通过 8.2 节中 Custom Function 节点创建自定义函数,获取灯光方向。

4.5 Matrix(矩阵)

        Matrix 中包含 Matrix 2x2、Matrix 3x3、Matrix 4x4、Transformation Matrix 节点。

        Transformation Matrix 节点可以获取到 Model、Inverse Model、View、Inverse View、Projection、Inverse Projection、View Projection、Inverse View Projection 矩阵,实现如下。

// Model, [模型空间->世界空间]的变换矩阵M
float4x4 _TransformationMatrix_Out = UNITY_MATRIX_M;
// InverseModel, [世界空间->模型空间]的变换矩阵I_M
float4x4 _TransformationMatrix_Out = UNITY_MATRIX_I_M;
// View, [世界空间->观察空间]的变换矩阵V
float4x4 _TransformationMatrix_Out = UNITY_MATRIX_V;
// InverseView, [观察空间->世界空间]的变换矩阵I_V
float4x4 _TransformationMatrix_Out = UNITY_MATRIX_I_V;
// Projection, [观察空间->裁剪空间]的变换矩阵P
float4x4 _TransformationMatrix_Out = UNITY_MATRIX_P;
// InverseProjection, [裁剪空间->观察空间]的变换矩阵I_P
float4x4 _TransformationMatrix_Out = UNITY_MATRIX_I_P;
// ViewProjection, [世界空间->裁剪空间]的变换矩阵VP
float4x4 _TransformationMatrix_Out = UNITY_MATRIX_VP;
// InverseViewProjection, [裁剪空间->世界空间]的变换矩阵I_VP
float4x4 _TransformationMatrix_Out = UNITY_MATRIX_I_VP;

4.6 Scene(场景参数)

        1)Camera(相机参数)

        Camera 节点用于获取相机的以下属性。

  • Position:相机的坐标(世界空间),代码:_WorldSpaceCameraPos。
  • Direction:相机的 forward 向量。
  • Orthographic:如果摄像机是正交摄像机,则返回 1,否则返回 0,代码:unity_OrthoParams.w。
  • Near Plane:近裁剪平面到相机的距离,代码:_ProjectionParams.y。
  • Far Plane:远裁剪平面到相机的距离,代码:_ProjectionParams.z。
  • Z Buffer Sign:使用反转的 Z 缓冲区时返回 -1,否则返回 1,代码:_ProjectionParams.x。
  • Width:摄像机的宽度(如果是正交摄像机),unity_OrthoParams.x。
  • Height:摄像机的高度(如果是正交摄像机),unity_OrthoParams.y。

        2)Fog(雾效参数)

        Fog 节点用于获取 Color(雾效颜色)和 Density(裁剪空间深度处的雾效强度)。

void Fog(float3 Position, out float4 Color, out float Density) {
    SHADERGRAPH_FOG(Position, Color, Density);
}

        3)Object(对象参数)

        Object 节点用于获取当前渲染对象在世界空间中的位置缩放。

float3 _Object_Position = SHADERGRAPH_OBJECT_POSITION;
float3 _Object_Scale = float3(
    length(float3(UNITY_MATRIX_M[0].x, UNITY_MATRIX_M[1].x, UNITY_MATRIX_M[2].x)),
    length(float3(UNITY_MATRIX_M[0].y, UNITY_MATRIX_M[1].y, UNITY_MATRIX_M[2].y)),
    length(float3(UNITY_MATRIX_M[0].z, UNITY_MATRIX_M[1].z, UNITY_MATRIX_M[2].z)));

        4)Scene Color(场景颜色)

        Scene Color 节点用于获取 UV 处的颜色缓冲区的颜色值。

void SceneColor(float4 UV, out float3 Out) {
    Out = SHADERGRAPH_SAMPLE_SCENE_COLOR(UV);
}

        说明:在通用渲染管线中,此节点返回 Camera Opaque Texture 的值,此纹理的内容仅适用于透明对象。将主节点的 Material Options 面板上的 Surface Type 下拉选单设置为 Transparent 可以从此节点接收正确的值。

        5)Scene Depth(场景深度)

        Scene Depth 节点用于获取 UV 处的深度缓冲区的深度值。

void SceneDepth_Raw(float4 UV, out float Out) {
    Out = SHADERGRAPH_SAMPLE_SCENE_DEPTH(UV);
}

        6)Screen(屏幕参数)

        Screen 节点用于获取屏幕的宽度和高度参数。

float _Screen_Width = _ScreenParams.x;
float _Screen_Height = _ScreenParams.y;

4.7 Texture(纹理)

        1)Texture 2D Asset 和 Cubemap Asset

        Texture 2D Asset 节点用于导入 Texture 2D 资源,Cubemap Asset 节点用于导入 Cubemap 资源。

        2)Sample Texture 2D 和 Sample Cubemap

        Sample Texture 2D 节点用于对 Texture 2D 进行采样,Sample Cubemap 节点用于对 Cubemap 进行采样。

        3)Texel Size(Texture 2D 的宽高)

        Texel Size 节点用于获取 Texture 2D 的宽度和高度。

float _TexelSize_Width = Texture_TexelSize.z;
float _TexelSize_Height = Texture_TexelSize.w;

        4)Split Texture Transform(Texture 2D 的缩放和偏移)

        Split Texture Transform 节点用于 Texture 2D 的 Tiling(缩放)和 Offset(偏移)属性。

        5)Sampler State(采样器的状态配置)

        Sampler State 节点用于配置采样器的状态。Filter 定义了采样的滤波模式,选项有:Linear、Point、Trilinear;Wrap 定义了采样的包裹模式,选项有:Repeat、Clamp、Mirror、MirrorOnce。

5 Math(数学)

        Math 官方介绍详见→Math Nodes,其中引用 Shader 中的函数释义详见→Shader常量、变量、结构体、函数。

5.1 Basic(基础运算)

// 加法, Out=A+B
void Add(float4 A, float4 B, out float4 Out)
// 减法, Out=A-B
void Subtract(float4 A, float4 B, out float4 Out)
// 乘法
void Multiply(float4 A, float4 B, out float4 Out) // Out=A*B
void Multiply(float4 A, float4x4 B, out float4 Out) // Out=mul(A,B)
void Multiply(float4x4 A, float4x4 B, out float4x4 Out) // Out=mul(A,B)
// 除法, Out=A/B
void Divide(float4 A, float4 B, out float4 Out)
// 幂运算, Out=pow(A,B)
void Power(float4 A, float4 B, out float4 Out)
// 平方根, Out=sqrt(In)
void SquareRoot(float4 In, out float4 Out)

5.2 Advanced(高级运算)

// 绝对值, Out=abs(In)
void Absolute(float4 In, out float4 Out)
// 取反, Out=-1*In
void Negate(float4 In, out float4 Out)
// 倒数
void Reciprocal(float4 In, out float4 Out) // Out=1.0/In
void Reciprocal_Fast(float4 In, out float4 Out) // Out=rcp(In)
// 取余, Out=fmod(A,B)
void Modulo(float4 A, float4 B, out float4 Out)
// 指数
void Exponential(float4 In, out float4 Out) // Out=exp(In)
void Exponential2(float4 In, out float4 Out) // Out=exp2(In)
// 对数
void Log(float4 In, out float4 Out) // Out=log(In)
void Log2(float4 In, out float4 Out) // Out=log2(In)
void Log10(float4 In, out float4 Out) // Out=log10(In)
// 反平方根
void ReciprocalSquareRoot(float4 In, out float4 Out) // Out=rsqrt(In)
// 模长, Out=length(In)
void Length(float4 In, out float Out)
// 归一化
void Normalize(float4 In, out float4 Out) // Out=normalize(In)
// 多色调分色显示, Out=floor(In/(1/Steps))*(1/Steps)
void Posterize(float4 In, float4 Steps, out float4 Out)

5.3 Trigonometry(三角函数运算)

// 角度转弧度, Out=radians(In)
void DegreesToRadians(float4 In, out float4 Out)
// 弧度转角度, Out=degrees(In)
void RadiansToDegrees(float4 In, out float4 Out)
// 正弦, Out=sin(In)
void Sine(float4 In, out float4 Out)
// 余弦, Out=cos(In)
void Cosine(float4 In, out float4 Out)
// 正切, Out=tan(In)
void Tangent(float4 In, out float4 Out)
// 反正弦, Out=asin(In)
void Arcsine(float4 In, out float4 Out)
// 反余弦, Out=acos(In)
void Arccosine(float4 In, out float4 Out)
// 反正切
void Arctangent(float4 In, out float4 Out) // Out=atan(In)
void Arctangent2(float4 A, float4 B, out float4 Out) // Out=atan2(A,B)
// 双曲正弦, Out=sinh(In)
void HyperbolicSine(float4 In, out float4 Out)
// 双曲余弦, Out=cosh(In)
void HyperbolicCosine(float4 In, out float4 Out)
// 双曲正切, Out=tanh(In)
void HyperbolicTangent(float4 In, out float4 Out)

5.4 Range(范围运算)

// 最大值, Out=max(A,B)
void Maximum(float4 A, float4 B, out float4 Out)
// 最小值, Out=min(A,B)
void Minimum(float4 A, float4 B, out float4 Out)
// 限界, Out=clamp(In,Min,Max)
void Clamp(float4 In, float4 Min, float4 Max, out float4 Out)
// 0-1限界, Out=saturate(In)
void Saturate(float4 In, out float4 Out)
// 取小数部分, Out=frac(In)
void Fraction(float4 In, out float4 Out)
// 1减, Out=1-In
void OneMinus(float4 In, out float4 Out)
// 重映射, Out=OutMinMax.x+(In-InMinMax.x)*(OutMinMax.y-OutMinMax.x)/(InMinMax.y-InMinMax.x)
void Remap(float4 In, float2 InMinMax, float2 OutMinMax, out float4 Out)
// 伪随机数生成器
void RandomRange(float2 Seed, float Min, float Max, out float Out) {
    float randomno = frac(sin(dot(Seed, float2(12.9898, 78.233)))*43758.5453);
    Out = lerp(Min, Max, randomno);
}

5.5 Round(取整运算)

// 正负符合, Out=sign(In)
void Sign(float4 In, out float4 Out)
// 取整数部分, Out=trunc(In)
void Truncate(float4 In, out float4 Out)
// 向上取整, Out=ceil(In)
void Ceiling(float4 In, out float4 Out)
// 向下取整, Out=floor(In)
void Floor(float4 In, out float4 Out)
// 四舍五入取整, Out=round(In)
void Round(float4 In, out float4 Out)
// 边界判断, Out=step(Edge,In), 即: In>=Edge时, 返回1, 否则返回0
void Step(float4 Edge, float4 In, out float4 Out)

5.6 Interpolation(插值运算)

// 插值, Out=lerp(A,B,T), 即: Out=(1-T)*A+T*B
void Lerp(float4 A, float4 B, float4 T, out float4 Out)
// 反插值, Out=(T-A)/(B-A)
void InverseLerp(float4 A, float4 B, float4 T, out float4 Out)
// 平滑插值, Out=smoothstep(Edge1,Edge2,In), 即: k=saturate((In-Edge1)/(Edge2-Edge1)), Out=k*k*(3-2*k)
void Smoothstep(float4 Edge1, float4 Edge2, float4 In, out float4 Out)

5.7 Vector(向量运算)

// 两点间距离, Out=distance(A,B)
void Distance(float4 A, float4 B, out float Out)
// 向量点乘, Out=dot(A,B)
void DotProduct(float4 A, float4 B, out float Out)
// 向量叉乘, Out=cross(A,B)
void CrossProduct(float3 A, float3 B, out float3 Out)
// 向量投影, Out=B*dot(A,B)/dot(B, B)
void Projection(float4 A, float4 B, out float4 Out)
// 向量反射, Out=reflect(In,Normal), In和Normal不需要归一化
void Reflection(float4 In, float4 Normal, out float4 Out)
// 菲涅尔效应, Out=pow((1.0-saturate(dot(normalize(Normal),normalize(ViewDir)))),Power)
void FresnelEffect(float3 Normal, float3 ViewDir, float Power, out float Out)
// 绕轴旋转
void RotateAboutAxis(float3 In, float3 Axis, float Rotation, out float3 Out)
// 球形遮罩, Out =1-saturate((distance(Coords,Center)-Radius)/(1-Hardness)), 即: 球内返回1, 求外返回零
void SphereMask(float4 Coords, float4 Center, float Radius, float Hardness, out float4 Out)
// 坐标或向量空间变换, 可以进行Object、World、View、Tangent、Absolute World空间之间变换
void Transform(float4 In, out float4 Out)

5.8 Matrix(矩阵运算)

// 构建矩阵
void MatrixConstruction(float4 M0, float4 M1, float4 M2, float3 M3, out float4x4 Out4x4, out float3x3 Out3x3, out float2x2 Out2x2)
// 计算矩阵的秩, Out=determinant(In)
void MatrixDeterminant(float4x4 In, out float Out)
// 分离矩阵的行向量或列向量
void MatrixSplit(float4x4 In, out float4 M0, out float4 M1, out float4 M2, out float4 M3)
// 矩阵转置, Out=transpose(In)
void MatrixTranspose(float4x4 In, out float4x4 Out)

5.9 Derivative(导数运算)

// Out=ddx(In)
void DDX(float4 In, out float4 Out)
// Out=ddxy(In)
void DDXY(float4 In, out float4 Out)
// Out=ddy(In)
void DDY(float4 In, out float4 Out)

5.10 Wave(波运算)

// 锯齿波, Out=2*(In-floor(0.5 + In))
void SawtoothWave(float4 In, out float4 Out)
// 方波, Out=1.0-2.0*round(frac(In))
void SquareWave(float4 In, out float4 Out)
// 三角波, Out=2.0*abs(2*(In-floor(0.5+In)))-1.0
void TriangleWave(float4 In, out float4 Out)
// 带噪声的正弦波
void NoiseSineWave(float4 In, float2 MinMax, out float4 Out) {
    float sinIn = sin(In);
    float sinInOffset = sin(In + 1.0);
    float randomno =  frac(sin((sinIn - sinInOffset) * (12.9898 + 78.233))*43758.5453);
    float noise = lerp(MinMax.x, MinMax.y, randomno);
    Out = sinIn + noise;
}

6 Procedural(程序纹理)

        Procedural 官方介绍详见→Procedural Nodes。

6.1 Noise(噪声纹理)

        Noise 下面有 Gradient Noise(梯度噪声)、Simple Noise(简单噪声)、Voronoi(泰森多边形)。噪声纹理应用:选中物体消融特效、消融特效、流动雾效。

6.2 Shapes(形状纹理)

        Shapes 下面有 Ellipse(椭圆)、Polygon(多边形)、Rectangle(矩形)、Rounded Polygon(圆角多边形)、Rounded Rectangle(圆角矩形)。

7 UV(UV 变换)

        UV 官方介绍详见→UV Nodes。

        1)Flipbook(翻书 uv 变换)

        Flipbook 节点用于做翻书动画,实现见→Flipbook Node,Width 和 Height 分别为水平和垂直区块的数量,Tile 为当前区块索引。

        2)Polar Coordinates(极坐标 uv 变换)

        Polar Coordinates 节点用于将直角坐标系下的 uv 坐标转换为极坐标系下的坐标,实现见→Polar Coordinates。

        3)Radial Shear(径向剪切 uv 变换)

        Radial Shear 节点用于模拟波的径向剪切变形效果,实现见→Radial Shear Node。

        4)Rotate(旋转 uv 变换)

        Rotate 节点用于实现纹理旋转效果,实现见→Rotate Node。

        5)Spherize(球形变形 uv 变换)

        Spherize 节点用于模拟鱼眼镜头的球形变形效果,实现见→Spherize。

        6)Tiling And Offset(缩放和偏移 uv 变换)

        Tiling And Offset 节点用于缩放和偏移 uv 坐标。

void TilingAndOffset(float2 UV, float2 Tiling, float2 Offset, out float2 Out) {
    Out = UV * Tiling + Offset;
}

        7)Twirl(旋转变形 uv 变换)

        Twirl 节点用于模拟黑洞的旋转变形效果,实现见→Twirl Node。

8 Utility(实用工具)

        Utility 官方介绍详见→Utility Nodes。

8.1 Logic(逻辑判断)

// 与运算, Out=A&&B
void And(float A, float B, out float Out)
// 或运算, Out=A||B
void Or(float In, out float Out)
// 非运算, Out=!In
void Not(float In, out float Out)
// 全true, Out=all(In), 即: 如果In中每个分量都不为零则返回1, 否则返回0
void All(float4 In, out float Out)
// 存在一true, Out=any(In), 即: 如果In中存在一个分量不为零则返回1, 否则返回0
void Any(float4 In, out float Out)
// 全非判断, Out=!A&&!B
void Nand(float A, float B, out float Out)
// 无穷数判断, Out = isinf(In)
void IsInfinite(float In, out float Out)
// 未知数判断, Out=(In<0.0||In>0.0||In==0.0)?0:1
void IsNan(float In, out float Out)
// 分支, Out=Predicate?True:False
void Branch(float Predicate, float4 True, float4 False, out float4 Out)
// 比较A和B的大小, 运算符可以选择: Equal、Not Equal、Less、Less Or Equal、Greater、Greater Or Equal
void Comparison(float A, float B, out float Out)
// 如果当前渲染正面则返回1,如果渲染背面则返回0
void IsFrontFaceNode(out float Out)

8.2 Custom Function(自定义函数)

        自定义函数节点允许用户通过脚本自定义节点的运算逻辑,官方介绍见→Custom Function Node。

        4.4 4)节提过,Shader Graph 13.1.9(2022.1+)版本才开始出现 Main Light Direction 节点,如果用户想在低版本的 Shader Graph 中获取灯光方向,可以通过 Custom Function 实现。下面将通过 Custom Function 实现 Main Light Direction 节点的功能。Shader Graph简介 中基于自定义的 Main Light 实现了漫反射光照效果。

        创建 Custom Function 节点,选中后,在 Node Settings 中配置如下,SHADERGRAPH_PREVIEW 用来判断是否是预览窗口。

#if SHADERGRAPH_PREVIEW
    Direction = half3(0.5, 0.5, 0);
    Color = half4(1, 0, 0, 1);
#else
    Light light = GetMainLight();
    Direction = light.direction;
    Color = light.color;
#endif

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu 安装 python

ubuntu 安装 python 初环境与设备查询是否安装安装python 本篇文章将介绍ubuntu 安装 python 初 希望能写一些简单的教程和案例分享给需要的人 环境与设备 系统&#xff1a;ubuntu 查询是否安装 因为系统也许会自带一个python&#xff0c;所以验证一下&#xff0c;如果自…

FPGA应用学习笔记----CORDIC 算法和小结

加减移位操作来运算三角函数&#xff0c;开根号&#xff0c;求对数 圆周旋转模式

【Uni-App】uview 开发多端应用,密码显示隐藏功能不生效问题

出现的问题&#xff1a; 使用uview组件u-input框密码绑定时会出现右侧密码显隐图标不显示的问题 思路&#xff1a; 1.看了下uview源码&#xff0c;发现这有一段注释&#xff0c;我们需要把源码修改一下&#xff0c;问题出在这里 这行代码修改为 :password"password || …

ChatGPT: 提升程序员开发效率的秘密武器!

引言 在现代软件开发中&#xff0c;时间和效率显得尤为重要。程序员们需要在尽可能短的时间内编写高质量的代码&#xff0c;并使之处于状态良好的维护周期。为满足这些需求&#xff0c;人工智能技术逐渐成为软件开发的一项核心能力。ChatGPT作为自然语言生成模型中的佼佼者&am…

K8S MetalLB LoadBalancer

1. 简介 kubernetes集群没有L4负载均衡&#xff0c;对外暴漏服务时&#xff0c;只能使用nodePort的方式&#xff0c;比较麻烦&#xff0c;必须要记住不同的端口号。 LoadBalancer&#xff1a;使用云提供商的负载均衡器向外部暴露服务&#xff0c;外部负载均衡器可以将流量路由…

面部表情识别(Pytorch):人脸检测模型+面部表情识别分类模型

目录 0 相关资料1 基于人脸检测面部表情分类识别方法2 项目安装2.1 平台与镜像2.2 项目下载2.3 模型下载2.4 上传待测试图片2.5 项目安装 3 demo测试 0 相关资料 面部表情识别2&#xff1a;Pytorch实现表情识别(含表情识别数据集和训练代码)&#xff1a;https://blog.csdn.net…

Java:正则表达式书写规则及相关案例:检验QQ号码,校验手机号码,邮箱格式,当前时间

正则表达式 目标:体验一下使用正则表达式来校验数据格式的合法性。需求:校验QQ号码是否正确&#xff0c;要求全部是数字&#xff0c;长度是(6-20&#xff09;之间&#xff0c;不能以0开头 首先用自己编写的程序判断QQ号码是否正确 public static void main(String[] args) {Sy…

camera hal|如何学习一个新平台

全网最具价值的Android Camera开发学习系列资料~ 作者:8年Android Camera开发,从Camera app一直做到Hal和驱动~ 欢迎订阅,相信能扩展你的知识面,提升个人能力~ 我自己目前从事的是android camera hal 的工作,工作上接触到的芯片平台要么是高通的,要么是mtk的。 其实…

shell脚本循环语句

shell脚本循环语句 一.echo命令二.查看当前系统的时间--date命令三.循环语句for四.while循环语句结构五.while循环语句结构&#xff08;迭代&#xff09;六.continue和break 一.echo命令 echo -n 表示不换行输出 echo -e输出转义符&#xff0c;将转义后的内容输出到屏幕上 常…

公文管理系统SSM+Activiti文档文件日志java jsp源代码

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 公文管理系统SSMActiviti 系统有1权限&#xff1a;管…

Jupyter并发测试以后出现EOFError marshal data too short

Jupyter 并发测试以后出现EOFError: marshal data too short 背景 由于项目需求需要用户能进行网页在线运行python代码程序&#xff0c;调研后决定使用Jupyter的服务接口实现此功能&#xff0c;目前使用docker进行容器化部署&#xff0c;测试针对次服务进行并发测试。测试并发…

k8s service

1、认识Service 程序在容器中、容器在Pod中&#xff0c;可以通过pod的ip来访问应用程序&#xff0c;但是podIP会随着创建销毁而改变。由此&#xff0c;Service出现&#xff1a; Service会对提供同一个服务的多个pod进行聚合&#xff0c;并且提供一个统一的入口地址。通过访问…

自学stm32,需要会到什么程度能找到一份工作?

学STM32&#xff0c;想要找到一份工作&#xff0c;需要具备以下基本条件和技能&#xff1a;掌握新建工程和调试工程的基本操作&#xff0c;熟悉使用官方的STM32CubeIDE等开发工具。熟悉C语言编程&#xff0c;理解基本的语法和编程概念&#xff0c;对汇编语言有一定了解。熟悉ST…

回归预测 | MATLAB实现基于PSO-LSSVM-Adaboost粒子群算法优化最小二乘支持向量机结合AdaBoost多输入单输出回归预测

回归预测 | MATLAB实现基于PSO-LSSVM-Adaboost粒子群算法优化最小二乘支持向量机结合AdaBoost多输入单输出回归预测 目录 回归预测 | MATLAB实现基于PSO-LSSVM-Adaboost粒子群算法优化最小二乘支持向量机结合AdaBoost多输入单输出回归预测预测效果基本介绍模型描述程序设计参考…

elementUI时间选择器el-time-picker的坑

//开始时间<el-time-pickerplaceholder"选择时间":format"HH:mm:ss" //显示的时间样式value-format"HH:mm:ss" //绑定值的样式 //不给默认为 Date 对象值&#xff1a;"2023-07-31T16:00:00.000Z"v-model"FormData.startTime&…

基于SpringBoot的旅游网站的设计与实现【附ppt|开题|万字文档(LW)和搭建文档

主要功能 前台界面&#xff1a; ①首页、旅游线路推荐、旅游资讯、线路搜索、查看更多等 ②旅游线路、度假旅游、探险考察、文化旅游、短程旅游、观光旅游、远程旅游、最新路线等 ③添加购物车、立即购买、评论、点我收藏等 ④个人中心、我的订单、我的地址、我的收藏、客服等…

如何保护员工安全、公司财产?劝你一定要试试这个技能!

在现代办公环境中&#xff0c;办公室视频监控正逐渐成为维护安全、管理风险和提升工作效率的重要工具。 办公室视频监控成为许多组织的一部分&#xff0c;它不仅有助于保护员工和财产&#xff0c;还能提供实时的信息和记录&#xff0c;以应对安全挑战和法规合规性要求。 客户案…

全国各城市-货物进出口总额和利用外资-外商直接投资额实际使用额(1999-2020年)

最新数据显示&#xff0c;全国各城市外商直接投资额实际使用额在过去一年中呈现了稳步增长的趋势。这一数据为研究者提供了对中国外商投资活动的全面了解&#xff0c;并对未来投资趋势和政策制定提供了重要参考。 首先&#xff0c;这一数据反映了中国各城市作为外商投资的热门目…

QMS质量管理系统是什么?

QMS质量管理系统是一种用于管理和优化企业质量管理的软件系统&#xff0c;在现代企业中&#xff0c;质量管理是非常重要的环节。 1. QMS系统的概念 QMS系统是一种用于管理和优化企业质量管理的软件系统。它可以帮助企业制定和实施质量管理策略、管理和控制质量过程、收集和分析…

分布式作业调度框架——ElasticJob

1、简介 ElasticJob 是面向互联网生态和海量任务的分布式调度解决方案&#xff0c;由两个相互独立的子项目 ElasticJob-Lite 和 ElasticJob-Cloud 组成。 它通过弹性调度、资源管控、以及作业治理的功能&#xff0c;打造一个适用于互联网场景的分布式调度解决方案&#xff0c;…