ShaderGraph中的LitShader如下:
在顶点和片元着色器暴露出了上图中的几个参数,要转换成URPLitShaderLab,首先要找到这几个参数,打开LitShader,找到第一个Pass,可以看到下图中的顶点和片元的定义函数,还有引用的两个库。
打开LitForwardPass.hlsl
顶点着色器如下:
片元着色器代码如下:
在ShaderGraph中的片元着色器的几个参数在SurfaceData中,只要在需要改变的时候重写如下函数即可。
最简URP下的Lit Shader代码如下:
Shader "CustomURPLitShaderBase"
{
Properties
{
}
SubShader
{
Tags
{
"RenderPipeline"="UniversalPipeline"
"RenderType"="Opaque"
"Queue"="Geometry"
}
Pass
{
Name "Universal Forward"
Tags
{
"LightMode" = "UniversalForward"
}
// Render State
Cull Back
Blend One Zero
ZTest LEqual
ZWrite On
HLSLPROGRAM
// Pragmas
#pragma target 4.5
#pragma exclude_renderers gles gles3 glcore
#pragma vertex vert
#pragma fragment frag
#define _NORMALMAP 1
// Includes
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
struct Attributes
{
float3 positionOS : POSITION;
float3 normalOS : NORMAL;
float4 tangentOS : TANGENT;
float4 uv1 : TEXCOORD1;
float4 uv2 : TEXCOORD2;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float3 positionWS : TEXCOORD0;
float3 normalWS : NORMAL;
float3 viewDirectionWS : TEXCOORD1;
};
void InitializeInputData(Varyings input,out InputData inputData)
{
inputData = (InputData)0;
inputData.positionWS = input.positionWS;
inputData.normalWS = NormalizeNormalPerPixel(input.normalWS);
inputData.viewDirectionWS = SafeNormalize(input.viewDirectionWS);
inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, float3(0,0,0), inputData.normalWS);
inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS);
}
Varyings vert(Attributes input)
{
Varyings output = (Varyings)0;
//世界空间下的坐标
float3 positionWS = TransformObjectToWorld(input.positionOS);
//世界空间下的法线坐标
output.normalWS = TransformObjectToWorldNormal(input.normalOS);
output.positionCS = TransformWorldToHClip(positionWS);
output.viewDirectionWS = GetWorldSpaceViewDir(positionWS);
return output;
}
half4 frag(Varyings unpacked) : SV_TARGET
{
InputData inputData;
InitializeInputData(unpacked,inputData);
SurfaceData surface;
#ifdef UNITY_COLORSPACE_GAMMA
surface.albedo = float3(0.5, 0.5, 0.5);
#else
surface.albedo = SRGBToLinear(float3(0.5, 0.5, 0.5));
#endif
surface.metallic = 0;
surface.specular = 0;
surface.smoothness = 0.5;
surface.occlusion = 1;
surface.emission = float3(0, 0, 0);
surface.alpha = 1;
surface.normalTS = half3(0, 0, 0);
surface.clearCoatMask = 0;
surface.clearCoatSmoothness = 1;
half4 color = UniversalFragmentPBR(inputData, surface);
return color;
}
ENDHLSL
}
}
}
结果:
如果需要显示阴影就在 CustomURPLitShaderBase的Subshader中增加一个阴影的pass即可
Pass
{
Name "ShadowCaster"
Tags{"LightMode" = "ShadowCaster"}
ZWrite On
ZTest LEqual
ColorMask 0
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
ENDHLSL
}
结果: