基础:TA Shader基础、Unity Shader语法
可编程渲染管线:渲染策略是可以供程序员定制的,可以定制的有:光照计算和光源,深度测试,摄像机光照烘焙,后期处理策略等等。
URP渲染管线概念:URP是一种轻量级渲染管线,适用于移动设备、虚拟现实(VR)、增强现实(AR)以及高性能需求的平台。URP的设计目标是在保持高性能的同时,提供更多的渲染功能和自定义选项。它支持基于物理的渲染(PBR),包括光照、阴影、反射等效果。URP还支持后处理效果、2D渲染、粒子系统、Shader图形编程、自定义渲染管线等功能。不同的渲染管线,shader是不能共用的。
Unity内置标准渲染管线:每个重要光源都需要绘制一次物体,着色。场景中存在多个重要光源则需要绘制物体多次并叠加效果,消耗性能,但是可以支持任意多光源
URP:全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,一次Pass可以计算多个光源。对于手机游戏来说,URP更加适合。
创建项目的时候,我们需要选择3D Sample Scene(URP)。项目的Package就会安排好URP的编程环境。
与普通项目相比,会多出Presets文件夹,里面包含着一些设置,包括本色,声音,法线,贴图等设置。Scenes中会有Sample Scene Lighting Setting文件,对场景的烘焙进行设置。Settings文件夹中就是关于渲染管线的设置了。包括:
URP的变化:
URP摄像机分为主摄像机,主摄像机会有一个列表管理若干个Overlay摄像机
主摄像机物体下包含Camera组件和Universal Additional Camera Data组件
Camera组件:
render type:渲染类型,分为base和overlay
Projection:
Projection:分为透视投影和正交投影
FOV Axis:FOV轴,垂直还是水平
Field of View:视场角
Physical Camera
Clipping Planes:近端和远端距离
Rendering:
Renderer:向前渲染和延迟渲染
Post Processing:是否后处理
Anti-aliasing:抗锯齿算法设置
Dithering:防抖
Render Shadow:是否绘制阴影
priority:优先级,越高的绘制在低的上面
Opaque Texture:纹理设置
Depth Texture:深度贴图设置
Culling Mask:绘制哪些物体
Occlusion Culling:
Environment:
Background type:背景,可以选择天空盒和纯色
HDR:高清
MSAA:抗锯齿
Viewport Rect:显示范围
Allow Dynamic Resolution:动态分辨率
Target Display:显示到哪个显示器
Target Eye:
Stack:Overlay摄像机的栈,Overlay摄像机放到里面才能显示
Output:
OutPut Texture:把摄像机的画面输出到的纹理对象
上面所有的属性都可以在Universal Additional Camera Data脚本中找到
全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,主光源和附加光源在一次Pass中可以一起着色。对于手机游戏来说,URP更加适合。
Light:
Type:光源类型,平行光,点光源,聚光灯,区域光
Color:颜色
Mode: Realtime(没有间接光照),Baked(静态计算,有间接光照),mixed(实时和静态烘焙)
Intensity:强度
indirect Multiplier:控制间接光照的强度(反射过来的光照)
Shadow Type:Soft Shadows,Hard Shadows,No Shadows
Render Mode:
Culling Mask:
默认情况下太阳光是主光源,其他是附加光源。
在Settings渲染质量的配置文件 中可以配置光源数目等信息。
这个模板基于Unlit Shader,最为灵活,可以开发出任意的shader
同样是ShaderLab,但是URP和Unity内置渲染管线不同,它不是内嵌的CG,内嵌的是HLSL
Shader "Universal Render Pipeline/Unlit"
{
Properties
{
[MainTexture] _BaseMap("Texture", 2D) = "white" {}
[MainColor] _BaseColor("Color", Color) = (1, 1, 1, 1)
_Cutoff("AlphaCutout", Range(0.0, 1.0)) = 0.5
// BlendMode
[HideInInspector] _Surface("__surface", Float) = 0.0
[HideInInspector] _Blend("__blend", Float) = 0.0
[HideInInspector] _AlphaClip("__clip", Float) = 0.0
[HideInInspector] _SrcBlend("Src", Float) = 1.0
[HideInInspector] _DstBlend("Dst", Float) = 0.0
[HideInInspector] _ZWrite("ZWrite", Float) = 1.0
[HideInInspector] _Cull("__cull", Float) = 2.0
// Editmode props
[HideInInspector] _QueueOffset("Queue offset", Float) = 0.0
// ObsoleteProperties
[HideInInspector] _MainTex("BaseMap", 2D) = "white" {}
[HideInInspector] _Color("Base Color", Color) = (0.5, 0.5, 0.5, 1)
[HideInInspector] _SampleGI("SampleGI", float) = 0.0 // needed from bakedlit
}
SubShader
{
Tags {"RenderType" = "Opaque" "IgnoreProjector" = "True" "RenderPipeline" = "UniversalPipeline" "ShaderModel"="4.5"}
LOD 100
Blend [_SrcBlend][_DstBlend]
ZWrite [_ZWrite]
Cull [_Cull]
Pass
{
Name "Unlit"
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
// -------------------------------------
// Unity defined keywords
#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
// CPU传过来的数据
#include "UnlitInput.hlsl"
// 渲染管线传过来的
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
// 顶点shader传递给片元shader的数据
struct Varyings
{
float2 uv : TEXCOORD0;
float fogCoord : TEXCOORD1;
float4 vertex : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
// 顶点shader
Varyings vert(Attributes input)
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
output.vertex = vertexInput.positionCS;
output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
output.fogCoord = ComputeFogFactor(vertexInput.positionCS.z);
return output;
}
//片元着色shader
half4 frag(Varyings input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
half2 uv = input.uv;
half4 texColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv);
half3 color = texColor.rgb * _BaseColor.rgb;
half alpha = texColor.a * _BaseColor.a;
AlphaDiscard(alpha, _Cutoff);
#ifdef _ALPHAPREMULTIPLY_ON
color *= alpha;
#endif
color = MixFog(color, input.fogCoord);
return half4(color, alpha);
}
ENDHLSL
}
// 只渲染深度信息
Pass
{
Name "DepthOnly"
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
ENDHLSL
}
// This pass it not used during regular rendering, only for lightmap baking.
Pass
{
Name "Meta"
Tags{"LightMode" = "Meta"}
Cull Off
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex UniversalVertexMeta
#pragma fragment UniversalFragmentMetaUnlit
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitMetaPass.hlsl"
ENDHLSL
}
}
SubShader
{
Tags {"RenderType" = "Opaque" "IgnoreProjector" = "True" "RenderPipeline" = "UniversalPipeline" "ShaderModel"="2.0"}
LOD 100
Blend [_SrcBlend][_DstBlend]
ZWrite [_ZWrite]
Cull [_Cull]
Pass
{
Name "Unlit"
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
// -------------------------------------
// Unity defined keywords
#pragma multi_compile_fog
#pragma multi_compile_instancing
#include "UnlitInput.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float2 uv : TEXCOORD0;
float fogCoord : TEXCOORD1;
float4 vertex : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings vert(Attributes input)
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
output.vertex = vertexInput.positionCS;
output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
output.fogCoord = ComputeFogFactor(vertexInput.positionCS.z);
return output;
}
half4 frag(Varyings input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
half2 uv = input.uv;
half4 texColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv);
half3 color = texColor.rgb * _BaseColor.rgb;
half alpha = texColor.a * _BaseColor.a;
AlphaDiscard(alpha, _Cutoff);
#ifdef _ALPHAPREMULTIPLY_ON
color *= alpha;
#endif
color = MixFog(color, input.fogCoord);
alpha = OutputAlpha(alpha, _Surface);
return half4(color, alpha);
}
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
ENDHLSL
}
// This pass it not used during regular rendering, only for lightmap baking.
Pass
{
Name "Meta"
Tags{"LightMode" = "Meta"}
Cull Off
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex UniversalVertexMeta
#pragma fragment UniversalFragmentMetaUnlit
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitMetaPass.hlsl"
ENDHLSL
}
}
FallBack "Hidden/Universal Render Pipeline/FallbackError"
CustomEditor "UnityEditor.Rendering.Universal.ShaderGUI.UnlitShader"
}
美术工作流:金属度与粗糙度、反射度与光泽度
Surface Type:渲染队列
Render face:渲染前面还是后面
alpha clipping:alpha小于某个值就不着色
Receive Shadow:是否接收阴影
Base Map:本色贴图
Metallic Map:金属度贴图,可以调节光滑度
Normal Map:法线贴图
Height Map:高度贴图
Occlusion Map:遮挡贴图
Tilling、Offset:和Unity自带的渲染管线一致
具体功能我们可以根据Lit shader脚本进行改造,具体信息查看LitForwardPass.hlsl文件,建议通读相关引用脚本的源码。