前面我们讲了基础名称上的区别和新增的库文件,那我们就要说说很重要的光照了。
Built-in光照文件
Lighting.cginc引用
UnityLightingCommon.cginc、UnityGBuffer.cginc、UnityGlobalIllumination.cginc
URP光照文件
Lighting.hlsl引用
Common.hlsl、EntityLighting.hlsl、ImageBasedLighting.hlsl、Core.hlsl、Shadows.hlsl、
Built-in URP
两者都有Lambert、BlinnPhong光照模型
以前我们得到主光信息需要
float4 lightColor = _LightColor0;
float3 lightDir = WorldSpaceLightDir(worldPos);
UNITY_LIGHT_ATTENUATION(atten, i, worldPos.xyz);
URP中有一个便捷方法mainLight
GetMainLight();GetMainLight(float4 shadowCoord);
//shadowCoord由之前说的VertexPositionInputs辅助GetShadowCoord(vertexInput);方法获得
有了mainlight,上图中的Light属性就可以直接用了,这里重载的区别是shadowAttenuation=1.0还是有实际值的区别
get方法中的赋值方式大概如下
half3 direction = _mainLightPosition.xyz;
half3 color = _MainLightColor.rgb;
half distanceAttenuation = unity_LightData.z;
half shadowAttenuation = MainLightRealtimShadow(shadowCoord);//shadowAttenuation = 1.0
URP lighting中帮我们封装好了BRDFData,可以使用集成的PBR光照算法
GI方面
built-in
float sh = 0;//多光源近似光会+=在sh上
float3 SH = ShadeSHPerVertex (worldNormal, sh);
URP
half3 SH = SampleSH(normalWS);//LPPV 不支持 Ligthweight Pipeline
half3 SH = SampleSHVertex(normalWS);//顶点评估
half3 SH = SampleSHPixel(L2Term, normalWS);//像素评估
LightMap方面
built-in
float2 uv2 = v.uv2 * unity_LightMapST.xy + unity_LightMapST.zw;
float3 lightmap = DecodeLightmap(tex2D(unity_Lightmap, i.uv2));
URP
Varyings里lightmap uv的声明 DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 1);
这里的宏定义为了区分出光照贴图和球谐光,使之只有一个生效。
Varyings input
1. inputData.normalWS = input.normal;
2. inputData.normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangent.xyz, input.bitangent.xyz, input.normal.xyz));
3. inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS);
OUTPUT_LIGHTMAP_UV(input.lightmapUV, unity_LightmapST, output.lightmapUV);
half3 bakedGI = SAMPLE_GI(input.lightmapUV, input.vertexSH, inputData.normalWS);
*OR*
half3 bakedGI = SamplLightmap(lightmapUV, normalWS);
扩展:
half4 decodeInstructions = half4(LIGHTMAP_HDR_MULTIPLIER, LIGHTMAP_HDR_EXPONENT, 0.0h, 0.0h);
half4 transformCoords = half4(1, 1, 0, 0);
real3 illuminance = real3(0.0, 0.0, 0.0);
float2 uv = lightmapUV.xy * lightmapScaleOffset.xy + lightmapScaleOffset.zw;
RGB9E5动态lightmap real4 encodedIlluminance = SAMPLE_TEXTURE2D(lightmapTex, lightmapSampler, uv).rgba;
illuminance = DecodeLightmap(encodedIlluminance, decodeInstructions);
RGBM 静态lightmap illuminance = SAMPLE_TEXTURE2D(lightmapTex, lightmapSampler, uv).rgb;
常用顶点函数的改动
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
half3 viewDirWS = GetCameraPositionWS() - vertexInput.positionWS;
half3 vertexLight = VertexLighting(vertexInput.positionWS, normalInput.normalWS);
half fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
output.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
inputData.fogCoord = input.fogFactorAndVertexLight.x;
output.normal = half4(normalInput.normalWS, viewDirWS.x);
output.tangent = half4(normalInput.tangentWS, viewDirWS.y);
output.bitangent = half4(normalInput.bitangentWS, viewDirWS.z);
output.normalWs = NormalizeNormalPerVertex (normalInput.normalws);//根据平台进行判断
关于常用采样的改动
half4 col = SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex, uv) ;
half4 diffuseAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap));
half3 diffuse = diffuseAlpha.rgb * _BaseColor.rgb;
half alpha = diffuseAlpha.a * _BaseColor.a;
half3 normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap));
half3 emission = SampleEmission(uv, _EmissionColor.rgb, TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap));
half4 specular = SampleSpecularSmoothness(uv, alpha, _SpecColor, TEXTURE2D_ARGS(_SpecGlossMap, sampler_SpecGlossMap));
half smoothness = specular.a;
InputData inputData;
InitializeInputData(input, normalTS, inputData);
color.rgb = MixFog(color.rgb, inputData.fogCoord);
对Unlit改造 试用这些改变
Shader "Diffuse Color" {
Properties {
_Color("Color Tint", color) = (1,1,1,1)
[NoScaleOffset]_MainTex ("Main Texture (RGB)", 2D) = "white" {}
_Forground("Filtering (RGB)",Color)=(0,0,0,1)
_TransVal ("Transparency Value", Range(0,10)) = 1.0
_FillCenter("Fill Center", Range(0,5)) = 1
}
SubShader {
Tags { "QUEUE" = "AlphaTest" "IgnoreProjector" = "true" "RenderType" = "Transparent" "RenderPipeline" = "UniversalPipeline"}
pass
{
Tags { "LightMode" = "UniversalForward" }
Blend srcalpha OneMinusSrcAlpha
ColorMask RGB
ZWrite Off
ZTest Lequal
HLSLPROGRAM
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
//不加不接受投影
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS
//下面2个可选
#pragma multi_compile _ _MAIN_LIGHT_CALCULATE_SHADOWS
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile_instancing
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
CBUFFER_START(UnityPerMaterial)
float4 _Forground;
float _TransVal;
float4 _Color;
float _FillCenter;
CBUFFER_END
struct a2v
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float4 tangentOS : TANGENT;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
#if defined(_MAIN_LIGHT_SHADOWS)
float4 shadowCoord:TEXCOORD1;
#endif
float3 normalWS:TEXCOORD2;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert(a2v v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
VertexPositionInputs vertexInput = GetVertexPositionInputs(v.positionOS.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(v.normalOS, v.tangentOS);
o.positionCS = vertexInput.positionCS;
o.uv = v.texcoord;
o.normalWS = normalInput.normalWS;
#if defined(_MAIN_LIGHT_SHADOWS)
o.shadowCoord = GetShadowCoord(vertexInput);
#endif
return o;
}
float4 frag(v2f i) : COLOR
{
UNITY_SETUP_INSTANCE_ID(i);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
float4 col = SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex, i.uv) ;
#if defined(_MAIN_LIGHT_SHADOWS)
Light mainLight = GetMainLight(i.shadowCoord);
float3 SH = SampleSH(i.normalWS);
half NdotL = dot(i.normalWS, mainLight.direction);
col.rgb *= _Color.rgb * mainLight.color.rgb * mainLight.shadowAttenuation * NdotL + SH;
#else
col.rgb *= _Color.rgb;
#endif
return col;
}
ENDHLSL
}
}
}