自学shader中,shader的api不好找啊。自己整理整理 万一以后有用呢~(未完待续)
写在前面
这篇文章是我自己在网上找的其他人的文章,总结归纳了一下。我也是刚开始学写shader,可能会有地方写的不对,如果看到我文章的大佬知道那里出错,麻烦指出,我一定虚心改正。该文章仅供参考!仅供参考!仅供参考!。
ShaderGraph节点库
当有不知道怎么调用api的时候参考ShaderGraph的节点库中的代码解释,秒懂。。
shaderGraph节点库
小技巧
小技巧001
先用ShaderGraph连连线,实现的差不多之后,再用代码翻译过来,会学的比较快诶!就跟抄答案一样。
Shader结构
Shader "文件路径/文件名"
{
//属性面板
Properties
{
//包含在Inspector中可配置的各种属性
//贴图
_Texture2D("Texture2D", 2D) = "white" {}
//颜色
_Color("Color", Color) = (1,1,1,1)
}
//子着色器
SubShader
{
//标签 设置当前子着色器的基本属性 例如渲染管线、渲染顺序、渲染模式等
Tags
{
"RenderPipeline"="UniversalRenderPipeline"
}
//一个Pass就是渲染一次模型
Pass
{
//URP代码片段 从 HLSLPROGRAM开始到ENDHLSL结束
HLSLPROGRAM
//顶点着色器
#pragma vertex vert
//片元着色器
#pragma fragment frag
//需要引入的文件
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
//模型数据
struct Attributes
{
float4 posOS : POSITION;
float2 uv : TEXCOORD0;
};
//
struct Varyings
{
float2 uv : TEXCOORD0;
float4 posHCS : SV_POSITION;
};
//采样
TEXTURE2D(_Texture2D);
SAMPLER(sampler_Texture2D);
//C-Buffer
CBUFFER_START(UnityPerMaterial)
float4 _Texture2D_ST;
half4 _Color;
CBUFFER_END
//顶点着色器
Varyings vert(Attributes IN)
{
Varyings OUT;
OUT.posHCS = TransformObjectToHClip(IN.posOS.xyz);
OUT.uv = TRANSFORM_TEX(IN.uv, _Texture2D);
return OUT;
}
//片元着色器
half4 frag(Varyings IN) : SV_Target
{
return SAMPLE_TEXTURE2D(_Texture2D, sampler_Texture2D, IN.uv) * _Color;
}
//结束代码片段
ENDHLSL
}
}
}
Properties中的写法
变量名(“inspector中显示的名称”,类型) = 默认值
_Texture2D("Texture2D", 2D) = "white" {}
2D贴图
_Texture2D("Texture2D", 2D) = "white" {}
贴图之类的需要在默认值后面加个{}
Rect贴图
_Rect("Rect Tex",Rect) = "white" {}
Cube贴图 (天空盒)
_Cube("Cube Tex",Cube) = "" {}
颜色
_Color("Color", Color) = (1,1,1,1)
浮点数
_Float("Float",float) = 0
滑动条
_Range("Range",Range(0,1)) = 0.5
四元数 Vector
_Vector("Vector",Vector)=(0,0,0,0)
Tag中的写法
RenderPipeline 渲染管道
使用URP渲染
"RenderPipeline"="UniversalRenderPipeline"
需要搭配下列代码一起使用,include后面会详解 这里给个示例
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
除设置渲染管线外
tag包括两部分,一部分是SubShader中,一部分在Pass中。
这部分是腾讯学堂找到的,原文直通车:https://gameinstitute.qq.com/community/detail/121997
SubShader中Tag
Queue (渲染顺序)
参数 | 默认值 |
---|---|
Background | 1000 |
Geometry | 2000(不写的话默认是这个) |
AlphaTest | 2450 |
Transparent | 3000 |
Overlay | 4000 |
Tags{
"Queue"="Geometry"
}
RenderType (渲染类型)
参数 | 默认值 |
---|---|
Opaque:不透明(法线、自发光、反射、地形Shader) | |
Transparent | 半透明(透明、粒子、字体、地形添加通道Shader) |
TransparentCutout | 遮罩透明(透明裁切、双通道植物Shader) |
Background | 天空盒Shader |
Overlay | GUI纹理、光晕、闪光Shader |
TreeOpaque | 地形引擎——树皮 |
TreeTransparentCutout | 地形引擎——树叶 |
TreeBillboard | 地形引擎——公告牌(始终面向摄像机)式树木 |
Grass | 地形引擎——草 |
GrassBillboard | 地形引擎——公告牌(始终面向摄像机)式草 |
Tags{
"RenderType"="Opaque"
}
DisableBatching (是否禁用Batch(打包、合并))
参数 | 默认值 |
---|---|
True | 禁用 |
False | 不禁用(默认) |
LODFading | 当LOD fade开启的时候禁用,一般用在树木上面 |
Tags{
"DisableBatching" = "True"
}
ForceNoShadowCasting (是否强制不投射阴影)
当这个值为True的时候,使用这个Shader的对象便不会投射阴影。
一般用于透明对象,或者不想继承其他shader阴影的时候。
参数 | 默认值 |
---|---|
True | 禁用 |
False | 不禁用(默认) |
Tags{
"ForceNoShadowCasting" = "False"
}
IgnoreProjector 无视投影器
当这个值为True的时候,对象便不受投射器影响。
一般用于半透明对象,因为让投射器影响它们不是什么好事情。
CanUseSpriteAtlas 可使用精灵集
当这个值为False的时候,不能使用精灵集。
PreviewType 材质的预览形式
默认显示为球体,可以使用Plane(2D平面)或Skybox(天空盒)
Pass中Tag
(还没用过,先记下吧)
LightMode (光照模式)
有位大佬解释的挺详细的,直通车https://blog.csdn.net/qq_39574690/article/details/105743236
参数 | 默认值 |
---|---|
Always | 总是渲染,不使用光照 |
ForwardBase | 用于前向渲染,使用环境光、主平行光、顶点/SH(球谐函数)光照以及光照贴图 |
ForwardAdd | 用于前向渲染,额外使用每像素光,每个光照一个通道 |
Deferred | 用于延迟着色,渲染G-Buffer |
ShadowCaster | 渲染对象的深度到阴影贴图或者深度纹理 |
PrepassBase | 用于(旧版)延迟光照,渲染法线和高光指数 |
PrepassFinal | 用于(旧版)延迟光照,合并贴图、光照和自发光来渲染最终色彩 |
Vertex | 当对象不受光照贴图影响的时候,用来渲染(旧版)顶点发光。使用所有的顶点光照 |
VertexLMRGBM | 当对象接受光照贴图影响的时候,用来渲染(旧版)顶点发光。适用于使用RGBM编码光照贴图的平台(PC&主机) |
VertexLM | 当对象接受光照贴图影响的时候,用来渲染(旧版)顶点发光。适用于使用double-LDR编码光照贴图的平台(移动平台) |
Tags{
"LightMode"="Always"
}
PassFlags
标志渲染管线如何传递数据给通道
OnlyDirectional:只有主平行光、环境光和光照探测器的数据会传递给通道
仅用于LightMode为ForwardBase
RequireOptions
标志通道至于在某些外部条件满足时才会被渲染
SoftVegetation:当Quality Setting中的Soft Vegetation选项被开启时,才会渲染通道
SubShader相关
SubShader
每个shader文件中至少有一个SubShader,它标记了针对某种显卡的渲染方式,当一个shader文件被使用的时候,显卡会找到改文件中的所有SubShader块,如果所有的SubShader都不能执行,则会使用Fallback 标记的shader。
每个SubShader中至少有一个Pass块
结构如下
Shader "ShaderName"{
SubShader{//针对显卡A
Pass{
//xxx
}
}
SubShader{//针对显卡B
Pass{
//xxx
}
}
SubShader{//针对显卡C
Pass{
//xxx
}
}
Fallback "Lit"
}
多pass模式
给Pass设置不同的LightMode可实现多Pass,URP最多是3个Pass。
原理还没看,想研究的话自行百度。
下面是简单示例。应该能看懂
SubShader
{
Tags
{
"RenderPipeline"="UniversalRenderPipeline"
}
//OutLine 描边Pass
Pass
{
Tags
{
"LightMode" = "SRPDefaultUnlit"
}
}
Pass
{
Tags
{
"LightMode" = "UniversalForward"
}
}
Pass
{
Tags
{
"LightMode" = "LightweightForward"
}
}
}
include 引入包
类型 | 包名 |
---|---|
Core | Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl |
Light | Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl |
Shadow | Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl |
其他有用的:
包名 |
---|
Packages/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl |
Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl |
Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl |
Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl |
Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl |
Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl |
Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareOpaqueTextue.hlsl |
Pass
{
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
}
摘抄自https://www.cnblogs.com/kexiaohao/p/16638070.html
Cull (表面剔除)
Cull Off 不剔除
Cull Back(默认)剔除背面(内表面)
Cull Front 剔除正面(外表面)
Pass
{
Cull Off
}
HLSLPROGRAM->ENDHLSL
应该是标记代码块,告诉引擎是用什么写的代码
Pass
{
HLSLPROGRAM
ENDHLSL
}
#pragma
告诉Unity哪个函数包含了顶点着色器的代码,哪个函数包含片元着色器的代码。
#pragma vertex name
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDHLSL
}
顶点/片元着色器函数
shader中的坐标转换函数
内置的变换矩阵
参数名 | 对应的方法名 | 解释 |
---|---|---|
UNITY_MATRIX_MVP | 当前的模型x观察x投影矩阵,用于将顶点/方向矢量从模型空间变换到裁剪空间 | |
UNITY_MATRIX_MV | 当前的模型x观察矩阵,用于将顶点/方向矢量从模型空间变换到观察空间 | |
UNITY_MATRIX_V | GetWorldToViewMatrix() | 当前的观察矩阵,用于将顶点/方向矢量从世界空间变换到观察空间 |
UNITY_MATRIX_P | GetViewToHClipMatrix() | 当前的投影矩阵,用于将顶点/方向矩阵从观察空间变换到裁剪空间 |
UNITY_MATRIX_VP | GetWorldToHClipMatrix() | 当前的观察x投影矩阵,用于将顶点/方向矢量从世界空间变换到裁剪空间 |
UNITY_MATRIX_T_MV | UNITY_MATRIX_MV的转置矩阵 | |
UNITY_MATRIX_IT_MV | UNITY_MATRIX_MV的逆转置矩阵,用于将法线从模型空间变换到观察空间,也可用于得到UNITY_MATRIX_MV的逆矩阵 | |
_Object2World/UNITY_MATRIX_M | GetObjectToWorldMatrix() | 当前的模型矩阵,用于将顶点/方向矢量从模型空间变换到世界空间 |
_World2Object | GetWorldToObjectMatrix() | _Object2World的逆矩阵,用于将顶点/方向矢量从世界空间变换到模型空间) |
摘抄自Unity Shader入门精要(冯乐乐 著)
变换矩阵封装好的方法
顶点变化
函数名 | 解释 |
---|---|
float3 TransformObjectToWorld(float3 positionWS) | 模型空间->世界空间 |
float3 TransformWorldToObject(float3 positionOS) | 世界空间->模型空间 |
float3 TransformWorldToView(float3 positionWS) | 世界空间->观察空间 |
float4 TransformObjectToHClip(float3 positionOS) | 模型空间->世界空间->裁剪空间(将位置从对象空间转换为同质空间)效果与上面MVP相同,但比MVP更高效 |
float4 TransformWorldToHClip(float3 positionWS) | 世界空间->裁剪空间(将位置从世界空间转换为同质空间) |
float4 TransformWViewToHClip(float3 positionVS) | 观察空间->裁剪空间(将位置从视图空间转换为同质空间) |
方向变化
函数名 | 解释 |
---|---|
float3 TransformObjectToWorldDir(float3 dirOS, bool doNormalize = true) | 模型空间->世界空间 |
float3 TransformWorldToObjectDir(float3 dirWS, bool doNormalize = true) | 世界空间->模型空间 |
real3 TransformWorldToViewDir(real3 dirWS, bool doNormalize = false) | 世界空间->观察空间 |
real3 TransformWorldToHClipDir(real3 directionWS, bool doNormalize = false) | 模型空间->世界空间->裁剪空间 |
法线变化
函数名 | 解释 |
---|---|
float3 TransformObjectToWorldNormal(float3 normalOS, bool doNormalize = true) | 模型空间->世界空间 |
float3 TransformWorldToObjectNormal(float3 normalWS, bool doNormalize = true) | 世界空间->模型空间 |
shader中的语义
语义是赋给Shader输入和输出的字符串,这个字符串表达了这个参数的含义。
这些语义可以上shader知道从哪里读数据,并把这个数据输出到哪里。
常用的语义
应用阶段传递模型数据给顶点着色器时常用语义
语义 | 解释 |
---|---|
POSITION | 模型空间的顶点位置 float4 |
NORMAL | 顶点法线 float3 |
TANGENT | 顶点切线 float4 |
TEXCOORD0 | 顶点纹理坐标 float2/float4 |
COLOR | 顶点颜色 float4 |
顶点着色器传递给片元着色器时常用语义
语义 | 解释 |
---|---|
SV_POSITION | 裁剪空间中的顶点坐标 |
COLOR0 | 输出顶点颜色 |
TEXCOORD0 | 顶点纹理坐标 |
片元着色器输出时常用语义
语义 | 解释 |
---|---|
SV_Target | 输出值会存储到渲染目标(render target)中 |
资料
内置管线Shader升级到URP详细手册
shaderGraph节点库
参考书籍
Unity Shader入门精要 (冯乐乐 著)