Added UtsEvaluateBSDF_MatCapDiffuse;
Added UtsEvaluateBSDF_MatCapSpecular;
This commit is contained in:
@@ -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
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user