Unity Shader入门
看这本书其实就行。Building Quality Shaders for Unity
ShaderLab
首先我们创建一个URP工程,然后复制这个地址里的shader。
Unity中的shader以ShaderLab的格式编写。 下面是上面地址复制的ShaderObject
// ShaderLab代码以Shader声明开始。 这个路径决定了Material面板中UnityShader的名字和位置。 Shader.Find也会使用这个路径
Shader "Example/URPUnlitShaderBasic"
{
// The properties部分包含编辑器能够设置的属性。
Properties
{
//[MainColor]表示这个变量为Material的主颜色
//当你在这里定义属性的时候,你也需要在HLSL代码声明它。
[MainColor] _BaseColor("Base Color", Color) = (1, 1, 1, 1)
//[MainTexture]表示这个变量为Material的主材质
[MainTexture] _BaseMap("Base Map", 2D) = "white"
}
// 包含一个或多个SubShader,Unity选择第一个兼容的SubShader
SubShader
{
// SubShader Tags define when and under which conditions a SubShader block or
// a pass is executed.
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
//Pass是Shader的基本元素。它包含设置GPU状态的指令,以及运行在GPU上的程序。
Pass
{
// The HLSLPROGRAM 包含HLSL程序代码
// HLSL的语义部分可以看这个地址 https://docs.unity3d.com/Manual/SL-ShaderSemantics.html
HLSLPROGRAM
// .#pragma vertex 定义了 vertex shader 函数
#pragma vertex vert
// #pragma fragment 定义了 fragment shader 函数
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
//vertex shader 结构体
struct Attributes
{
float2 uv : TEXCOORD0;
float4 positionOS : POSITION; // 看语义部分
};
//fragment shader结构体
struct Varyings
{
float2 uv : TEXCOORD0;
// The positions in this struct must have the SV_POSITION semantic.
float4 positionHCS : SV_POSITION;
};
//HLSL代码声明Property中的属性
//https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@14.0/manual/writing-shaders-urp-unlit-texture.html
CBUFFER_START(UnityPerMaterial)
float4 _BaseMap_ST;
half4 _BaseColor;
TEXTURE2D(_BaseMap);
SAMPLER(sampler_BaseMap);
CBUFFER_END
Varyings vert(Attributes IN)
{
Varyings OUT;
// The TransformObjectToHClip 函数将顶点坐标从模型空间转化到裁剪空间
// 坐标变换看这个 https://www.bilibili.com/video/BV1Uu411w71V/
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
OUT.uv = TRANSFORM_TEX(IN.uv, _BaseMap);
// Returning the output.
return OUT;
}
// The fragment shader definition.
half4 frag() : SV_Target
{
half4 color = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv);
return color * _BaseColor;
}
ENDHLSL
}
}
}
内容补充
Vertex Shader 输出的结果会在光栅化后通过interpolation处理传递给每个像素的 fragment Shader。
为什么Clip Space被称为Homogeneous Clip Space
After the eye coordinates are transformed by multiplying GL_PROJECTION matrix, the clip coordinates are still a homogeneous coordinates. It finally becomes the normalized device coordinates (NDC) by divided by the w-component of the clip coordinates. —— gl projection matrix