chore: checkpoint current workspace changes
This commit is contained in:
183
docs/reference/NahidaUnity/Shaders/GenshinForwardPass.hlsl
Normal file
183
docs/reference/NahidaUnity/Shaders/GenshinForwardPass.hlsl
Normal file
@@ -0,0 +1,183 @@
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float3 normalOS : NORMAL;
|
||||
float4 tangentOS : TANGENT;
|
||||
float4 color : COLOR;
|
||||
float2 uv : TEXCOORD0;
|
||||
float2 backUV : TEXCOORD1;
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float2 backUV : TEXCOORD1;
|
||||
float3 positionWS : TEXCOORD2;
|
||||
half3 tangentWS : TEXCOORD3;
|
||||
half3 bitangentWS : TEXCOORD4;
|
||||
half3 normalWS : TEXCOORD5;
|
||||
float4 positionNDC : TEXCOORD6;
|
||||
half4 color : COLOR;
|
||||
float4 positionCS : SV_POSITION;
|
||||
};
|
||||
|
||||
half GetShadow(Varyings input, half3 lightDirection, half aoFactor)
|
||||
{
|
||||
half NDotL = dot(input.normalWS, lightDirection);
|
||||
half halfLambert = 0.5 * NDotL + 0.5;
|
||||
half shadow = saturate(2.0 * halfLambert * aoFactor);
|
||||
return lerp(shadow, 1.0, step(0.9, aoFactor));
|
||||
}
|
||||
|
||||
half GetFaceShadow(Varyings input, half3 lightDirection)
|
||||
{
|
||||
half3 F = SafeNormalize(half3(_FaceDirection.x, 0.0, _FaceDirection.z));
|
||||
half3 L = SafeNormalize(half3(lightDirection.x, 0.0, lightDirection.z));
|
||||
half FDotL = dot(F, L);
|
||||
half FCrossL = cross(F, L).y;
|
||||
|
||||
half2 shadowUV = input.uv;
|
||||
shadowUV.x = lerp(shadowUV.x, 1.0 - shadowUV.x, step(0.0, FCrossL));
|
||||
half faceShadowMap = SAMPLE_TEXTURE2D(_FaceLightMap, sampler_FaceLightMap, shadowUV).r;
|
||||
half faceShadow = step(-0.5 * FDotL + 0.5 + _FaceShadowOffset, faceShadowMap);
|
||||
|
||||
half faceMask = SAMPLE_TEXTURE2D(_FaceShadow, sampler_FaceShadow, input.uv).a;
|
||||
half maskedFaceShadow = lerp(faceShadow, 1.0, faceMask);
|
||||
|
||||
return maskedFaceShadow;
|
||||
}
|
||||
|
||||
half3 GetShadowColor(half shadow, half material, half day)
|
||||
{
|
||||
int index = 4;
|
||||
index = lerp(index, 1, step(0.2, material));
|
||||
index = lerp(index, 2, step(0.4, material));
|
||||
index = lerp(index, 0, step(0.6, material));
|
||||
index = lerp(index, 3, step(0.8, material));
|
||||
|
||||
half rangeMin = 0.5 + _ShadowOffset - _ShadowSmoothness;
|
||||
half rangeMax = 0.5 + _ShadowOffset;
|
||||
half2 rampUV = half2(smoothstep(rangeMin, rangeMax, shadow), index / 10.0 + 0.5 * day + 0.05);
|
||||
half3 shadowRamp = SAMPLE_TEXTURE2D(_ShadowRamp, sampler_ShadowRamp, rampUV);
|
||||
|
||||
half3 shadowColor = shadowRamp * lerp(_ShadowColor, 1.0, smoothstep(0.9, 1.0, rampUV.x));
|
||||
shadowColor = lerp(shadowColor, 1.0, step(rangeMax, shadow));
|
||||
|
||||
return shadowColor;
|
||||
}
|
||||
|
||||
half3 GetSpecular(Varyings input, half3 lightDirection, half3 albedo, half3 lightMap)
|
||||
{
|
||||
half3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
|
||||
half3 H = SafeNormalize(lightDirection + V);
|
||||
half NDotH = dot(input.normalWS, H);
|
||||
half blinnPhong = pow(saturate(NDotH), _SpecularSmoothness);
|
||||
|
||||
half3 normalVS = TransformWorldToViewNormal(input.normalWS, true);
|
||||
half2 matcapUV = 0.5 * normalVS.xy + 0.5;
|
||||
half3 metalMap = SAMPLE_TEXTURE2D(_MetalMap, sampler_MetalMap, matcapUV);
|
||||
|
||||
half3 nonMetallic = step(1.1, lightMap.b + blinnPhong) * lightMap.r * _NonmetallicIntensity;
|
||||
half3 metallic = blinnPhong * lightMap.b * albedo * metalMap * _MetallicIntensity;
|
||||
half3 specular = lerp(nonMetallic, metallic, step(0.9, lightMap.r));
|
||||
|
||||
return specular;
|
||||
}
|
||||
|
||||
half GetRim(Varyings input)
|
||||
{
|
||||
half3 normalVS = TransformWorldToViewNormal(input.normalWS, true);
|
||||
float2 uv = input.positionNDC.xy / input.positionNDC.w;
|
||||
float2 offset = float2(_RimOffset * normalVS.x / _ScreenParams.x, 0.0);
|
||||
|
||||
float depth = LinearEyeDepth(SampleSceneDepth(uv), _ZBufferParams);
|
||||
float offsetDepth = LinearEyeDepth(SampleSceneDepth(uv + offset), _ZBufferParams);
|
||||
half rim = smoothstep(0.0, _RimThreshold, offsetDepth - depth) * _RimIntensity;
|
||||
|
||||
half3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
|
||||
half NDotV = dot(input.normalWS, V);
|
||||
half fresnel = pow(saturate(1.0 - NDotV), 5.0);
|
||||
|
||||
return rim * fresnel;
|
||||
}
|
||||
|
||||
Varyings ForwardPassVertex(Attributes input)
|
||||
{
|
||||
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
|
||||
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
|
||||
|
||||
Varyings output = (Varyings)0;
|
||||
output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
|
||||
output.backUV = TRANSFORM_TEX(input.backUV, _BaseMap);
|
||||
output.positionWS = vertexInput.positionWS;
|
||||
output.tangentWS = normalInput.tangentWS;
|
||||
output.bitangentWS = normalInput.bitangentWS;
|
||||
output.normalWS = normalInput.normalWS;
|
||||
output.positionNDC = vertexInput.positionNDC;
|
||||
output.color = input.color;
|
||||
output.positionCS = vertexInput.positionCS;
|
||||
|
||||
output.positionCS.xy += _ScreenOffset.xy * output.positionCS.w;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
half4 ForwardPassFragment(Varyings input, FRONT_FACE_TYPE facing : FRONT_FACE_SEMANTIC) : SV_TARGET
|
||||
{
|
||||
#if _DOUBLE_SIDED
|
||||
input.uv = lerp(input.uv, input.backUV, IS_FRONT_VFACE(facing, 0.0, 1.0));
|
||||
#endif
|
||||
|
||||
half4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv);
|
||||
half3 albedo = baseMap.rgb * _BaseColor.rgb;
|
||||
half alpha = baseMap.a;
|
||||
|
||||
#if _IS_FACE
|
||||
albedo = lerp(albedo, _FaceBlushColor.rgb, _FaceBlushStrength * alpha);
|
||||
#endif
|
||||
|
||||
#if _NORMAL_MAP
|
||||
half3x3 tangentToWorld = half3x3(input.tangentWS, input.bitangentWS, input.normalWS);
|
||||
half4 normalMap = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, input.uv);
|
||||
half3 normalTS = UnpackNormal(normalMap);
|
||||
half3 normalWS = TransformTangentToWorld(normalTS, tangentToWorld, true);
|
||||
input.normalWS = normalWS;
|
||||
#endif
|
||||
|
||||
Light mainLight = GetMainLight();
|
||||
half3 lightDirection = SafeNormalize(mainLight.direction * _LightDirectionMultiplier);
|
||||
|
||||
half4 lightMap = SAMPLE_TEXTURE2D(_LightMap, sampler_LightMap, input.uv);
|
||||
half material = lerp(lightMap.a, _CustomMaterialType, _UseCustomMaterialType);
|
||||
#if _IS_FACE
|
||||
half shadow = GetFaceShadow(input, lightDirection);
|
||||
#else
|
||||
half aoFactor = lightMap.g * input.color.r;
|
||||
half shadow = GetShadow(input, lightDirection, aoFactor);
|
||||
#endif
|
||||
half3 shadowColor = GetShadowColor(shadow, material, _IsDay);
|
||||
|
||||
half3 specular = 0.0;
|
||||
#if _SPECULAR
|
||||
specular = GetSpecular(input, lightDirection, albedo, lightMap.rgb);
|
||||
#endif
|
||||
|
||||
half3 emission = 0.0;
|
||||
#if _EMISSION
|
||||
emission = albedo * _EmissionIntensity * alpha;
|
||||
#endif
|
||||
|
||||
half3 rim = 0.0;
|
||||
#if _RIM
|
||||
rim = albedo * GetRim(input);
|
||||
#endif
|
||||
|
||||
half3 finalColor = albedo * shadowColor + specular + emission + rim;
|
||||
half finalAlpha = 1.0;
|
||||
|
||||
return half4(finalColor, finalAlpha);
|
||||
}
|
||||
Reference in New Issue
Block a user