Unity 内置渲染管线各个Shader的用途和性能分析,以及如何修改Shader(build in shader 源码下载)

所有Shader分析

路径:Standard

优点:

真实感:支持 PBR 渲染,能够呈现高质量的光照和材质效果。
灵活性:高度灵活,提供了多种可调参数,适应不同的需求。
跨平台兼容:广泛支持不同的硬件平台,特别是桌面和主流移动设备。
简化的开发流程:内置的预设和参数配置使得开发者可以快速实现材质效果,减少自定义代码的需求。

缺点:
性能开销:在低性能设备上可能会带来性能问题,尤其是移动设备或 AR/VR 设备。
不适合极端优化:在对性能要求极高的项目中,可能需要考虑更简化的着色器。
不支持高级特性:对于需要实时光线追踪、体积光、次表面散射等高级渲染特性的场景,可能需要使用 HDRP 等高级渲染管线。

路径:Nature/

优点

自然环境优化:Nature 路径下的着色器专门针对自然环境(如树木、草地、岩石、水面)进行了优化,能够提供非常真实的材质表现,提升自然景观的视觉效果。

性能优化:许多 Nature 着色器(如 TreeBillboardSoft 和 Grass Soft)都进行了性能优化,使用了如广告牌渲染和简化的光照模型等技术,以便在大规模场景中渲染大量的自然物体(如树木和草地)时减少性能开销。

高质量的材质表现:通过对光照、透明度、反射、折射等特性的处理,Nature 路径下的着色器能够在自然景观中呈现高质量的材质细节,尤其是在户外环境中具有很高的视觉吸引力。

简化的工作流程:Unity 已经为常见的自然环境材质(如树木、草地、水面等)提供了预制的着色器,开发者可以直接使用这些着色器,而不需要编写复杂的自定义着色器,快速开发自然环境。

缺点

局限性:尽管 Nature 路径下的着色器提供了很多优化,但它们的应用范围主要局限于自然环境材质,不适合用于所有类型的游戏或场景。例如,对于需要高度自定义效果或非常复杂的材质,开发者可能需要编写自定义着色器。

性能限制:在非常复杂的自然环境中,尽管这些着色器进行了优化,但如果场景中有大量树木、草地或水面,可能仍然会对性能造成一定压力,特别是在较低性能的硬件上。

不支持高级渲染特性:Nature 路径下的着色器虽然能够提供高质量的自然效果,但它们通常不支持如光线追踪、次表面散射(SSS)等高级渲染特性。如果项目需要这些特性,可能需要迁移到更复杂的渲染管线(如 HDRP)或者编写自定义着色器。

路径:UI/

常用

优点

专为 UI 渲染优化:这些着色器专门优化了 2D UI 元素的渲染,确保 UI 元素在不同的设备和平台上都能够高效渲染,且不会造成过多的性能损失。

易于使用:Unity 提供了多个 UI 专用的内置着色器,开发者不需要编写复杂的自定义着色器即可实现常见的 UI 效果,如按钮、文本、渐变、遮罩等。

支持多种视觉效果:UI 路径下的着色器能够支持多种常见的 UI 特效,如透明度、渐变、外轮廓、遮罩等,能有效提升 UI 的视觉层次感和交互体验。

透明度和层级支持:大部分 UI 着色器支持透明度控制和渲染顺序,适用于需要透明元素(如模糊背景、透明按钮)的应用。

性能优化:Unity 的 UI 着色器在设计时考虑了性能,尤其在渲染大量动态 UI 元素时能够高效工作。

缺点

不支持复杂材质:这些着色器通常不适用于复杂的 3D 渲染和材质效果。对于需要光照、反射等高级效果的 UI 元素,可能需要自定义着色器。

渲染性能问题:在复杂 UI 布局中,尤其是有大量透明元素或动态更新的元素时,UI 渲染性能可能会出现瓶颈,需要特别优化渲染顺序和透明度处理。

灵活性有限:虽然 Unity 提供了多个内置的 UI 着色器,但如果需要高度自定义的 UI 渲染效果,可能需要编写自定义的着色器来满足特定需求。

路径:Particles/

Particles/Standard Surface

主要特性
PBR支持:支持金属度(Metallic)、光滑度(Smoothness)、法线贴图(Normal Map)等PBR属性。

透明度支持:支持透明度混合(Alpha Blending)和透明度裁剪(Alpha Clipping)。

粒子系统优化:针对粒子系统的渲染需求进行了优化,适合用于复杂的粒子效果。

光照支持:支持实时光照和阴影(取决于粒子系统的设置)。

使用场景
高质量粒子效果:当需要粒子效果具有真实的材质表现(如金属、玻璃、烟雾等)时,可以使用此Shader。

复杂光照环境:在需要粒子与场景光照交互(如反射、阴影)时,此Shader是一个不错的选择。

透明效果:适合需要透明度混合或裁剪的粒子效果(如火焰、烟雾、魔法特效等)。

Particles/Standard Unlit

主要特性
不受光照影响:粒子颜色完全由材质和纹理决定,不参与场景光照计算。

透明度支持:支持透明度混合(Alpha Blending)和透明度裁剪(Alpha Clipping)。

颜色叠加:支持粒子系统的颜色叠加(Color Over Lifetime、Color by Speed等)。

纹理动画:支持纹理动画(Texture Sheet Animation),用于实现帧动画效果。

高性能:由于不参与光照计算,性能开销较低,适合移动设备或大量粒子效果。

使用场景
2D粒子效果:如烟雾、火焰、魔法特效等。

UI特效:如按钮点击特效、过渡动画等。

背景特效:如星空、飘雪等不需要光照的场景。

移动设备:由于性能开销低,适合在移动设备上使用。

路径:Unlit/

Unlit/Texture

最简单的Unlit Shader,仅显示纹理,不受光照影响。

用途:显示2D纹理或颜色。

Unlit/Color

显示纯色,不受光照影响。

用途:显示单一颜色的物体。

Unlit/Transparent

支持透明度混合(Alpha Blending)的Unlit Shader。

用途:显示透明物体,如UI元素、烟雾等。

Unlit/Transparent Cutout

支持透明度裁剪(Alpha Clipping)的Unlit Shader。

用途:显示镂空效果,如树叶、栅栏等。

Unlit/Texture (Supports Lightmap)

支持光照贴图的Unlit Shader。

用途:在不受实时光照影响的情况下,使用光照贴图烘焙的光照信息。

Unlit/Detail

支持细节纹理的Unlit Shader。

用途:在基础纹理上叠加细节纹理,适合地面、墙壁等。

路径:Mobile/

Mobile 路径下的着色器是针对移动设备进行优化的。这些着色器通常计算简单,旨在提供快速的渲染性能,适应移动设备的性能和内存限制。下面是 Mobile 路径下常见着色器的详细分析,包括每个着色器的用途和特点。

Mobile/Diffuse

✅ 漫反射光照
✅ 使用Lambertian漫反射模型,计算简单,适合低性能设备。
✅ 支持主纹理和颜色
✅ 可以设置基础纹理(Main Texture)和颜色(Color)。
✅ 高性能
✅ 由于光照计算简单,性能开销非常低,适合移动设备或大量物体的渲染。
✅ 无高光反射
✅ 不支持高光反射(Specular),仅计算漫反射。

使用场景
移动设备:在性能受限的设备上运行,如移动设备或WebGL。
简单场景:适用于不需要复杂光照效果的场景,如背景物体、低多边形风格的游戏。
大量物体:当场景中有大量物体需要渲染时,使用Mobile/Diffuse可以提高性能。

Mobile/Bumped Diffuse

漫反射光照

✅ 使用Lambertian漫反射模型,计算简单,适合低性能设备。
✅ 支持法线贴图
✅ 通过法线贴图增强表面细节,使材质看起来更加真实。
✅ 高性能
✅ 虽然支持法线贴图,但光照计算仍然较为简单,适合移动设备。
✅ 无高光反射
✅ 不支持高光反射(Specular),仅计算漫反射。

使用场景
移动设备:在性能受限的设备上运行,如移动设备或WebGL。
需要表面细节的场景:适用于需要简单凹凸效果的材质,如砖墙、岩石等。
大量物体:当场景中有大量物体需要渲染时,使用Mobile/Bumped Diffuse可以在性能和效果之间取得平衡。

Mobile/Skybox

✅ 高性能
✅ 专为移动设备优化,性能开销低。
✅ 支持立方体贴图(Cubemap)
✅ 使用立方体贴图作为天空盒的纹理。
✅ 无光照计算
✅ 天空盒不受场景光照影响,仅显示纹理颜色。
✅ 简单易用
✅ 配置简单,适合快速实现天空盒效果。

使用场景
移动设备:在性能受限的设备上运行,如移动设备或WebGL。
背景环境:用于显示天空、山脉、城市等背景环境。
快速原型开发:在需要快速实现天空盒效果时使用。

Mobile/Unlit (Supports Lightmap)

✅ 不受实时光照影响
✅ 不参与实时光照计算,颜色和纹理直接显示。
✅ 支持光照贴图
✅ 使用烘焙的光照贴图来增强场景的光照效果。
✅ 高性能
✅ 由于不进行实时光照计算,性能开销较低,适合移动设备。
✅ 透明度支持
✅ 支持透明度混合(Alpha Blending)和透明度裁剪(Alpha Clipping)。

使用场景
移动设备:在性能受限的设备上运行,如移动设备或WebGL。
静态场景:适用于使用光照贴图烘焙的静态场景。
背景物体:如建筑物、地形等不需要实时光照的物体。
UI元素:如按钮、图标、文字等。

Mobile/VertexLit

✅ 仅按顶点光照进行渲染
✅ 非半透渲染效果。
✅ 没有其他额外光源时,可以使用更加快速的

Mobile/VertexLit (Only Directional Lights)

Mobile/Particles/Additive

  • 特点

✅ 高性能:相比标准 Particles/Additive,减少了计算量,适合移动端。
✅ 加法混合:粒子颜色会叠加到背景上,使亮度增强。
✅ 不受光照影响:粒子的颜色不会因光照变化,始终保持亮度。
✅ 支持颜色 Tint:可以通过 Color 属性调整粒子颜色。
✅ 支持纹理:可以使用 MainTex 来控制粒子的外观。

  • 渲染方式

Mobile/Particles/Additive 使用 加法混合(Additive Blending),适用于需要高亮度叠加的粒子效果:
混合公式:
源颜色 * 源Alpha + 目标颜色 * 1
解释:
粒子的颜色(源颜色) 直接 加到背景颜色上,形成亮度叠加效果。
不会变暗,而是会随着粒子重叠变得更亮。
透明度(Alpha)影响亮度,而不是影响可见度。
适用于火焰、爆炸、激光、光效,但 不适用于烟雾、阴影等需要透明过渡的效果。
深度写入(ZWrite)关闭:

ZWrite Off 避免了深度缓冲写入,防止粒子相互遮挡问题(但可能会导致重叠粒子排序错误)。

  • 适用场景

适用情况 说明
火焰 ✅ 适合,亮度叠加可以增强燃烧感
爆炸 ✅ 适合,碎片和火光可以不断增加亮度
魔法光效 ✅ 适合,高亮粒子适用于魔法技能特效
能量波 ✅ 适合,强光波动效果
烟雾 ❌ 不适合(应该使用 Alpha Blended,否则烟雾会发光)
阴影粒子 ❌ 不适合(应该使用 Multiply,否则阴影会变亮)

Mobile/Particles/Alpha Blended

  • 特点
    ✅ 高性能:相比标准 Particles/Alpha Blended,减少了计算量,适合移动端。
    ✅ Alpha 混合:支持透明度渐变,使粒子可以自然融入场景。
    ✅ 不受光照影响:粒子的颜色不会因光照变化,适用于固定亮度的效果。
    ✅ 支持颜色 Tint:可以通过 Color 属性调整粒子颜色。
    ✅ 支持纹理:可以使用 MainTex 来控制粒子的外观
  • 渲染方式

Mobile/Particles/Alpha Blended 采用 透明度混合(Alpha Blending),可以创建柔和的过渡效果:
混合公式:
源颜色 * 源Alpha + 目标颜色 * (1 - 源Alpha)
解释:
粒子的颜色(源颜色) 会与 背景颜色(目标颜色) 混合。
Alpha 控制透明度,值越低越透明,值越高越不透明。
适用于柔和过渡的透明粒子(如烟雾、魔法光效、能量波等)。
深度写入(ZWrite)关闭:

  • 适用场景
    烟雾 ✅ 适合,透明度混合可使烟雾渐变
    魔法光效 ✅ 适合,透明度可调整,适合能量光波
    半透明能量场 ✅ 适合,可以叠加多个粒子获得自然效果
    火焰 ❌ 不适合(通常用 Additive 以增加亮度)
    阴影粒子 ❌ 不适合(通常用 Multiply 以与背景融合)

ZWrite Off 避免了深度缓冲写入,防止粒子相互遮挡问题(但可能会导致重叠粒子排序错误)。

Mobile/Particles/VertexLit Blended

  • 特点
    ✅ 性能优化:比 Particles/VertexLit Blended 更高效,适合移动设备。
    ✅ 支持光照:逐顶点光照(Vertex Lit),比逐像素光照(Pixel Lit)计算更快。
    ✅ Alpha 混合:可以用于 半透明粒子(如烟雾、魔法光效等)。
    ✅ 支持纹理:可以使用 MainTex 来控制粒子的外观。
    ✅ 不支持法线贴图:因为是逐顶点光照,不计算法线贴图。
  • 混合模式(Alpha Blending)

Mobile/Particles/VertexLit Blended

使用 Alpha 混合 来渲染粒子,使其可以 半透明:
混合公式:
源颜色 * 源Alpha + 目标颜色 * (1 - 源Alpha)
公式解释:
颜色由 粒子颜色(源颜色) 和 背景颜色(目标颜色) 叠加得到。
Alpha 控制透明度,值越低越透明,值越高越不透明。
适用于透明粒子效果(如烟雾、魔法、能量光效)。

  • 适用场景

光照影响的烟雾 ✅ 适合,光照会影响粒子的亮度和阴影
光照影响的魔法特效 ✅ 适合,可以受光源影响变亮
半透明能量场 ✅ 适合,支持透明度渐变
火焰 ❌ 不适合(通常用 Additive 以增加亮度)
阴影粒子 ❌ 不适合(通常用 Multiply 以与背景融合)

Mobile/Particle/Multiply

  • 特点:

✅优化移动设备性能:比标准 Particles/Multiply 更高效,减少 GPU 计算量,适合低端设备。
✅乘法混合模式(Multiply Blending):
公式:输出颜色 = 源颜色 × 目标颜色
✅颜色被相乘后通常会变暗,因此适用于 阴影、污渍、光照效果等。
✅无光照影响:不会受场景光照影响,适用于需要始终保持相同颜色表现的粒子效果。
✅支持透明度(Alpha):可以控制粒子的透明度,使其能够渐隐消失。

  • Multiply 混合模式的工作原理:

在 Multiply Blending 中,粒子颜色与背景颜色相乘,得到更暗的颜色。

白色(1,1,1) × 背景颜色 = 背景颜色(无影响)
灰色(0.5,0.5,0.5) × 背景颜色 = 暗色背景
黑色(0,0,0) × 背景颜色 = 全黑(隐藏)
示例:

如果粒子颜色是 50% 灰色(0.5, 0.5, 0.5),而背景是 红色(1, 0, 0),
计算结果是 深红色(0.5, 0, 0)。
这样,粒子就会与背景自然融合,看起来像是阴影或光照效果。

  • 适用场景

烟雾(Smoke) ✅ 适合,使烟雾颜色与背景混合变暗
阴影(Shadows) ✅ 可用于投射阴影的效果
污渍(Dirt, Stains) ✅ 适合,模拟污渍与地面融合
火焰(Fire) ❌ 不适合(通常用 Additive 着色器)
光晕(Glow) ❌ 不适合(通常用 Alpha Blended)

对比
在这里插入图片描述

路径:FX/

用于特效的Shader,如屏幕扭曲、光晕等。

路径:GUI/

用于GUI元素的Shader。

路径:Skybox/

建议用Mobile/Skybox
优点

逼真的效果:Skybox 着色器能够为场景提供非常真实的背景效果,尤其是程序化生成的天空或立方体贴图。
高效渲染:Skybox 着色器非常高效,因为它们通常在场景渲染的最后一步渲染,且不会与场景中的其他物体交互。
支持动态效果:通过程序化的 Skybox/Procedural,可以实现日夜变化、云层变化等动态效果,提升视觉效果的沉浸感。

缺点

性能开销:如果使用程序生成的天空(如 Skybox/Procedural),计算复杂的云层、光照、太阳位置等可能会对性能产生影响。
纹理质量要求高:对于 Skybox/6 Sided 和 Skybox/Cubemap 来说,需要高分辨率的纹理来保证视觉效果,否则可能会出现分辨率低、失真等问题。
无法交互:天空盒是一个背景对象,通常不会与其他物体发生交互,因此无法直接模拟如反射、阴影等与物体的互动效果。

路径:Sprites/

优点

性能优化:精灵着色器通常非常轻量级,特别是 Sprites/Default 这样的着色器,它能够高效地处理大量 2D 精灵渲染。
灵活性:支持透明度、颜色修改和简单的光照效果,适合常见的 2D 游戏场景。
简单易用:大多数精灵渲染只需要 Sprites/Default 即可,减少了开发和优化的复杂度。

缺点

不支持复杂的光照和反射:对于 2D 游戏,精灵渲染大多不支持复杂的光照、反射和阴影效果,这对于某些需要更复杂渲染的场景可能不够用。
适用于 2D 精灵:这些着色器专为 2D 渲染设计,不适合用于 3D 渲染的场景或物体。

路径:Legacy Shaders/

Legacy就是遗留的意思,老木乃伊了,非必要不用,Particles路径下的shader的优化版都在Mobile/Particles,适用于桌面设备或较旧的 Unity 项目,支持较为复杂的光照和粒子效果,但性能可能不适合移动设备。

用Mobile替换Legacy,有些虽然shader名字一样,会少一些属性,比如缺少Color,如果还想要,就需要修改这个Shader了

如何修改自带Shader

因为直接在unity里是看不到源码也无法修改的,当需要给默认shader增加需求,比如增加颜色或者修改ui的渲染顺序等等,我们需要先拿到shader源文件

下载Build in shader源文件方法
gitHub
https://github.com/liwanx/Unity-Built-in-Shaders
gitee
https://gitee.com/liwanx/Unity-Built-in-Shaders
你用什么版本的unity 就可以从那个大版本里拿你要的shader
比如修改
在这里插入图片描述
通常在DefaultResourcesExtra文件下找到Sprites-Default,复制到unity中

改下外部名字Custom_××
在这里插入图片描述

再改下内部路径Custom/××,
在这里插入图片描述
保存之后就可以在这里找到了
在这里插入图片描述

然后就可以开始实现需求

最后附上Shader结构

// Shader 的路径名称  默认为文件名,也可以与文件名不同
Shader "Unlit/HiShader"
{
    // 属性 
    // Material Inspector显示的所有参数都在需要在这里进行声明
    Properties
    {
        // 通常所有属性名都以下划线字符开头 _MainTex
        _MainTex ("Texture", 2D) = "white" {}
                                            
        // 比较常见的属性类型
        // ————————————————————————————————————————————————
        _Integer ("整数(新版)", Integer) = 1
        _Int ("整数(旧版)", Int) = 1
        _Float ("浮点数", Float) = 0.5
        _FloatRange ("浮点数滑动条", Range(0.0, 1.0)) = 0.5
        // Unity包含以下内置纹理, 可以直接填充
        // “white”(RGBA:1,1,1,1)
        // “black”(RGBA:0,0,0,1)
        // “gray”(RGBA:0.5,0.5,0.5,1)
        // “bump”(RGBA:0.5,0.5,1,0.5)
        // “red”(RGBA:1,0,0,1)
        _Texture2D ("2D纹理贴图", 2D) = "red" {}
        // 字符串留空或输入无效值,则它默认为 “gray”
        _DefaultTexture2D ("2D纹理贴图", 2D) = "" {}
        // 默认值为 “gray”(RGBA:0.5,0.5,0.5,1)
        _Texture3D ("3D纹理贴图", 3D) = "" {}
        _Cubemap ("立方体贴图", Cube) = "" {}
        // Inspector会显示四个单独的浮点数字段
        _Vector ("Example vector", Vector) = (0.25, 0.5, 0.5, 1)
        // Inspector会显示拾色器拾取色彩RGBA值
        _Color("色彩", Color) = (0.25, 0.5, 0.5, 1)
        // ————————————————————————————————————————————————
                                            
        // 除此之外 属性声明还可以具有一个可选特性 用来告知Unity如何处理它们
        // HDR可以使色彩亮度的值超过1
        [HDR]_HDRColor("HDR色彩", Color) = (1,1,1,1)
        // Inspector隐藏此属性
        [HideInInspector]_Hide("看不见我~", Color) = (1,1,1,1)
        // Inspector隐藏此纹理属性的Scale Offset字段
        [NoScaleOffset]_HideScaleOffset("隐藏ScaleOffset", 2D) = "" {}
        // 指示纹理属性为法线贴图,如果分配了不兼容的纹理,编辑器则会显示警告。
        [Normal]_Normal("法线贴图", 2D) = "" {}
    }
                                        
    // 子着色器 
    // 一个Shader至少有一个或者多个子着色器SubShader,这些子着色器互不干扰,且只有一个会运行
    // 在加载shader时Unity会遍历所有SubShader列表,并最终选择用户机器支持的第一个
    SubShader
    {
        // 可以通过Tags来向子着色器分配标签
        // 只可以写在SubShader语块内,不可写在Pass内
        /* 以键值对的形式存在,可以出现多个键值对
            Tags { 
                "TagName1" = "Value1"
                "TagName2" = "Value2"
                "TagName3" = "Value3"
                ...
                 }
        */
                                            
        // RenderPipeline: 声明子着色器是否与通用渲染管线 (URP) 或高清渲染管线 (HDRP) 兼容
        // 仅与 URP 兼容
        // Tags { "RenderPipeline"="UniversalRenderPipeline" }
        // 仅与 HDRP 兼容
        // Tags { "RenderPipeline"="HighDefinitionRenderPipeline" }
        // RenderPipeline不声明或任何其他值表示与 URP 和 HDRP 不兼容
        // ————————————————————————————————————————————————
                                            
        // Queue: 声明渲染队列
        // Tags { "Queue"="Background" } 
        // 最早被调用的渲染,用来渲染天空盒或者背景
        // Tags { "Queue"="Geometry" }   
        // 这是默认值,用来渲染非透明物体(普通情况下,场景中的绝大多数物体应该是非透明的)
        // Tags { "Queue"="AlphaTest" }  
        // 用来渲染经过Alpha Test的像素,单独为AlphaTest设定一个Queue是出于对效率的考虑
        // Tags { "Queue"="Transparent" }
        // 以从后往前的顺序渲染透明物体
        // Tags { "Queue"="Overlay" }    
        // 用来渲染叠加的效果,是渲染的最后阶段(比如镜头光晕等特效)
        // ————————————————————————————————————————————————
                                            
        // RenderType: 用来区别这个Shader要渲染的对象是属于什么类别的。
        // 设置渲染类型 用一种称为着色器替换的技术在运行时交换子着色器,用来区别这个Shader要渲染的对象是属于什么类别的
        // 这里表示非透明物体渲染
        Tags { "RenderType"="Opaque" }
        // 更多详细内容可参考官网文档 https://docs.unity.cn/cn/2021.3/Manual/SL-SubShaderTags.html
                                            
        // LOD (Level of Detail)
        // 视频中仅为LOD名词概念介绍,Shader中的LOD属性有一定的区别
        // 更多详细内容可参考官网文档 https://docs.unity3d.com/Manual/SL-ShaderLOD.html
        LOD 100
                                    
        // 每个子着色器由多个通道组成,许多简单的着色器只使用一个通道,但想要一些更复杂的效果,着色器可能需要更多通道
        // 一个Pass就是一次绘制,可以看成是一个Draw Call而Pass的意义在于多次渲染,
        // 如果你有一个Pass,那么着色器只会被调用一次,如果你有多个Pass的话,
        // 那么就相当于执行多次SubShader了,这就叫双通道或者多通道。
                                            
        // Draw Call:其实就是CPU调用图像编程接口的渲染命令,CPU每次调用DrawCall,都需要向GPU发送许多数据啊、渲染状态等等,
        // 一旦CPU执行完应用阶段,GPU就会开始执行这次的渲染流程。而GPU渲染的速度比CPU提交命令的速度要快的多,
        // 所以如果DrawCall数量过多的情况下,CPU需要进行大量的计算,进而就会导致CPU过载,影响游戏的运行效率。
        Pass
        {
            CGPROGRAM
            // 声明顶点着色器
            #pragma vertex vert
            // 声明像素着色器
            #pragma fragment frag
            // 使雾生效
            #pragma multi_compile_fog
                                    
            // 引用CG的核心代码库
            #include "UnityCG.cginc"
                                    
            // 应用程序阶段结构体
            struct appdata
            {
                // 参考:https://docs.microsoft.com/zh-cn/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics
                // POSITION 着色器语言的语义,用来限定着色器的输入输出值的类型
                // 模型空间的顶点坐标
                float4 vertex : POSITION;
                // 模型的第一套UV坐标
                float2 uv : TEXCOORD0;
            };
                                    
            struct v2f
            {
                // UV
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                // SV_POSITION 当这个值需要作为输出值输出给系统用的时候 前面需要加SV_前缀
                // 当然因为有向下兼容的机制 不加也没啥太大问题
                float4 vertex : SV_POSITION;
            };
                                    
            // 在Properties中声明的参数要在这里相对应的定义后才可以使用
            sampler2D _MainTex;
            float4 _MainTex_ST;
                                    
            // 定义顶点着色器函数 函数名要与声明顶点着色器名称相同
            v2f vert (appdata v)
            {
                v2f o;
                // 将顶点坐标从模型空间变换到裁剪空间
                o.vertex = UnityObjectToClipPos(v.vertex);
                // Transforms 2D UV by scale/bias property
                // #define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)
                // 等价于v.uv.xy * _MainTex_ST.xy + _MainTex_ST.zw;
                // 简单来说,TRANSFORM_TEX主要作用是拿顶点的uv去和材质球的tiling和offset作运算,
                // 确保材质球里的缩放和偏移设置是正确的
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                                                                        
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }
                                    
            // SV_Target可以视为COLOR ,虽说他也是作为输出值输出给系统的
            // 但它其实是告诉系统把输出的颜色值存储到RenderTarget中
            // 所以这里我们用SV_Target
            fixed4 frag (v2f i) : SV_Target
            {
                // 采样2D纹理贴图
                fixed4 col = tex2D(_MainTex, i.uv);
                // 应用雾
                UNITY_APPLY_FOG(i.fogCoord, col);
                // 返回经过处理后的最终色彩
                return col;
            }
            ENDCG
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李万兴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值