Added UtsEvaluateBSDF_MatCapDiffuse;

Added UtsEvaluateBSDF_MatCapSpecular;
This commit is contained in:
Misaki
2025-01-24 17:59:40 +09:00
parent 476fdc3774
commit fac66d8694
9 changed files with 307 additions and 299 deletions

View File

@@ -34,8 +34,85 @@ float3 GetSmoothedWorldNormal(float2 uv, float3x3 t_tbn)
return mul(normal, t_tbn);
}
float3 UtsComputeDiffuseColor(float3 baseColor, float metallic, float min)
{
#if _PBR_MODE_OFF
return baseColor;
#else
return baseColor * (max(min, 1.0 - metallic));
#endif
}
float3 UtsComputeDiffuseColor(float3 baseColor, float metallic)
{
return UtsComputeDiffuseColor(baseColor, metallic, 0.0);
}
#define SampleRampSignalLine(texture, u) (SAMPLE_TEXTURE2D_LOD(texture, s_linear_clamp_sampler, float2(u, 0.5), 0))
// Exposure
float3 ApplyCurrentExposureMultiplier(float3 color)
{
return color * lerp(GetCurrentExposureMultiplier(), 1, _ToonIgnoreExposureMultiplier);
}
float3 ConvertFromEV100(float3 EV100)
{
float3 value = pow(2, EV100) * 2.5f;
return value;
}
float3 ConvertToEV100(float3 value)
{
return log2(value * 0.4f);
}
float WeightSample(PositionInputs positionInput)
{
// Center-weighted
const float2 kCenter = _ScreenParams.xy * 0.5;
const float weight = pow(length((kCenter.xy - positionInput.positionSS.xy) / _ScreenParams.xy), 1.0);
return 1.0 - saturate(weight);
}
float3 ApplyCompensation(float3 originalColor)
{
float3 ev100_Color = ConvertToEV100(originalColor) + _ToonEvAdjustmentCompensation * 0.5f;
float3 resultColor = max(0, ConvertFromEV100(ev100_Color));
return resultColor;
}
float3 GetExposureAdjustedColor(float3 originalColor)
{
if (_ToonEvAdjustmentCurve != 0)
{
float3 ev100_Color = ConvertToEV100(originalColor);
ev100_Color = clamp(ev100_Color, _ToonEvAdjustmentValueMin, _ToonEvAdjustmentValueMax);
float3 ev100_remap = (ev100_Color - _ToonEvAdjustmentValueMin) * (128 - 1) / (_ToonEvAdjustmentValueMax - _ToonEvAdjustmentValueMin);
ev100_remap = clamp(ev100_remap, 0.0, 127.0);
int3 ev100_idx = (int3)ev100_remap;
float3 ev100_lerp = ev100_remap - ev100_idx;
float3 ev100_remapped;
ev100_remapped.r = _ToonEvAdjustmentValueArray[ev100_idx.r] + (_ToonEvAdjustmentValueArray[ev100_idx.r + 1] - _ToonEvAdjustmentValueArray[ev100_idx.r]) * ev100_lerp.r;
ev100_remapped.g = _ToonEvAdjustmentValueArray[ev100_idx.g] + (_ToonEvAdjustmentValueArray[ev100_idx.g + 1] - _ToonEvAdjustmentValueArray[ev100_idx.g]) * ev100_lerp.g;
ev100_remapped.b = _ToonEvAdjustmentValueArray[ev100_idx.b] + (_ToonEvAdjustmentValueArray[ev100_idx.b + 1] - _ToonEvAdjustmentValueArray[ev100_idx.b]) * ev100_lerp.b;
float3 resultColor = ConvertFromEV100(ev100_remapped);
return resultColor;
}
else // else is neccessary to avoid warrnings.
{
return originalColor;
}
}
// ----------------------------------------------------------------------------
// Transform
// ----------------------------------------------------------------------------

View File

@@ -5,7 +5,7 @@
#ifndef UCTS_HDRP_INCLUDED
#define UCTS_HDRP_INCLUDED
#define UCTS_HDRP 1
#include "Packages/com.misaki.hdrp-toon/Runtime/HDRP/Shaders/Includes/Common/UtsCommon.hlsl"
#define UTS_LAYER_VISIBILITY
@@ -201,19 +201,26 @@ UtsBSDFData ConvertUTSSurfaceDataToUTSBSDFData(UTSSurfaceData surfaceData)
UtsBSDFData output;
output.materialFeatures = surfaceData.materialFeatures;
output.diffuseColor = UtsComputeDiffuseColor(surfaceData.baseColor, surfaceData.metallic, 0.05);
output.firstShadingDiffuseColor = UtsComputeDiffuseColor(surfaceData.firstShadingColor, surfaceData.metallic, 0.05);
output.secondShadingDiffuseColor = UtsComputeDiffuseColor(surfaceData.secondShadingColor, surfaceData.metallic, 0.05);
float albedoIntensity = max(0.1, (1 - sqrt(surfaceData.metallic)) * (1.7 - 0.7 * (1 - sqrt(surfaceData.metallic))));
output.diffuseColor = albedoIntensity * surfaceData.baseColor;
output.firstShadingDiffuseColor = albedoIntensity * surfaceData.firstShadingColor;
output.secondShadingDiffuseColor = albedoIntensity * surfaceData.secondShadingColor;
output.fresnel0 = ComputeFresnel0(surfaceData.baseColor, surfaceData.metallic,0.22);
#if _PBR_MODE_OFF
output.fresnel0 = surfaceData.baseColor;
#else
output.fresnel0 = ComputeFresnel0(surfaceData.baseColor, surfaceData.metallic, 0.22);
#endif
output.fresnel90 = ComputeF90(output.fresnel0);
output.reflectivity = (1.0 - 0.22) * (1 - surfaceData.metallic);
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;
@@ -242,10 +249,12 @@ PreLightData GetPreLightData_UTS(float3 V, PositionInputs posInput, inout UtsBSD
// Handle IBL + area light + multiscattering.
// Note: use the not modified by anisotropy iblPerceptualRoughness here.
float specularReflectivity;
GetPreIntegratedFGDGGXAndDisneyDiffuse(clampedNdotV, preLightData.iblPerceptualRoughness, bsdfData.fresnel0, bsdfData.fresnel90, preLightData.specularFGD, preLightData.diffuseFGD, specularReflectivity);
#ifdef USE_DIFFUSE_LAMBERT_BRDF
float specularReflectivity = 1.0;
#if _PBR_MODE_OFF
preLightData.diffuseFGD = 1.0;
preLightData.specularFGD = 1.0;
#else
GetPreIntegratedFGDGGXAndDisneyDiffuse(clampedNdotV, preLightData.iblPerceptualRoughness, bsdfData.fresnel0, bsdfData.fresnel90, preLightData.specularFGD, preLightData.diffuseFGD, specularReflectivity);
#endif
#ifdef LIT_USE_GGX_ENERGY_COMPENSATION
@@ -262,23 +271,18 @@ PreLightData GetPreLightData_UTS(float3 V, PositionInputs posInput, inout UtsBSD
float3 iblN;
// We avoid divergent evaluation of the GGX, as that nearly doubles the cost.
// If the tile has anisotropy, all the pixels within the tile are evaluated as anisotropic.
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
{
float TdotV = dot(bsdfData.tangentWS, V);
float BdotV = dot(bsdfData.bitangentWS, V);
#if _PBR_MODE_ANISOTROPY
float TdotV = dot(bsdfData.tangentWS, V);
float BdotV = dot(bsdfData.bitangentWS, V);
preLightData.partLambdaV = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, clampedNdotV, bsdfData.roughnessT, bsdfData.roughnessB);
preLightData.partLambdaV = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, clampedNdotV, bsdfData.roughnessT, bsdfData.roughnessB);
// perceptualRoughness is use as input and output here
GetGGXAnisotropicModifiedNormalAndRoughness(bsdfData.bitangentWS, bsdfData.tangentWS, N, V, bsdfData.anisotropy, preLightData.iblPerceptualRoughness, iblN, preLightData.iblPerceptualRoughness);
}
else
{
preLightData.partLambdaV = GetSmithJointGGXPartLambdaV(clampedNdotV, bsdfData.roughnessT);
iblN = N;
}
// perceptualRoughness is use as input and output here
GetGGXAnisotropicModifiedNormalAndRoughness(bsdfData.bitangentWS, bsdfData.tangentWS, N, V, bsdfData.anisotropy, preLightData.iblPerceptualRoughness, iblN, preLightData.iblPerceptualRoughness);
#else
preLightData.partLambdaV = GetSmithJointGGXPartLambdaV(clampedNdotV, bsdfData.roughnessT);
iblN = N;
#endif
preLightData.iblR = reflect(-V, iblN);
@@ -305,22 +309,9 @@ PreLightData GetPreLightData_UTS(float3 V, PositionInputs posInput, inout UtsBSD
preLightData.ltcTransformCoat = SampleLtcMatrix(CLEAR_COAT_PERCEPTUAL_ROUGHNESS, clampedNdotV, LTCLIGHTINGMODEL_GGX);
}
// refraction (forward only)
#if HAS_REFRACTION
RefractionModelResult refraction = REFRACTION_MODEL(V, posInput, bsdfData);
preLightData.transparentRefractV = refraction.rayWS;
preLightData.transparentPositionWS = refraction.positionWS;
preLightData.transparentTransmittance = exp(-bsdfData.absorptionCoefficient * refraction.dist);
// Empirical remap to try to match a bit the refraction probe blurring for the fallback
// Use IblPerceptualRoughness so we can handle approx of clear coat.
preLightData.transparentSSMipLevel = PositivePow(preLightData.iblPerceptualRoughness, 1.3) * uint(max(_ColorPyramidLodCount - 1, 0));
#endif
return preLightData;
}
// Legacy for compatibility with existing shaders
inline bool IsGammaSpace()
{

View File

@@ -19,7 +19,7 @@ float StepFeatherToon(float value,float step,float feather)
return saturate((value - step + feather) / feather);
}
float3 ComputeSpecularTerm(float3 V, float3 L, UtsBSDFData bsdfData)
float3 ComputeSpecularTerm(UtsBSDFData bsdfData, PreLightData preLightData, float3 V, float3 L)
{
#ifdef _PBR_MODE_OFF
return 0;
@@ -29,56 +29,51 @@ float3 ComputeSpecularTerm(float3 V, float3 L, UtsBSDFData bsdfData)
float3 H = normalize(L + V);
float NdotL = dot(N, L);
float NdotV = dot(N, V);
float clampedNdotV = ClampNdotV(NdotV);
float clampedNdotL = saturate(NdotL);
float flippedNdotL = ComputeWrappedDiffuseLighting(-NdotL, TRANSMISSION_WRAP_LIGHT);
float diffuseNdotL = clampedNdotL;
float LdotV = dot(L, V);
float NdotH = saturate(dot(N, H));
float HdotL = saturate(dot(H, L));
float3 F = F_Schlick(bsdfData.fresnel0, bsdfData.fresnel90, HdotL);
float clampedNdotV = ClampNdotV(preLightData.NdotV);
float clampedNdotL = saturate(NdotL);
float partLambdaV;
float3 DV = 0;
#ifdef _PBR_MODE_STANDARD
partLambdaV = GetSmithJointGGXPartLambdaV(clampedNdotV, bsdfData.roughnessT);
// We use abs(NdotL) to handle the none case of double sided
DV = DV_SmithJointGGX(NdotH, abs(NdotL), clampedNdotV, bsdfData.roughnessT, partLambdaV);
#ifdef _PBR_MODE_STANDARD
partLambdaV = GetSmithJointGGXPartLambdaV(clampedNdotV, bsdfData.roughnessT);
// We use abs(NdotL) to handle the none case of double sided
DV = DV_SmithJointGGX(NdotH, abs(NdotL), clampedNdotV, bsdfData.roughnessT, partLambdaV);
#elif _PBR_MODE_ANISOTROPY
float TdotV = dot(bsdfData.tangentWS, V);
float BdotV = dot(bsdfData.bitangentWS, V);
ConvertAnisotropyToRoughness(bsdfData.perceptualRoughness, bsdfData.anisotropy, bsdfData.roughnessT, bsdfData.roughnessB);
partLambdaV = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, clampedNdotV, bsdfData.roughnessT, bsdfData.roughnessB);
// For anisotropy we must not saturate these values
float TdotH = dot(bsdfData.tangentWS, H);
float TdotL = dot(bsdfData.tangentWS, L);
float BdotH = dot(bsdfData.bitangentWS, H);
float BdotL = dot(bsdfData.bitangentWS, L);
#elif _PBR_MODE_ANISOTROPY
float TdotV = dot(bsdfData.tangentWS, V);
float BdotV = dot(bsdfData.bitangentWS, V);
ConvertAnisotropyToRoughness(bsdfData.perceptualRoughness, bsdfData.anisotropy, bsdfData.roughnessT, bsdfData.roughnessB);
partLambdaV = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, clampedNdotV, bsdfData.roughnessT, bsdfData.roughnessB);
// For anisotropy we must not saturate these values
float TdotH = dot(bsdfData.tangentWS, H);
float TdotL = dot(bsdfData.tangentWS, L);
float BdotH = dot(bsdfData.bitangentWS, H);
float BdotL = dot(bsdfData.bitangentWS, L);
// We use abs(NdotL) to handle the none case of double sided
DV = DV_SmithJointGGXAniso(TdotH, BdotH, NdotH, clampedNdotV, TdotL, BdotL, abs(NdotL), bsdfData.roughnessT, bsdfData.roughnessB, partLambdaV);
// We use abs(NdotL) to handle the none case of double sided
DV = DV_SmithJointGGXAniso(TdotH, BdotH, NdotH, clampedNdotV, TdotL, BdotL, abs(NdotL), bsdfData.roughnessT, bsdfData.roughnessB, partLambdaV);
#elif _PBR_MODE_HAIR
float3 t = ShiftTangent(bsdfData.bitangentWS, N, bsdfData.anisotropy);
float specularExponent = RoughnessToBlinnPhongSpecularExponent(PerceptualRoughnessToRoughness(bsdfData.coatRoughness));
DV = D_KajiyaKay(t, H, specularExponent);
#elif _PBR_MODE_HAIR
float3 t = ShiftTangent(bsdfData.bitangentWS, N, bsdfData.anisotropy);
float specularExponent = RoughnessToBlinnPhongSpecularExponent(PerceptualRoughnessToRoughness(bsdfData.coatRoughness));
DV = D_KajiyaKay(t, H, specularExponent);
float normalizeSpec = DV * rcp(specularExponent + 2) * 2 * PI;
//DV *= StepFeatherToon(normalizeSpec,specularStep,specularFeather);
DV = DV * normalizeSpec * _KKColor.rgb;
#elif _PBR_MODE_TOON
float specularExponent = RoughnessToBlinnPhongSpecularExponent(PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness));
specTerm = pow(NdotH, 5.0 * specularExponent);
specTerm = StepFeatherToon(specTerm, _ToonSpecularStep, _ToonSpecularFeather);
return specTerm * ColorSpaceDielectricSpec.rgb * clampedNdotL;
#endif
float normalizeSpec = DV * rcp(specularExponent + 2) * 2 * PI;
//DV *= StepFeatherToon(normalizeSpec,specularStep,specularFeather);
DV = DV * normalizeSpec * _KKColor.rgb;
#elif _PBR_MODE_TOON
float specularExponent = RoughnessToBlinnPhongSpecularExponent(PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness));
DV = pow(NdotH, 5.0 * specularExponent);
DV = StepFeatherToon(DV, _ToonSpecularStep, _ToonSpecularFeather);
//specTerm = pow(NdotH, 5.0 * specularExponent);
//specTerm = StepFeatherToon(specTerm, _ToonSpecularStep, _ToonSpecularFeather);
//return specTerm * ColorSpaceDielectricSpec.rgb * clampedNdotL;
#endif
specTerm = DV * F;
specTerm = DV * preLightData.specularFGD;
specTerm = specTerm * clampedNdotL;
return specTerm;