Shader code cleanup;
Added punctual light evaluation in light loop;
This commit is contained in:
@@ -5,6 +5,8 @@
|
||||
|
||||
#define inverselerp(a, b, x) saturate(((x) - (a)) / ((b) - (a)))
|
||||
|
||||
#define APPLY_WEIGHT(x, y, t) lerp(x, x * y, t)
|
||||
|
||||
float2 GetWHRatio()
|
||||
{
|
||||
return float2(_ScreenParams.y / _ScreenParams.x, 1);
|
||||
|
||||
@@ -28,11 +28,6 @@
|
||||
|
||||
struct UTSData
|
||||
{
|
||||
float3 viewDirection;
|
||||
float3 normalDirection;
|
||||
fixed cameraDir;
|
||||
float cameraRoll;
|
||||
fixed signMirror;
|
||||
};
|
||||
|
||||
struct UTSSurfaceData
|
||||
@@ -54,8 +49,7 @@ struct UTSSurfaceData
|
||||
float3 geomNormalWS;
|
||||
float3 tangentWS;
|
||||
|
||||
real3 subsurfaceColor;
|
||||
real subsurfaceMask;
|
||||
real4 subsurfaceColor;
|
||||
|
||||
real anisotropy;
|
||||
};
|
||||
@@ -75,7 +69,7 @@ struct UtsBSDFData
|
||||
real ambientOcclusion;
|
||||
real specularOcclusion;
|
||||
real perceptualRoughness;
|
||||
|
||||
|
||||
real3 subsurfaceColor;
|
||||
|
||||
float3 geomNormalWS;
|
||||
@@ -104,8 +98,8 @@ UTSSurfaceData ConvertSurfaceDataToUTSSurfaceData(SurfaceData surfaceData)
|
||||
output.specularColor = surfaceData.specularColor;
|
||||
output.geomNormalWS = surfaceData.geomNormalWS;
|
||||
output.tangentWS = surfaceData.tangentWS;
|
||||
output.subsurfaceColor = surfaceData.transmittanceColor;
|
||||
output.subsurfaceMask = surfaceData.subsurfaceMask;
|
||||
output.subsurfaceColor.rgb = surfaceData.transmittanceColor;
|
||||
output.subsurfaceColor.a = surfaceData.subsurfaceMask;
|
||||
output.anisotropy = surfaceData.anisotropy;
|
||||
|
||||
return output;
|
||||
@@ -124,8 +118,8 @@ UTSSurfaceData GetUTSSurfaceData(FragInputs input, float3 V, float2 UV)
|
||||
|
||||
float4 firstShadingTexture = SAMPLE_TEXTURE2D(_1st_ShadeMap, sampler_BaseColorMap, TRANSFORM_TEX(UV, _BaseColorMap));
|
||||
float4 secondShadingTexture = SAMPLE_TEXTURE2D(_1st_ShadeMap, sampler_BaseColorMap, TRANSFORM_TEX(UV, _BaseColorMap));
|
||||
output.firstShadingColor = lerp(firstShadingTexture.rgb, mainTexture.rgb, _Use_BaseAs1st) * _1st_ShadeColor;
|
||||
output.secondShadingColor = lerp(secondShadingTexture.rgb, output.firstShadingColor, _Use_1stAs2nd) * _2nd_ShadeColor;
|
||||
output.firstShadingColor = lerp(firstShadingTexture.rgb, mainTexture.rgb, _Use_BaseAs1st) * _1st_ShadeColor.rgb;
|
||||
output.secondShadingColor = lerp(secondShadingTexture.rgb, output.firstShadingColor, _Use_1stAs2nd) * _2nd_ShadeColor.rgb;
|
||||
|
||||
float4 normalLocal = 0;
|
||||
if (_Use_SSSLut)
|
||||
@@ -138,8 +132,13 @@ UTSSurfaceData GetUTSSurfaceData(FragInputs input, float3 V, float2 UV)
|
||||
}
|
||||
normalLocal.rgb = UnpackNormalScale(normalLocal, _NormalScale);
|
||||
float3 normalWS = normalize(mul(normalLocal.rgb, input.tangentToWorld));
|
||||
#if _PBR_MODE_OFF
|
||||
float smoothness = 0.0;
|
||||
float metallic = 0.0;
|
||||
#else
|
||||
float smoothness = _Smoothness;
|
||||
float metallic = _Metallic;
|
||||
#endif
|
||||
float ao = 1.0;
|
||||
float3 specularColor = 1;
|
||||
float anisotropy = 0;
|
||||
@@ -189,7 +188,6 @@ UTSSurfaceData GetUTSSurfaceData(FragInputs input, float3 V, float2 UV)
|
||||
output.tangentWS = Orthonormalize(input.tangentToWorld[0].rgb, normalWS);
|
||||
|
||||
output.subsurfaceColor = SAMPLE_TEXTURE2D(_SSSLutMap, sampler_MainTex, TRANSFORM_TEX(UV, _BaseColorMap)) * _SSSIntensity;
|
||||
output.subsurfaceMask = 1.0;
|
||||
|
||||
output.anisotropy = anisotropy;
|
||||
|
||||
@@ -216,13 +214,9 @@ UtsBSDFData ConvertUTSSurfaceDataToUTSBSDFData(UTSSurfaceData surfaceData)
|
||||
|
||||
output.ambientOcclusion = surfaceData.ambientOcclusion;
|
||||
output.specularOcclusion = surfaceData.specularOcclusion;
|
||||
#if _PBR_MODE_OFF
|
||||
output.perceptualRoughness = 0.0;
|
||||
#else
|
||||
output.perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness);
|
||||
#endif
|
||||
|
||||
output.subsurfaceColor = surfaceData.subsurfaceColor * surfaceData.subsurfaceMask;
|
||||
output.subsurfaceColor = surfaceData.subsurfaceColor.rgb * surfaceData.subsurfaceColor.a;
|
||||
|
||||
output.normalWS = surfaceData.normalWS;
|
||||
output.geomNormalWS = surfaceData.geomNormalWS;
|
||||
@@ -230,8 +224,7 @@ UtsBSDFData ConvertUTSSurfaceDataToUTSBSDFData(UTSSurfaceData surfaceData)
|
||||
output.bitangentWS = normalize(cross(surfaceData.normalWS, surfaceData.tangentWS));
|
||||
|
||||
output.anisotropy = surfaceData.anisotropy;
|
||||
output.roughnessT = output.perceptualRoughness * 0.5;
|
||||
output.roughnessB = output.perceptualRoughness * 2.0;
|
||||
ConvertAnisotropyToRoughness(output.perceptualRoughness, surfaceData.anisotropy, output.roughnessT, output.roughnessB);
|
||||
|
||||
return output;
|
||||
}
|
||||
@@ -312,6 +305,12 @@ PreLightData GetPreLightData_UTS(float3 V, PositionInputs posInput, inout UtsBSD
|
||||
return preLightData;
|
||||
}
|
||||
|
||||
void UtsClampRoughness(inout PreLightData preLightData, inout UtsBSDFData bsdfData, float minRoughness)
|
||||
{
|
||||
bsdfData.roughnessT = max(minRoughness, bsdfData.roughnessT);
|
||||
bsdfData.roughnessB = max(minRoughness, bsdfData.roughnessB);
|
||||
}
|
||||
|
||||
// Legacy for compatibility with existing shaders
|
||||
inline bool IsGammaSpace()
|
||||
{
|
||||
@@ -534,10 +533,6 @@ float3 ShadeSH9 (float4 normal)
|
||||
return res;
|
||||
}
|
||||
|
||||
float rateR = 0.299;
|
||||
float rateG = 0.587;
|
||||
float rateB = 0.114;
|
||||
|
||||
float3 SampleBakedGI_UTS(float3 positionRWS, float3 normalWS, float2 uvStaticLightmap, float2 uvDynamicLightmap, bool needToIncludeAPV = false)
|
||||
{
|
||||
float3 bakeDiffuseLighting = float3(0, 0, 0);
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
#ifndef UTS_PBR
|
||||
#define UTS_PBR
|
||||
#ifndef UTS_MATERIAL_EVALUATION
|
||||
#define UTS_MATERIAL_EVALUATION
|
||||
|
||||
#define ColorSpaceDielectricSpec half4(0.22, 0.22, 0.22, 0.779)
|
||||
|
||||
struct UtsShadeMask
|
||||
{
|
||||
float baseShadeMask;
|
||||
float firstShadeMask;
|
||||
};
|
||||
|
||||
float3 GetSpecularColor(float3 albedo, float metalic)
|
||||
{
|
||||
float3 specColor = lerp(ColorSpaceDielectricSpec.rgb, albedo, metalic);
|
||||
@@ -111,6 +117,104 @@ half3 FitWithCurveApprox(half NdotL, half Curvature)
|
||||
return lerp(curve0, curve1, mad(oneMinusCurva2, -1.0 * oneMinusCurva2, 1.0));
|
||||
}
|
||||
|
||||
float3 SampleSDFTexture(float3 L, float2 uv, out float angle)
|
||||
{
|
||||
float2 right_uv = float2(1 - uv.x, uv.y);
|
||||
float3 left_SDFTex = SAMPLE_TEXTURE2D(_SDFShadowTex, sampler_SDFShadowTex, uv).rgb;
|
||||
float3 right_SDFTex = SAMPLE_TEXTURE2D(_SDFShadowTex, sampler_SDFShadowTex, right_uv).rgb;
|
||||
|
||||
float2 leftVector = normalize(mul(UNITY_MATRIX_M, float4(1, 0, 0, 0)).xz);
|
||||
float2 forwardVector = normalize(mul(UNITY_MATRIX_M, float4(0, 0, 1, 0)).xz);
|
||||
|
||||
float2 lightDirection = normalize(L.xz);
|
||||
angle = 1.0 - (dot(forwardVector, lightDirection) * 0.5 + 0.5);
|
||||
bool isRightSide = dot(lightDirection, leftVector) > 0;
|
||||
|
||||
return isRightSide ? right_SDFTex : left_SDFTex;
|
||||
}
|
||||
|
||||
float GetHairShadow(PositionInputs posInput, float3 L, float2 positionSS)
|
||||
{
|
||||
// Push the face fragment view space position towards the light for a little bit
|
||||
float hairShadowOpacity = saturate(Remap(length(posInput.positionWS), float2(_HairShadowFadeOutDistance, _HairShadowFadeInDistance), float2(0, 1)));
|
||||
|
||||
float3 viewLightDir = TransformWorldToViewDir(L); // / posInput.deviceDepth; when linearDepth grows large, the movement amount should be lower since we are getting further from the face.
|
||||
float3 cameraDirOS = normalize(TransformWorldToObject(GetCameraPositionWS()));
|
||||
float shadowLengthY = _HairShadowDistance * 5.0 * max(0.5, posInput.linearDepth * _HairShadowDistanceScaleFactor) / posInput.linearDepth;
|
||||
float2 shadowLength = float2(shadowLengthY * 2.0f, shadowLengthY);
|
||||
|
||||
float3 camDirOS = normalize(TransformWorldToObject(GetCameraPositionWS()));
|
||||
float camDirFactor = 1 - smoothstep(0.1, 0.9, camDirOS.y);
|
||||
shadowLength.y *= camDirFactor;
|
||||
|
||||
float2 samplingPoint = (positionSS + shadowLength * viewLightDir.xy * (_ScreenSize.xy / float2 (1920.0f, 1080.0f))) * _ScreenSize.zw; // Use 1080p as the reference resolution to achieve consistent shadow lengths across various screen resolutions.
|
||||
|
||||
// Then sample the hair buffer, to see if the fragment lands in shadow.
|
||||
float2 scaledUVs = samplingPoint * _HairShadowRTHandleScale; // We have to including the scaling factor for our shadow map since we are not going to allocate new texture if the rendering resolution changed.
|
||||
float hairDepth = SAMPLE_TEXTURE2D(_HairShadowTex, s_trilinear_clamp_sampler, scaledUVs).r;
|
||||
float depthCorrect = posInput.deviceDepth <= hairDepth + _HairShadowDepthBias ? 1 : 0; // Hair < Face means Hair are closer to camera
|
||||
// Note that we have LinearEyeDepth in the buffer. A comparison of depth is needed so that we don't project the shadow of hair behind the face.
|
||||
float hairShadow = lerp(0,hairShadowOpacity,depthCorrect);
|
||||
}
|
||||
|
||||
UtsShadeMask GetShadeMak(float3 normalWS, float3 L, SHADOW_TYPE shadow, float2 uv, out float additionalSpecular)
|
||||
{
|
||||
UtsShadeMask shadeMask;
|
||||
ZERO_INITIALIZE(UtsShadeMask, shadeMask);
|
||||
|
||||
#if _SHADOW_MODE_NORMAL
|
||||
float NdotL = dot(normalWS, L);
|
||||
float halfLambert = 0.5 * NdotL + 0.5;
|
||||
|
||||
//float systemShadows = saturate(max(0.0, shadow.x + 0.5 - 0.0001 + _Tweak_SystemShadowsLevel));
|
||||
//float shadingGrade = lerp(halfLambert, halfLambert * systemShadows, _Set_SystemShadowsToBase);
|
||||
|
||||
float firstColorFeatherForMask = lerp(_1st_ShadeColor_Feather, 0.0, max(_ComposerMaskMode, _FirstShadeOverridden));
|
||||
shadeMask.baseShadeMask = saturate((halfLambert - (_1st_ShadeColor_Step - firstColorFeatherForMask)) / (_1st_ShadeColor_Step - (_1st_ShadeColor_Step - firstColorFeatherForMask)));
|
||||
|
||||
float secondColorFeatherForMask = lerp(_2nd_ShadeColor_Feather, 0.0, max(_SecondShadeOverridden, _ComposerMaskMode));
|
||||
shadeMask.firstShadeMask = saturate((halfLambert - (_2nd_ShadeColor_Step - secondColorFeatherForMask)) / (_2nd_ShadeColor_Step - (_2nd_ShadeColor_Step - secondColorFeatherForMask)));
|
||||
|
||||
additionalSpecular = 0;
|
||||
#elif _SHADOW_MODE_SDF
|
||||
float angle;
|
||||
float smoothGamma = _SDFSmoothGamma / 10.0f;
|
||||
float shadowLevel = _SDFShadowLevel / 10.0f;
|
||||
|
||||
float3 sdfTexture = SampleSDFTexture(L, uv, angle); // r: sdf shadow, g: sdf noise highlight, b: fixed shadow
|
||||
float sdfShadowMask = smoothstep(sdfTexture.r - smoothGamma, sdfTexture.r + smoothGamma, angle - shadowLevel);
|
||||
|
||||
shadeMask.baseShadeMask = sdfShadowMask * sdfTexture.b;
|
||||
additionalSpecular = sdfTexture.g;
|
||||
#endif
|
||||
|
||||
shadeMask.baseShadeMask = APPLY_WEIGHT(shadeMask.baseShadeMask, shadow, _Set_SystemShadowsToBase);
|
||||
|
||||
return shadeMask;
|
||||
}
|
||||
|
||||
DirectLighting UtsShadeSurface(UtsBSDFData bsdfData, PreLightData preLightData, SHADOW_TYPE shadow,
|
||||
float3 lightColor, float3 V, float3 L, float2 uv,
|
||||
float diffuseDimmer, float specularDimmer)
|
||||
{
|
||||
DirectLighting lighting;
|
||||
ZERO_INITIALIZE(DirectLighting, lighting);
|
||||
|
||||
if (Max3(lightColor.r, lightColor.g, lightColor.b) > 0.0)
|
||||
{
|
||||
float additionalSpecular;
|
||||
UtsShadeMask shadeMask = GetShadeMak(bsdfData.normalWS, L, shadow, uv, additionalSpecular);
|
||||
|
||||
float3 diffuseTerm = lerp(lerp(bsdfData.secondShadingDiffuseColor, bsdfData.firstShadingDiffuseColor, shadeMask.firstShadeMask), bsdfData.diffuseColor, shadeMask.baseShadeMask);
|
||||
float3 specularTerm = (ComputeSpecularTerm(bsdfData, preLightData, V, L) + additionalSpecular) * shadeMask.baseShadeMask;
|
||||
|
||||
lighting.diffuse += diffuseTerm * lightColor * diffuseDimmer;
|
||||
lighting.specular += specularTerm * lightColor * specularDimmer;
|
||||
}
|
||||
|
||||
return lighting;
|
||||
}
|
||||
|
||||
// Todo: SDF nose high light
|
||||
// #if define(_SDFShadow) || define(_SDFNoiseHelight)
|
||||
#ifdef _SDFShadow
|
||||
Reference in New Issue
Block a user