欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 金融 > Unity shader 语法入门

Unity shader 语法入门

2025/5/18 6:47:40 来源:https://blog.csdn.net/z2014z/article/details/144728891  浏览:    关键词:Unity shader 语法入门

简介

Shader 即着色器,是一种用于描述如何渲染图形和计算图形外观的程序
主要用于控制图形的颜色、光照、纹理和其他视觉效果

着色器通常由着色器语言编写,这些着色器语言提供了指令和语法,用于编写描述光照、纹理映射、阴影、反射等图形外观的代码

简单理解:Shader就是着色器,是用于编写图形表现效果程序代码 (可以类比理解为网页的CSS)

shader开发主要针对 几何阶段-顶点着色器光栅化阶段-片元着色器的数据进行自定义处理,进而决定最终的渲染效果

简单理解:通过Shader来处理数据,实现渲染效果

分类

unity中的3种shader

1、Fixed function shader:固定功能着色器,用于高级shader在老式显卡无法显示时的fallback。

2、Surface shader:表面着色器,unity推崇的shader类型,使用unity预制的光照模型来进行光照运算,只需要一个表面处理函数surf即可,使用CG/HLSL语法。

3、Vertex & Fragment shader:顶点&片段着色器,属于可编程渲染管线,使用CG/HLSL语法。

Shader程序的基本结构

shader 主要有三部分组成:Properties属性、N(N≥1)个子着色器、Fallback回滚。

Shader "Custom/myShader"{Properties{}SubShader{}Fallback "ShaderName"
}

属性,用来指定代码的输入数据;

子着色器是代码的主体,每一个子着色器中包含一个或者多个的Pass。在计算着色时,平台先选择最优先可以使用的着色器,然后依次运行其中的Pass,然后得到输出的结果;

回滚,保底手段,用来处理所有Subshader都不能运行时(比如目标设备实在太老,所有Subshader中都有其不支持的特性),会执行回滚中设置的 Shader 。ShaderName` 必须是系统提供或者自建存在的 shader,当有重名时考虑其目录名。

注:在实际开发过程中,主要在SubShader中编写代码

Shader程序实例

首先,新建一个Shader,可以在Project面板中找到,Create,选择Shader,然后将其命名为Diffuse Texture,打开刚才新建的Shader

代码如下:

Shader "Custom/Diffuse Texture" {Properties {_MainTex ("Base (RGB)", 2D) = "white" {}}SubShader {Tags { "RenderType"="Opaque" }LOD 200CGPROGRAM#pragma surface surf Lambertsampler2D _MainTex;struct Input {float2 uv_MainTex;};void surf (Input IN, inout SurfaceOutput o) {half4 c = tex2D (_MainTex, IN.uv_MainTex);o.Albedo = c.rgb;o.Alpha = c.a;}ENDCG} FallBack "Diffuse"
}

Properties 属性

Properties{}中定义着色器属性,定义的属性作为输入提供给所有的子着色器。

属性定义的语法:

_Name("Display Name", type) = defaultValue[{options}]

分别对应:名称、显示名称、属性类型、默认值

举例说明:

基础数据类型
类型描述示例
Color颜色类型,一个四维向量,主要前三维表示RGB 取值范围是在 0-1 之间。_Color("Color",Color) = (1,1,1,1)
VectorVector 向量类型,一般为四维向量,其取值是浮点类型。可以说 Color 是 Vector 的一个特例。_Vector("Vector",Vector) = (1,2,3,4)
IntInt 类型(整型),整数类型属性。_Int("Int",Int) = 40
FloatFloar 类型,浮点数类型属性。_Float("Float",Float) = 4.5
RangleRangle 类型,范围类型,用于指定属性的取值范围,其类型是浮点型。_Rangle("Rangle",Rangle(10,22)) = 11.5
特殊数据类型
类型描述示例
2D2D 类型,往往用于指定图片,纹理。 而不指定图片源,可以是设置的默认颜色。 注意颜色名是字符串。_2D("Texture",2D) = "red"{}
CubeCube 类型,是多个纹理图片组成的立方体6面,可以看作是 2D 类型的数组类型,往往多用于天空盒。_Cube("Cube",Cube) = "White"{}
3D3D类型 3D 纹理。_3D("3D",3D)="blue"{}

subShader 子着色器

一个或者多个子着色器SubShader(至少有一个),子着色器SubShader中含有一个或者多个通道Pass

Tags 标签

通过标签来决定何时以何种方式调用该着色器。

语法:

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

指定 TagName1 具有 Value1TagName2 具有 Value2。可根据需要添加任意数量的标签。

常用标签

1.Rendering Order - Queue tag

unity为了解决渲染顺序的问题,提供了渲染队列,unity内部使用整数索引表示每个渲染队列,索引越小越先渲染

** 名称**队列索引号描述
Background1000最先渲染,通常绘制作为背景的物体,如天空盒
Geometry
2000默认的队列,大部分不透明的物体使用这个队列
AlphaTest2450需要Alpha Test的物体使用此队列,单独处理是因为处理完不透明物体后进行alpha测试更高效
Transparent3000这个渲染队列是在**Geometry**
** AlphaTest**之后按从后往前的顺序渲染的。任何alpha混合(即着色器不写入深度缓冲)应该在这里(玻璃,粒子特效等)。
Overlay
4000这个渲染队列用于一些叠加效果。最后渲染的东西应该在这里(比如镜头光斑,后处理)。

使用示例:

Shader "Transparent Queue Example"
{SubShader{Tags { "Queue" = "Transparent" }Pass{// rest of the shader body...}}}

如果需要渲染的物体在这些队列之间,可以使用:

Tags { “Queue” = “Geometry+1” }

2.RenderType tag

RenderType标签将着色器分类为若干预定义组,例如是一个不透明的着色器,或alpha测试的着色器等。被用于着色器替换,或者在某些情况下用于生成相机的深度纹理。

所有Unity 内置的着色器,都设置了一个RenderType类型,便于渲染时的着色器替换。

内置的RenderType类型有:

类型描述
Opaque用于大多数着色器(法线着色器、自发光着色器、反射着色器以及地形的着色器)。
Transparent用于半透明着色器(透明着色器、粒子着色器、字体着色器、地形额外通道的着色器)。
TransparentCutout蒙皮透明着色器(Transparent Cutout,两个通道的植被着色器)。
Background天空盒着色器。
Overlay光晕着色器、闪光着色器。
TreeOpaque地形引擎中的树皮。
TreeTransparentCutout地形引擎中的树叶。
TreeBillboard地形引擎中的广告牌树。
Grass地形引擎中的草。
GrassBillboard地形引擎何中的广告牌草。
通用状态

LOD level of detail,表示着色器的细节层次效果

LOD valueShader name
100VertexLit
150Decal Reflective VertexLit
200Diffuse
250Diffuse Detail Reflective Bumped Unlit Reflective Bumped VertexLit
300Bumped Specular
400Bumped Specular
500Parallax
600Parallax Specular
Shader本体

shader 代码在 CGPROGRAM、ENDCG 两个标记中编写

CGPROGRAM
#pragma surface surf Lambertsampler2D _MainTex;struct Input {float2 uv_MainTex;
};void surf (Input IN, inout SurfaceOutput o) {half4 c = tex2D (_MainTex, IN.uv_MainTex);o.Albedo = c.rgb;o.Alpha = c.a;
}
ENDCG

编译指令

#pragma **surface** **surfaceFunction** **lightModel** [optionalparams]

  • surface - 声明的是一个表面着色器
  • surfaceFunction - 着色器代码的方法的名字
  • lightModel - 使用的光照模型。

lightModel光照模型

  • Lambert:该光照模型能很好的表示粗糙表面的光照,但不能表现出镜面反射高光
  • Toon:最近在游戏中常用的风格之一即是Toon shading(又称 cel shading).这是一种非逼真渲染风格,通过改变了光在一个模型上反射实际情况来给人以手绘的感觉
  • BlinnPhong:仿真镜面反射材料
  • Standard:Unity5中默认的光照模式是Standard, 其引入了 物理渲染 (PBR), 但是与其它光照模型没有什么不同。相比于朗伯反射, PBR提供了一个更加逼真的光线物体作用模型,PBR考虑了材料的物理属性, 比如能量守恒以及光的散射

sampler2D _MainTex;简单地理解,sampler2D就是GLSL中的2D贴图的类型,相应的,还有sampler1D,sampler3D,samplerCube等等格式。

_MainTex的声明,之前已经在Properties里声明过。用来实例的这个shader其实是由两个相对独立的块组成的,

外层的属性声明,回滚等等是Unity可以直接使用和编译的ShaderLab;

而在CGPROGRAM...ENDCG这样一个代码块中,这是一段CG程序。对于这段CG程序,要想访问在Properties中所定义的变量的话,必须使用和之前变量相同的名字进行声明

CG规定了声明为表面着色器的方法(这里是surf方法)的参数类型和名字,只能按照规定写,第一个参数是一个Input结构,第二个参数是一个inout的SurfaceOutput结构。

Input其实是需要去定义的结构,可以把所需要参与计算的数据都放到这个Input结构中,传入surf函数使用;

SurfaceOutput是已经定义好了数据类型的输出结构,但是初始其内容是空白的,需要向里面填写输出,这样就可以完成着色了。

常用的数据类型

3种基本数值类型:float、half和fixed。

这3种基本数值类型可以再组成vector和matrix,比如half3是由3个half组成、float4x4是由16个float组成。

float:32位高精度浮点数。

half:16位中精度浮点数。范围是[-6万, +6万],能精确到十进制的小数点后3.3位。

fixed:11位低精度浮点数。范围是[-2, 2],精度是1/256。

Sampler2D:2D纹理属性

float和vec都可以在之后加入一个2到4的数字,来表示被打包在一起的2到4个同类型数。

//Define a 2d vector variable
vec2 coordinate;
//Define a color variable
float4 color;
//Multiply out a color
float3 multipliedColor = color.rgb * coordinate.x;

INPUT结构体:

plain struct Input { 	float2 uv_MainTex; 
}; 

作为输入的结构体必须命名为Input,这个结构体中定义了一个float2的变量

默认的Input结构体中有一个uv_MainTex参数,代表了纹理的UV值。

SurfaceOutput结构体的定义如下

plain struct SurfaceOutput {     half3 Albedo;     //像素的颜色     half3 Normal;     //像素的法向值     half3 Emission;   //像素的发散颜色     half Specular;    //像素的镜面高光     half Gloss;       //像素的发光强度     half Alpha;       //像素的透明度 
}; 

surf函数

void surf (Input IN, inout SurfaceOutput o) {half4 c = tex2D (_MainTex, IN.uv_MainTex);o.Albedo = c.rgb;o.Alpha = c.a;
}

这里用到了一个tex2d函数,这是CG程序中用来在一张贴图中对一个点进行采样的方法,返回一个float4。

这里对_MainTex在输入点上进行了采样,并将其颜色的rbg值赋给输出的像素颜色,将a值赋给透明度。于是,着色器通过找到贴图上对应的uv点,直接使用颜色信息来进行着色

参考资料

猫都能学会的Unity3D Shader入门指南(一)

shader框架结构

Shader Tags整理

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词