UnityShader——基础篇之UnityShader基础

UnityShader基础

UnityShader概述

材质和UnityShader

  总的来说,在Unity中需要配合使用材质(Material)和 Unity Shader 才能达到需要的效果,常见流程为:

  • 创建一个材质
  • 创建一个 Unity Shader,并把它赋给上一步中创建的材质
  • 把材质赋给需要渲染的对象
  • 在材质面板中调整 Unity Shader 的属性,以得到满意的效果

在这里插入图片描述

  Unity Shader定义了渲染所需的各种代码(如顶点着色器和片元着色器)、属性(如使用哪些纹理等)和指令(渲染和标签设置等)

  材质允许调节这些属性,将其最终赋给对应的模型

Unity 中的材质

  Unity 中的材质需要结合一个 GameObject 的 Mesh 或者 Particle systems 组件来工作,它决定了游戏对象看起来是什么样子的(也需要 Unity Shader 的配合)

  创建一个新的材质,可以在 Unity 的菜单栏中选择 Assets -> Create -> Material 来创建,也可以直接在 Project 视图中右击 -> Create -> Material 来创建

  当创建了一个材质后,就可以把它赋值给一个对象,这可以通过把材质直接拖拽到 Scene 视图中的对象来实现,或者在该对象的 Mesh Renderer 组件中直接赋值,如图:

在这里插入图片描述

  在 Unity 的 2020.x 版本中,默认情况下,一个新建的材质将使用Unity内置的 Standard Shader,这是一种基于物理渲染的着色器

  Unity的材质和许多建模软件(如 Cinema 4D、Maya 等)中提供的材质工鞥呢类似,他们都提供了一个面板来调整材质的各个参数,这种可视化的方法使得开发者不再需要自行在代码中设置和改变所需的各种参数,如图:

在这里插入图片描述

Unity 中的 Shader

  创建一个新的 Unity Shader,可以在 Unity 的菜单栏中选择 Assets -> Create -> Shader 来创建,也可以直接在 Project 视图中右击 -> Create -> Shader 来创建,Unity 一共提供了5种 Unity Shader 模板供选择 —— Shader Surface Shader, Unlit Shader, Image Effect Shader, Compute Shader 以及 Ray Tracing Shader。

  Standard Surface Shader 会产生一个包含了标准光照模型的表面着色器模板

  Unlit Shader会产生一个不包含光照(但包含雾效)的基本的顶点/片元着色器

  Image Effect Shader 为实现各种屏幕后处理效果提供了一个基本模板

  Compute Shader 会产生一种特殊的 Shader 文件,这类 Shader 旨在利用 GPU 的并行性来进行一些常规渲染流水线无关的计算

  Ray Tracing Shader是一种用于Unity中的实时光线追踪的Shader。光线追踪是一种通过追踪从相机到场景中各个像素的光线的技术,以模拟光线在真实世界中的传播和反射。Ray Tracing Shader可以帮助开发者实现更加逼真的光影效果,包括实时反射、折射、阴影和环境光照等效果。


  一个单独的 Unity Shader 是无法发挥任何作用的,它必须和材质结合起来。

  所以,可以在材质面板最上方的下拉菜单中选择需要使用的 Unity Shader,当选择完毕后,材质面板中就会出现该 Unity Shader 可用的各种属性。这些属性可以是颜色、纹理、浮点数、滑动条(限制了范围的浮点数)、向量等

  当把材质赋给场景中的一个对象,就可以看到调整属性所发生的视觉变化


  Unity Shader本质上就是一个文本文件,和 Unity 中的很多外部文件类似,Unity Shader 也有导入设置(Import Settings)面板,在 Project视图中选中某个 Unity Shader即可看到,如图:

在这里插入图片描述

  在该面板上,可以在 Default Maps 中指定该 Unity Shader 使用的默认纹理。当任何材质第一次使用该 Unity Shader 时,这些纹理就会自动被赋予到相应的属性上。在下方的面板中,Unity 会显示出和该 Unity 相关的信息,例如它是否是一个表面着色器(Surface Shader)、是否是一个固定函数着色器(Fixed Function Shader)等,还有一些信息是和在 Unity Shader 中的标签设置有关,例如是否会投射阴影、使用的渲染队列、LOD值等

  对于表面着色器来说,可以通过单击 Show generated code 按钮来打开一个新的文件,在该文件里将显示 Unity 在背后为该表面着色器生成的顶点/片元着色器。这可以方便对这些生成的代码进行修改(需要复制到一个新的 Unity Shader 中才可保存)和研究

  如果 Unity Shader 使一个固定函数着色器,在 Fixed function 的后面也会出现一个 Show generated code 按钮,来查看该固定函数着色器生成的顶点/片元着色器。Compile and show code 下拉列表可以让开发者检查该 Unity Shader 针对不同图像编程接口(例如 OpenGL、D3D9、D3D11等)最终编译成的 Shader 代码,如图所示:

在这里插入图片描述

  直接单击该按钮可以查看生成的底层的汇编指令。可以利用这些代码来分析和优化着色器

  除此之外,Unity Shader 的导入面板还可以方便地查看其使用的渲染队列(Reder queue)、是否关闭批处理(Disable batching)、属性列表(Properties)等信息

Unity Shader 的基础:ShaderLab

什么是 ShaderLab

  Unity Shader 是 Unity 为研发者提供的高层记得渲染抽象层,Unity 希望以这种方式来让开发者更加轻松的控制渲染,见下图:

在这里插入图片描述

  在 Unity 中,所有的 Unity Shader 都是使用 ShaderLab 来编写的

  ShaderLab 是 Unity 编写 Unity Shader 的一种说明性语言,它使用了一些嵌套在花括号内部的**语义&&(syntax)来描述一个 Unity Shader 文件的结构,这些结构包含了许多渲染所需的数据,例如 Properties 语句块中定义了着色器所需的各种属性,这些属性将会出现在材质面板中

  从设计上来说,ShaderLab 类似于 CgFX 和 Direct3D Effects(FX)语言,他们都定义了要显示一个材质所需的所有东西,而不仅仅是着色器代码

  一个 Unity Shader 的基础结构如下所示:

Shader "ShaderName"{Properties{//属性}SubShader{//显卡A使用的子着色器}SubShader{//显卡B使用的子着色器}Fallback "VertexLit"
}

UnityShader的结构

给Shader起名字

  每个Unity Shader文件的第一行都需要通过 Shader 语义来制定该 Unity Shader 的名字,这个名字由一个字符串来定义

  当为材质选择使用的 Unity Shader 时,这些名称就会出现在材质面板的下拉列表里,通过在字符串中添加斜杠(“/”),可以控制 Unity Shader 在材质面板中出现的位置,如下:

Shader "Unlit/001Shader"{}

  那么,这个 Unity Shader在材质面板中的位置就是:Shader -> Unlit -> 001Shader,如图:

在这里插入图片描述

材质和 Unity Shader 的桥梁:Properties

  Properties语义块中包含了一系列属性(property),这些属性将会出现在材质面板中

  Properties语义块的定义通常如下:

Properties{Name("display name",PropertyType) = DefaultValueName("display name",PropertyType) = DefaultValue//更多属性
}

  开发者声明这些属性是为了在材质面板中能够方便的调整各种材质属性

  如果需要在 Shader 中访问它们,就需要使用每个属性的名字(Name),Unity中,这些属性的名字通常由一个下划线开始,显示的名称(display name)则是出现在材质面板上的名字,需要为每个属性指定它的类型(PropertyType),常见的属性如表:

属性类型默认值的定义语法例子
Intnumber_Int(“Int”,Int) = 2
Floatnumber_Float(“Float”,Float) = 1.5
Range(min,max)number_Range(“Range”,Range(0.0,5.0) = 3.0
Color(number,number,number,number)_Color(“Color”,Color) = (1,1,1,1)
Vector(number,number,number,number)_Verctor(“Vector”,Vector) = (2,3,6,1)
2D“defaulttexture”{}_2D(“2D”,2D) = “”{}
Cube“defaulttexture”{}_Cube(“Cube”,Cube) = “white”{}
3D“defaulttexture”{}_3D(“3D”,3D) = “black”

  除此之外,还需要为每个属性指定一个默认值,在第一次把该 Unity Shader 赋给某个素材时,菜盒子面板显示的就是这些默认值

    对于 Int、Float、Range ,这些数字类型的属性,其默认值就是一个单独的数;

    对于 ColorVector 这类属性,默认值是用圆括号包围的一个四维向量;

    对于 2D、Cube、3D 这3种纹理类型,默认值的类型稍微复杂,他们的默认值是通过一个字符串后跟一个花括号来指定的,其中,字符串要么是空的,要么是内置的纹理名称,如 “white”“black”“gray” 或者 “bump”。或括号的用处原本是用于制定一些纹理属性的。

  如果需要控制固定管线的纹理坐标的生成,就需要再顶点着色器中编写计算相应纹理坐标的代码

  如下方的代码:

Shader "Unlit/001Shader"
{Properties{_Int("Int",int) = 2_Float("Float",float) = 1.5_Range("Range",range(0.0,5.0)) = 1.0_Color("Color",Color) = (1,1,1,1)_Vector("Vector",Vector) = (2,3,6,1)_2D("2D",2D) = ""{}_Cube("Cube",Cube) = "white"{}_3D("3D",3D) = "black"{}}FallBack "diffuse"
}

  材质面板中的显示结果,如图:

在这里插入图片描述

  Unity 允许重载默认的材质编辑面板,以提供更多自定义的数据类型

  为了在 Unity 中可以访问到这些属性,需要在 Cg 代码片中定义和这些属性类型相匹配的变量,需要说明的是,即使不在 Properties 语义块中生命这些属性,也可以直接在 Cg 代码片中定义变量

  此时,可以通过脚本向 Shader 中换地这些属性,因此,Properties与一块的作用仅仅是为了让这些属性可以出现在材质面板中

SubShader

  每一个 Unity Shader 文件可以包含多个 SubShader 语义块,但最少要有一个。

    当 Unity 需要加载这个 Unity Shader 时,Unity 会扫描所有的 SubShader 语义块,然后选择第一个能够在目标平台运行的SubShader

    如果都不支持的话,Unity 就会使用 Fallback 语义指定的 Unity Shader

  Unity 提供这种语义的原因在于,不同的显卡具有不同的能力。例如:一些旧的显卡仅能支持一定数目的操作指令,而一些更高级的显卡可以支持更多的指令数

  那么就希望在旧的显卡上使用计算复杂度低的着色器,在高级的显卡上使用计算复杂度较高的着色器,以便提供更出色的画面

  SubShader 语义块中包含的定义通常如下

SubShader{//可选Tags//可选RenderSetupPass{}//Other Passes
}

  SubShader 中定义了一系列 Pass 以及可选的状态(RenderSetup)和标签(Tags)设置。

  每个 Pass 定义了一个完整的渲染流程,但如果 Pass 数目过多,往往会造成渲染性能的下降

  因此,应该尽量使用最小数目的 Pass,状态和标签同样可以在 Pass 声明,不同的是,SubShader 中的一些标签是特定的

  也就是说,这些标签设置和 Pass 中使用的标签是不一样的,对于状态设置来说,使用的语法是相同的

  但是如果在 SubShader 进行了这些设置,呢么将会用于所有的 Pass

  状态设置

  ShaderLab 提供了一系列渲染状态的设置指令,这些指令可以设置显卡的各种状态,例如是否开启混合/深度测试等

  ShaderLab 中常见的渲染状态设置选项如下表:

状态名称设置指令解释
CullCull Back|Front|Off设置剔除模式:剔除背面/正面/关闭剔除
ZTestZTest Less Greater|LEqqual|GEqual|Equal|NotEqual|Always设置深度测试时使用的函数
ZWriteZWrite On|Off开启/关闭深度写入
BlendBlend SrcFactor DstFactor开启并设置混合模式

  当在 SubShader 块中设置了上述渲染状态时,将会应用到所有的 Pass,如果不想这样(如在双面渲染中,希望第一个 Pass 中剔除正面来对背面进行渲染,在第二个 Pass 中剔除背面来对正面进行渲染),可以在 Pass 语义块中单独进行上面的设置

  SubShader的标签

  SubShader 的标签(Tags)是一个键值对(Key/Value Pair),它的键和值都是字符串类型,这些键值对是 SubShader 和渲染引擎之间的沟通桥梁。它们用来告诉 Unity 的渲染引擎希望怎样以及何时渲染这个对象:

  标签的结构如下:

Tags{"TagName1" = "Value1" "TagName2" = "Value2"}

  SubShader 的标签快支持的标签类型如表:

标签类型说明例子
Queue控制渲染顺序,指定该物体属于哪一个渲染队列,通过这种方式可以保证所有的透明物体可以在所有不透明物体后面被渲染,也可以自定义使用的渲染队列来控制物体的渲染顺序Tags{“Queue” = “Transparent”}
RenderTyep对着色器进行分类,例如这是一个不同明德着色器,或是一个透明的着色器等,这可以被用于着色器替换(Shader Replacement)功能Tags{“renderType”=“Opaque”}
DisableBatching一些 SubShader 在使用 Unity 的批处理功能时会出现问题,例如使用了模型空间下的坐标进行顶点动画,这是可以通过该标签来直接指明是否对该 SubShader 使用批处理Tags{“DisableBatching” = “True”
ForceNoShadowCasting控制使用该 SubShader 的物体是否会投射阴影Tags{“ForceNoShadowCasting”=“True”
IgnoreProjector如果该标签为"True",那么使用该 SubShader 的物体将不会受 Projector 的影响,通常用于半透明物体Tags{“IgnoreProjector”=“True”}
CanUseSpriteAtlas当该 SubShader 是用于精灵(sprite)时,将该标签设置为"False"Tags{“CanUseSpriteAtlas”=“False”
PreviewType知名材质面板将如何预览改材质。默认情况下,材质将显示为一个球形,可以通过把这些标签的值设为"Plane""SkyBox"来改变预览类型Tags{“PreviewType”=“Plane”}

  需要注意的是,上述标签仅可以在 SubShader 中声明,而不可以在 Pass 块中声明。Pass 块虽然也可以定义标签,但这些标签是不同于 SubShader 的标签类型

  Pass 语义块

  Pass 语义块包含的语义如下:

Pass{NameTagsRenderSetup
}

  首先,可以在 Pass 中定义该 Pass 的名称,例如:

Name "MyPassName"

  通过这个名称,可以使用 ShaderLab 的 UsePass 命令来直接使用其他 UnityShader 中的 Pass,例如:

UsePass "MyShader/MYPASSNAME"

  这样可以提高代码的复用性,需要注意的是,由于 Unity 内部会把所有 Pass 的名称转换成大写字母的表示,因此,在使用 UsePass 命令时必须使用大写形式的名字

  其次,可以对 Pass 设置渲染状态。SubShader 的状态设置同样适用于 Pass。除了上面提到的状态设置外,在 Pass 中我们还可以使用固定管线的着色器命令

  Pass 同样可以设置标签,但它的标签不同于 SubShader 的标签,这些标签也是用于告诉渲染引擎希望怎样来渲染该物体

  Pass 中使用的标签类型如下表:

标签类型说明例子
LightMode定义该 Pass 在 Unity 的渲染流水线中的角色Tags{“LightMode”=“ForwardBase”}
RequireOptions用于指定当满足某些条件时才渲染该 Pass,它的值是一个由空格分割的字符串。Tags{“RequireOptions”=“SoftVegetation”}

  除了上面普通的 Pass 定义外,UnityShader 还支持一些特殊的 Pass,以便进行代码复用或实现更复杂的效果:

    UsePass:如之前提到的一样,可以使用该命令来复用其他 UnityShader 中的 Pass

    GrabPass:该 Pass 负责抓取屏幕并将结果存储在一张纹理中,以用于后续的 Pass 处理

Fallback

  紧跟在各个 SubShader 语义块后面的,可以是一个 Fallback 指令,它用于告诉 Unity,“如果上面所有的 SubShader 在这块显卡上都不能运行,那么就是用这个最低级的 Shader”

  它的语义如下:

Fallback "name"
//或者
Fallback Off

  如上所述,可以通过一个字符串来告诉 Unity 这个“最低级的 UnityShader”是谁,也可以关闭 Fallback 功能,但一旦这么做,那么意思就是“如果一块显卡跑不了上面所有的 Shader,那就不管他了”

  例子如下:

Fallback "VertexLit"

  事实上,Fallback还会影响阴影的投射

  在渲染阴影纹理时,Unity 会在每个 UnityShader 中寻找一个阴影投射的 Pass,通常情况下,不需要自己专门实现一个 Pass,这是因为 Fallback 使用的内置 Shader 中包含了这样一个通用的 Pass,因此,为每个 UnityShader 正确设置 Fallback 是非常重要的

ShaderLab还有其他的语义吗

  除了上述的语义,还有一些不常用到的寓意。

  例如:如果不满足于 Unity 内置的属性类型,想要自定义材质面板的编辑界面,就可以使用 CustomEditor 语义来拓展编辑界面。还可以使用 Category 语义来对 UnityShader 中的命令进行分组。

UnitySahder 的形式

  尽管 UnityShader 可以做的事情很多(例如设置渲染状态等),但其最重要的任务还是指定各种着色器所需的代码。这些着色器代码可以写在 SubShader 语义块中(表面着色器的做法),也可以写在 Pass 语义块中(顶点/片元着色器和固定函数着色器的做法)

  在 Unity 中,可以使用下面 3 种形式来编写 UnityShader,而不管使用哪种形式,真正意义上的 Shader 代码都需要包含在 ShaderLab 语义块中,如下所示:

Shader "MyShader"{Properties{//所需的各种属性}SubShader{//真正意义上的 Shader 代码会出现在这里//表面着色器{Surface Shader}或者//顶点/片元着色器{Vertex/Fragment Shader}或者//固定函数着色器{Fixed Function Shader}}SubShader{//和上一个 SubShader 类似}
}

表面着色器

  表面着色器(Surface Shader) 是 Unity 自己创造的一种着色器代码类型,他需要的代码量很少,Unity 在背后做了很多工作,渲染的代价比较大。

  本质上和顶点/片元着色器是一样的,当给Unity提供一个便面着色器的时候,在背后仍旧需要把它装换成对应的顶点/片元着色器

  它的价值在于:Unity 处理了很多光照细节,不需要去操心这些“烦人的事情”

  示例代码如下:

Shader "Custom/Simple Surface Shader"{SubSHader{Tags{"RenderType"="Opaque"}CGPROGAM#pragma surface surf Lambertstruct Input{float4 color : COLOR;};void surf(Input IN,inout SurfaceOutput o){o.Albedo = 1;}ENDCG}Fallback "Diffuse"
}

  表面着色器被定义在 SubShader 语义块(不是 Pass 语义块)中的 CGPROGRAM 和 ENDCG 之间

  原因是表面着色器不需要开发者关心使用多少个 Pass,每个 Pass 如何渲染等问题,Unity 会在背后做好这些事情

  CGPROGRAM 和 ENDCG 之间的代码是使用 Cg/HLSL 编写的,也就是说,需要把 Cg/HLSL 语言嵌套在 ShaderLab 语言中

  这里的 Cg/HLSL 是 Unity 经封装后提供的,它的语法和标准的 Cg/HLSL 语法几乎一样,但还是有细微的不同

顶点/片元着色器

  Unity 中可以使用 Cg/HLSL 语言来编写顶点/片元着色器(Vertex/Fragment Shader)。它们更加复杂,但灵活性更高

  示例代码如下:

Shader "Custom/Simple VertexFragment Shader"{SubShader{Pass{CGPROGRAM#progama vetex vert#pragma fragment fragfloat4 vert(float4 v : POSITION) : SV_POSITON{return mul(UNITY_MATRIX_MVP,v);}fixed4 frag() : SV_Target{return fixed4(1.0,0.0,0.0,1.0);}ENDCG}}
}

  顶点/片元着色器的代码需要定义在 CGPROGRAM 和 ENDCG 之间,不同的是,顶点/片元着色器是写在 Pass 语义块内,而非 SubShader内的

  这样的原因是,需要自己定义每个 Pass 需要使用的 Shader 代码,虽然可能需要编写更多的代码,但好处是灵活性很高,更重要的是,可以空时渲染的实现细节

固定函数着色器

  对于一些较旧的设备(其GPU仅支持 DirectX 7.0、OpenGL 1.5 或 OpenGL ES 1.1),它们不支持可编程管线着色器,因此,这时候就需要使用固定函数着色器(Fixed Function Shader) 来完成渲染。这些着色器网网址可以完成一个非常简单的效果

  示例代码如下:

Shader "Tutorial/Basic"{Properties{_Color("Main Color",Color} = {1,0.5,0.5,1}}SubShader{Pass{Material{Diffuse [_Color]}}}
}

  固定着色器的代码被定义在 Pass 语义块中,这些代码相当于 Pass 中的一些渲染设置

  对于固定函数着色器来说,需要完全使用 ShaderLab 的语法(使用 ShaderLab 的渲染设置命令)来编写,而不是使用 Cg/HLSL

  由于现在绝大多数 GPU 都支持可编程的渲染管线,这种编程方式已经被逐渐抛弃,在新版的 Unity 中,所有固定函数着色器都会在背后被 Unity 编译成对应的顶点/片元着色器

选择哪种 UnityShader 形式

  如果有非常明确的需求必须要使用固定函数着色器,否则使用可编程管线的着色器,即表面着色器或顶点/片元着色器

  如果要和各种光源打交道,可能更需要使用表面着色器,但需要小新在移动平台中的性能表现

  如果需要使用的光照数目非常少,那么使用顶点/片元着色器使一个更好的选择

  如果有很多自定义的渲染效果,使用顶点/片元着色器

其他的一些问题

UnityShader != 真正的Shader

  尽管UnityShader翻译过来就是Unity着色器,在Unity里,UnityShader实际上指的就是一个ShaderLab文件——硬盘上以.shader作为文件后缀的一种文件

  在UnityShader里,可以做的事情远多于一个传统意义上的Shader

    传统的Shader中,仅可以编写特定类型的Shader,例如顶点着色器、片元着色器等,在UnityShader中,可以在同一个文件里同时包含需要的顶点着色器和片元着色器代码

    在传统的Shader中,无法设置一些渲染设置,例如是否开启混合、深度测试等,这些是开发者在另外的代码中自行设置的。而在UnityShader中,通过一行特定的指令就可以完成这些设置

    在传统的Shader中,我们需要编写荣昌的代码来设置着色器的输入和输出,要小心的处理这些输入输出的位置对应关系等。而在UnityShader中,只需要在特定的语句块中生命一些属性,就可以依靠材质来方便的改变这些属性。而且对于模型自带的数据(如定点位置、纹理坐标、法线等),UnityShader也提供了直接访问的方法,不需要开发者自行编码来传给着色器

  UnityShader出了上述这些优点外,也有一些缺点。

    由于UnityShader的高度封装性,可以编写的Shader类型和语法都被限制了。对于一些类型的Shader,例如曲面细分着色器(Tessellation Shader)、几何着色器(Geometry Shader)等,Unity的支持就相对差一些。例如:Unity 4.x 仅在 DirectX 11平台下提供曲面细分着色器、几何着色器的相关功能,而对于OpenGL平台则没有这些支持。除此之外,一些高级的Shader语法UnityShader也不支持

  可以说,UnityShader提供了一种让开发者同时控制渲染流水线中多个阶段的一种方式,不仅仅是提供Shader代码。作为开发者而言,绝大部分时候只需要和UnityShader打交道,而不需要关心渲染引擎底层的实现细节

UnityShader和Cg/HLSL之间的关系

  UnityShader是用ShaderLab语言编写的,但对于表面着色器和顶点/片元着色器,可以在ShaderLab内部嵌套Cg/HLSL语言来编写这些着色器代码。这些Cg/HLSL代码是嵌套在 CGPROGRAM 和 ENDCG 之间的。由于Cg和DX9风格的HLSL从写法上来说几乎是同一种语言,因此在Unity里Cg和HLSL是等价的。可以说,Cg/HLSL代码是区别于ShaderLab的另一个世界

  通常,Cg的代码片段是位于Pass语义块内部的,如下所示

Pass{//Pass的标签和状态设置CGPROGRAM//编译指令,例如:#pragma vertex vert#pragma fragment frag//Cg代码ENDCG//其他一些设置
}

  在提供给编程人员这些便利的背后,Unity编辑器会把这些Cg片段编译成低级语言,如汇编语言等。同城,Unity会自动把这些诶Cg片段编译到所有相关平台(这里的平台是指不同的渲染平台,如Dirext3D 9、OpenGL、Direct3D 11、OpenGL ES等)上。这些编译过程比较复杂,Unity会使用不同的编译器来吧Cg转换成对应平台的代码。这样就不会在切换平台时再重新编译,而且如果代码在某些平台上发生错误就可以立刻得到错误信息。

  可以在UnityShader的导入设置面板上查看这些编译后的代码,查看这些代码有助于进行Debug或优化等

  如图:

在UnityShader的导入设置面板中可以通过Compile and show code按钮来查看Unity对Cg片段编译后的代码,通过单击Compile and show按钮右侧的倒三角可以打开下拉菜单,在这个下拉菜单中可以选择变异的平台种类,如职位当前的显卡设备编译特定的汇编代码,或为所有的平台编译汇编代码,也可以自定义选择编译到哪些平台上
  但当发布游戏的时候,游戏数据文件中质保函目标平台需要的编译代码,而那些在目标平台上不需要的代码部分就会被移除。例如,当发布到Mac OS X平台上时,DirectX对应的代码部分就会被移除。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android模拟器linux内核的下载,编译,运行,驱动开发测试

Android模拟器linux内核的下载,编译,运行,内核模块开发 1.下载适合Android模拟器的内核 git clone https://aosp.tuna.tsinghua.edu.cn/android/kernel/goldfish.git git branch -a git checkout android-goldfish-4.14-gchips 新建一个目录…

【2024最新版】Java JDK安装配置全攻略:图文详解

目录 1. 引言2. 准备工作2.1 **确定操作系统**2.2 **检查系统要求**2.3 **下载JDK安装包**3. 安装步骤(以Windows系统为例)4. 配置环境变量4.1 jdk配置验证4.2 **配置JAVA_HOME环境变量**4.3 **配置Path环境变量**4.4 验证jdk是否配置成功 5. 结语 1. 引…

机器学习周记(第四十四周:Robformer)2024.6.17~2024.6.23

目录 摘要ABSTRACT1 论文信息1.1 论文标题1.2 论文摘要1.3 论文引言1.4 论文贡献 2 论文模型2.1 问题描述2.2 Robformer2.2.1 Encoder2.2.2 Decoder 2.3 鲁棒序列分解模块2.4 季节性成分调整模块 摘要 本周阅读了一篇利用改进 Transformer 进行长时间序列预测的论文。论文模型…

浅析MySQL-基础篇01

目录 执行一条select语句,发生了什么? MYSQL执行流程是怎么样的? 第一步:连接器 第二步:查询缓存 第三步:解析SQL 解析器 第四步:执行SQL 预处理器 优化器 执行器 执行一条select语句…

Temu(拼多多跨境电商) API接口:获取商品详情

核心功能介绍——获取商品详情 在竞争激烈的电商市场中,快速、准确地获取商品数据详情对于电商业务的成功至关重要。此Temu接口的核心功能在于其能够实时、全面地获取平台上的商品数据详情。商家通过接入Temu接口,可以轻松获取商品的标题、价格、库存、…

Day15 —— 大语言模型简介

大语言模型简介 大语言模型基本概述什么是大语言模型主要应用领域大语言模型的关键技术大语言模型的应用场景 NLP什么是NLPNLP的主要研究方向word2vecword2vec介绍word2vec的两种模型 全连接神经网络神经网络结构神经网络的激活函数解决神经网络过拟合问题的方法前向传播与反向…

什么是REST API

1. 什么是RESTful API REST API,全称 Representational State Transfer,最初由计算机科学家 Roy Fielding 提出。 是遵循 REST 架构规范的应用编程接口(API),支持与 RESTful Web 服务进行交互。 又被称作 RESTful API…

深度神经网络——深度学习中的 RNN 和 LSTM 是什么?

引言 自然语言处理和人工智能聊天机器人领域许多最令人印象深刻的进步都是由 递归神经网络(RNN) 和长短期记忆(LSTM)网络。 RNN 和 LSTM 是特殊的神经网络架构,能够处理顺序数据,即按时间顺序排列的数据。…

《Python 机器学习》作者新作:从头开始构建大型语言模型,代码已开源

ChatGPT狂飙160天,世界已经不是之前的样子。 更多资源欢迎关注 自 ChatGPT 发布以来,大型语言模型(LLM)已经成为推动人工智能发展的关键技术。 近期,机器学习和 AI 研究员、畅销书《Python 机器学习》作者 Sebastian …

Mac M3 Pro 部署Trino-server-449

目录 1、下载安装包 2、解压并设置配置参数 3、启动并验证 4、使用cli客户端连接测试 1、下载安装包 官方:trino-server-449 CLI 网盘: server https://pan.baidu.com/s/16IH-H39iF8Fb-Vd14f7JPA?pwd3vjp 提取码: 3vjp cli https://pan.baidu.…

计算机网络 动态路由OSPF

一、理论知识 1.OSPF基本概念 ①OSPF是一种链路状态路由协议,使用Dijkstra算法计算最短路径。 ②OSPF使用区域(Area)来组织网络,区域0(Area 0)是主干区域。 ③路由器通过通告直连网络加入OSPF域。 ④反…

Ubuntu磁盘映射到本地磁盘

远程服务器是 Ubuntu 系统,本地是 windows 系统。 1、安装 samba 服务器 sudo apt update sudo apt install samba smbclient通过如下命令可以看到已经安装成功 $ whereis sambaoutput: samba: /usr/sbin/samba /usr/lib/x86_64-linux-gnu/samba /etc/samba /usr…

CentOS 7、Debian、Ubuntu,这些是什么意思

CentOS 7、Debian、Ubuntu 都是基于 Linux 内核的操作系统,它们各自有不同的特性和用途。以下是对它们的详细解释: CentOS 7 CentOS(Community ENTerprise Operating System) 是一个基于开源的 Linux 发行版。CentOS 7 是 CentOS …

如何在Qt Designer中管理QSplitter

问题描述 当按下按钮时,我希望弹出一个对话框,用户可以在其中选择内容并最终按下 ‘Ok’ 按钮。我想在这个对话框中放置一个 QSplitter,左侧面板将显示树状结构,右侧将显示其他内容。如何正确实现这一点? 从 Qt 的示…

【Mac】KeyKey — Typing Practice for mac软件介绍及安装

软件介绍 KeyKey 是一款为 macOS 设计的盲打练习软件,旨在帮助用户提高打字速度和准确性。它通过提供多种练习模式和实时反馈,使用户能够逐渐掌握触摸打字技能。以下是 KeyKey 的主要功能和特点: 主要功能和特点 多语言支持: …

python---OpenCv(二),背景分离方法较有意思

目录 边界矩形 旋转矩形(最小外接矩形): 计算轮廓 找4个点的坐标 把浮点型转为Int 画轮廓 边界矩形--(最大外接矩形) 转灰度 找轮廓 找顶点 画矩形 显示 背景分离方法(这个很好玩,可以识别在动的物体) 边…

泛微E9与金蝶云星空ERP的无缝集成案例详解(包括接口与字段)

业务系统现状 背景介绍 泛微E9和金蝶云星空ERP是两款广泛应用与企业管理的信息系统,分别在移动办公自动化和企业资源计划管理领域占据重要地位。然而企业在使用这些系统时往往面临着信息孤岛和系统孤立的问题,导致数据无法在不系统之间高效流转共享。 当…

qml:导入B站Up主的FluentUI插件

文章目录 文章介绍如何加载1、下载代码2、官方文档和组件介绍 运行FluentUI新建自己的qml项目,并导入FluentUI调用组件,展示效果图 文章介绍 up主“会磨刀的小猪”模仿微软Fluent风格写的界面,可以理解为用qt和qml写出的win10/win11风格的界…

Ubuntu 之Glade图形化设计器

演示环境说明:本机使用Windows 11 家庭版本搭载 Ubuntu 22.04.4 LTS 子系统,同时并安装Ubuntu桌面虚拟化软件XLaunch。 如果没有搭建好上述问题,请参考:windows11子系统Ubuntu 22.04.4子安装图形化界面 Glade是什么?…

im即时通讯软件系统,私有化部署国产化信创适配安全可控

私有化部署IM即时通讯软件系统是许多企业为了确保数据安全、控制隐私保护、提升灵活性而考虑的重要选择之一。信创适配安全可控是企业在私有化部署IM即时通讯软件系统时需要关注的关键点。本文将探讨私有化部署IM即时通讯软件系统的意义、信创适配的重要性,以及如何…