Compare commits
3 Commits
b1ef8afc8d
...
e6b58cb321
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6b58cb321 | ||
|
|
12a03e9c3c | ||
|
|
b838223551 |
@@ -16,6 +16,10 @@ namespace Misaki.HdrpToon.Editor
|
||||
|
||||
private SerializedObject _customSettings;
|
||||
|
||||
private SerializedProperty _hairShadowSetting;
|
||||
private SerializedProperty _hairBlendingSetting;
|
||||
private SerializedProperty _outlineSetting;
|
||||
|
||||
public UTSRendererSettingProvider(string path, SettingsScope scopes, IEnumerable<string> keywords = null) : base(path, scopes, keywords)
|
||||
{
|
||||
}
|
||||
@@ -23,15 +27,19 @@ namespace Misaki.HdrpToon.Editor
|
||||
public override void OnActivate(string searchContext, VisualElement rootElement)
|
||||
{
|
||||
_customSettings = UTSRenderPassSettings.GetSerializedSettings();
|
||||
|
||||
_hairShadowSetting = _customSettings.FindProperty("hairShadowSetting");
|
||||
_hairBlendingSetting = _customSettings.FindProperty("hairBlendingSetting");
|
||||
_outlineSetting = _customSettings.FindProperty("outlineSetting");
|
||||
}
|
||||
|
||||
public override void OnGUI(string searchContext)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
EditorGUILayout.PropertyField(_customSettings.FindProperty("hairShadowSetting"), Styles.hairShadow);
|
||||
EditorGUILayout.PropertyField(_customSettings.FindProperty("hairBlendingSetting"), Styles.hairBlending);
|
||||
EditorGUILayout.PropertyField(_customSettings.FindProperty("outlineSetting"), Styles.outline);
|
||||
EditorGUILayout.PropertyField(_hairShadowSetting, Styles.hairShadow);
|
||||
EditorGUILayout.PropertyField(_hairBlendingSetting, Styles.hairBlending);
|
||||
EditorGUILayout.PropertyField(_outlineSetting, Styles.outline);
|
||||
_customSettings.ApplyModifiedPropertiesWithoutUndo();
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
|
||||
@@ -17,11 +17,16 @@ namespace Misaki.HdrpToon
|
||||
private bool _initialized = false;
|
||||
private bool _srpCallbackInitialized = false;
|
||||
|
||||
[SerializeField]
|
||||
private HDAdditionalLightData _bindingSourceLightData;
|
||||
[SerializeField]
|
||||
private HDAdditionalLightData _targetBoxLightData;
|
||||
|
||||
[SerializeField]
|
||||
private uint _layerMask;
|
||||
[SerializeField]
|
||||
private Light _bindingSourceLight;
|
||||
[SerializeField]
|
||||
private Light _targetBoxLight;
|
||||
|
||||
public Transform trackedTransform;
|
||||
@@ -159,11 +164,6 @@ namespace Misaki.HdrpToon
|
||||
Release();
|
||||
}
|
||||
|
||||
private void UpdateObjectLightLayers()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
internal static GameObject CreateBoxLight(Transform transform)
|
||||
{
|
||||
if (transform == null)
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
//nobuyuki@unity3d.com
|
||||
//toshiyuki@unity3d.com (Universal RP/HDRP)
|
||||
|
||||
#define APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
|
||||
|
||||
#if SHADERPASS != SHADERPASS_FORWARD
|
||||
#error SHADERPASS_is_not_correctly_define
|
||||
#endif
|
||||
@@ -14,7 +16,8 @@
|
||||
#endif
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoopDef.hlsl"
|
||||
#include "EnvLighting.hlsl"
|
||||
#include "UtsEnvLighting.hlsl"
|
||||
#include "UtsAreaLight.hlsl"
|
||||
#include "HDRPToonFunction.hlsl"
|
||||
|
||||
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
@@ -503,7 +506,6 @@ void Frag(PackedVaryingsToPS packedInput,
|
||||
|
||||
uint v_lightListOffset = 0;
|
||||
uint v_lightIdx = lightStart;
|
||||
float channelAlpha = 0.0f;
|
||||
[loop] // vulkan shader compiler can not unroll.
|
||||
while (v_lightListOffset < lightCount)
|
||||
{
|
||||
@@ -530,14 +532,14 @@ void Frag(PackedVaryingsToPS packedInput,
|
||||
float4 distances; // {d, d^2, 1/d, d_proj}
|
||||
GetPunctualLightVectors(posInput.positionWS, s_lightData, lightDirection, distances);
|
||||
float4 lightColor = EvaluateLight_Punctual(context, posInput, s_lightData, lightDirection, distances);
|
||||
float3 additionalLightColor = ApplyCurrentExposureMultiplier(lightColor.rgb) * lightColor.a;
|
||||
float3 additionalLightColor = ApplyCurrentExposureMultiplier(lightColor.rgb);
|
||||
const float notDirectional = 1.0f;
|
||||
|
||||
UTSLightData utsLightData;
|
||||
utsLightData.lightColor = additionalLightColor;
|
||||
utsLightData.lightDirection = lightDirection;
|
||||
utsLightData.diffuseDimmer = s_lightData.diffuseDimmer;
|
||||
utsLightData.specularDimmer = s_lightData.specularDimmer;
|
||||
utsLightData.diffuseDimmer = saturate(s_lightData.diffuseDimmer * lightColor.a);
|
||||
utsLightData.specularDimmer = saturate(s_lightData.specularDimmer * lightColor.a);
|
||||
utsLightData.shadowTint = s_lightData.shadowTint;
|
||||
utsLightData.penumbraTint = s_lightData.penumbraTint;
|
||||
|
||||
@@ -635,13 +637,13 @@ void Frag(PackedVaryingsToPS packedInput,
|
||||
float4 ltcValue;
|
||||
|
||||
// Diffuse
|
||||
ltcValue = EvaluateLTC_Area(isRectLight, center, right, up, halfWidth, halfHeight, transpose(preLightData.ltcTransformDiffuse), /*bsdfData.perceptualRoughness*/ 1.0f, s_lightData.cookieMode, s_lightData.cookieScaleOffset);
|
||||
//utsLightData.diffuseDimmer *= ltcValue.a * intensity;
|
||||
utsLightData.lightColor *= ltcValue.rgb * ltcValue.a * intensity;
|
||||
ltcValue = UTS_EvaluateLTC_Area(isRectLight, center, right, up, halfWidth, halfHeight, transpose(preLightData.ltcTransformDiffuse), /*bsdfData.perceptualRoughness*/ 1.0f, true, s_lightData.cookieMode, s_lightData.cookieScaleOffset);
|
||||
utsLightData.diffuseDimmer *= saturate(ltcValue.a * intensity);
|
||||
utsLightData.lightColor *= ltcValue.rgb;
|
||||
|
||||
// Specular
|
||||
ltcValue = EvaluateLTC_Area(isRectLight, center, right, up, halfWidth, halfHeight, transpose(preLightData.ltcTransformSpecular[0]), bsdfData.perceptualRoughness, s_lightData.cookieMode, s_lightData.cookieScaleOffset);
|
||||
utsLightData.specularDimmer *= ltcValue.a * intensity;
|
||||
ltcValue = UTS_EvaluateLTC_Area(isRectLight, center, right, up, halfWidth, halfHeight, transpose(preLightData.ltcTransformSpecular[0]), bsdfData.perceptualRoughness, false, s_lightData.cookieMode, s_lightData.cookieScaleOffset);
|
||||
utsLightData.specularDimmer *= saturate(ltcValue.a * intensity);
|
||||
|
||||
if (isRectLight)
|
||||
{
|
||||
@@ -670,162 +672,6 @@ void Frag(PackedVaryingsToPS packedInput,
|
||||
//utsAggregateLighting.directDiffuse += intensity;
|
||||
#endif
|
||||
|
||||
/*
|
||||
if(s_lightData.lightType == GPULIGHTTYPE_RECTANGLE)
|
||||
{
|
||||
#if SHADEROPTIONS_BARN_DOOR
|
||||
// Apply the barn door modification to the light data
|
||||
RectangularLightApplyBarnDoor(s_lightData, posInput.positionWS);
|
||||
#endif
|
||||
|
||||
if (dot(s_lightData.forward, unL) < FLT_EPS)
|
||||
{
|
||||
float3x3 lightToWorld = float3x3(s_lightData.right, s_lightData.up, -s_lightData.forward);
|
||||
unL = mul(unL, transpose(lightToWorld));
|
||||
|
||||
float halfWidth = s_lightData.size.x * 0.5;
|
||||
float halfHeight = s_lightData.size.y * 0.5;
|
||||
|
||||
float range = s_lightData.range;
|
||||
float3 invHalfDim = rcp(float3(range + halfWidth, range + halfHeight, range));
|
||||
|
||||
float intensity;
|
||||
// Compute the light attenuation.
|
||||
#ifdef ELLIPSOIDAL_ATTENUATION
|
||||
// The attenuation volume is an axis-aligned ellipsoid s.t.
|
||||
// r1 = (r + w / 2), r2 = (r + h / 2), r3 = r.
|
||||
intensity = EllipsoidalDistanceAttenuation(unL, invHalfDim, s_lightData.rangeAttenuationScale, s_lightData.rangeAttenuationBias);
|
||||
#else
|
||||
// The attenuation volume is an axis-aligned box s.t.
|
||||
// hX = (r + w / 2), hY = (r + h / 2), hZ = r.
|
||||
intensity = BoxDistanceAttenuation(unL, invHalfDim, s_lightData.rangeAttenuationScale, s_lightData.rangeAttenuationBias);
|
||||
#endif
|
||||
|
||||
if(intensity != 0.0f)
|
||||
{
|
||||
utsLightData.diffuseDimmer *= intensity;
|
||||
utsLightData.specularDimmer *= intensity;
|
||||
|
||||
// Translate the light s.t. the shaded point is at the origin of the coordinate system.
|
||||
s_lightData.positionRWS -= posInput.positionWS;
|
||||
|
||||
float4x3 lightVerts;
|
||||
|
||||
// TODO: some of this could be precomputed.
|
||||
lightVerts[0] = s_lightData.positionRWS + s_lightData.right * -halfWidth + s_lightData.up * -halfHeight; // LL
|
||||
lightVerts[1] = s_lightData.positionRWS + s_lightData.right * -halfWidth + s_lightData.up * halfHeight; // UL
|
||||
lightVerts[2] = s_lightData.positionRWS + s_lightData.right * halfWidth + s_lightData.up * halfHeight; // UR
|
||||
lightVerts[3] = s_lightData.positionRWS + s_lightData.right * halfWidth + s_lightData.up * -halfHeight; // LR
|
||||
|
||||
// Rotate the endpoints into the local coordinate system.
|
||||
lightVerts = mul(lightVerts, transpose(preLightData.orthoBasisViewNormal));
|
||||
|
||||
float3 ltcValue;
|
||||
|
||||
// Evaluate the diffuse part
|
||||
// Polygon irradiance in the transformed configuration.
|
||||
float4x3 LD = mul(lightVerts, preLightData.ltcTransformDiffuse);
|
||||
float3 formFactorD;
|
||||
|
||||
#ifdef APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
|
||||
formFactorD = PolygonFormFactor(LD, real3(0,0,1), 4);
|
||||
ltcValue = PolygonIrradianceFromVectorFormFactor(formFactorD);
|
||||
#else
|
||||
ltcValue = PolygonIrradiance(LD);
|
||||
#endif
|
||||
|
||||
utsLightData.diffuseDimmer *= ltcValue;
|
||||
|
||||
// Evaluate the specular part
|
||||
// Polygon irradiance in the transformed configuration.
|
||||
float4x3 LS = mul(lightVerts, preLightData.ltcTransformSpecular);
|
||||
float3 formFactorS;
|
||||
#ifdef APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
|
||||
formFactorS = PolygonFormFactor(LS, real3(0,0,1), 4);
|
||||
ltcValue = PolygonIrradianceFromVectorFormFactor(formFactorS);
|
||||
#else
|
||||
ltcValue = PolygonIrradiance(LS);
|
||||
#endif
|
||||
|
||||
utsLightData.specularDimmer *= ltcValue;
|
||||
|
||||
//Evaluate the shadow part
|
||||
float shadow;
|
||||
posInput.positionWS = posInput.positionWS + lightDirection * _ShadowBias;
|
||||
#if defined(SCREEN_SPACE_SHADOWS_ON) && !defined(_SURFACE_TYPE_TRANSPARENT)
|
||||
if ((s_lightData.screenSpaceShadowIndex & SCREEN_SPACE_SHADOW_INDEX_MASK) != INVALID_SCREEN_SPACE_SHADOW)
|
||||
{
|
||||
shadow = GetScreenSpaceShadow(posInput, s_lightData.screenSpaceShadowIndex);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
shadow = EvaluateShadow_RectArea(context, posInput, s_lightData, builtinData, GetNormalForShadowBias(bsdfData), normalize(s_lightData.positionRWS), length(s_lightData.positionRWS));
|
||||
}
|
||||
context.shadowValue = shadow;
|
||||
posInput.positionWS = posInput.positionWS - lightDirection * _ShadowBias;
|
||||
|
||||
#if defined(UTS_DEBUG_SELFSHADOW)
|
||||
|
||||
#else
|
||||
UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, s_lightData.lightType, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(s_lightData.lightType == GPULIGHTTYPE_TUBE)
|
||||
{
|
||||
float len = s_lightData.size.x;
|
||||
float3 T = s_lightData.right;
|
||||
|
||||
// Pick the major axis of the ellipsoid.
|
||||
float3 axis = s_lightData.right;
|
||||
|
||||
// We define the ellipsoid s.t. r1 = (r + len / 2), r2 = r3 = r.
|
||||
// TODO: This could be precomputed.
|
||||
float range = s_lightData.range;
|
||||
float invAspectRatio = saturate(range / (range + (0.5 * len)));
|
||||
|
||||
// Compute the light attenuation.
|
||||
float intensity = EllipsoidalDistanceAttenuation(unL, axis, invAspectRatio, s_lightData.rangeAttenuationScale, s_lightData.rangeAttenuationBias);
|
||||
|
||||
if(intensity != 0.0f)
|
||||
{
|
||||
utsLightData.diffuseDimmer *= intensity;
|
||||
utsLightData.specularDimmer *= intensity;
|
||||
|
||||
// Translate the light s.t. the shaded point is at the origin of the coordinate system.
|
||||
s_lightData.positionRWS -= posInput.positionWS;
|
||||
|
||||
// TODO: some of this could be precomputed.
|
||||
float3 P1 = s_lightData.positionRWS - T * (0.5 * len);
|
||||
float3 P2 = s_lightData.positionRWS + T * (0.5 * len);
|
||||
|
||||
// Rotate the endpoints into the local coordinate system.
|
||||
P1 = mul(P1, transpose(preLightData.orthoBasisViewNormal));
|
||||
P2 = mul(P2, transpose(preLightData.orthoBasisViewNormal));
|
||||
|
||||
// Compute the binormal in the local coordinate system.
|
||||
float3 B = normalize(cross(P1, P2));
|
||||
|
||||
float ltcValue;
|
||||
|
||||
// Evaluate the diffuse part
|
||||
ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcTransformDiffuse);
|
||||
utsLightData.diffuseDimmer *= ltcValue;
|
||||
|
||||
// Evaluate the specular part
|
||||
ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcTransformSpecular);
|
||||
utsLightData.specularDimmer *= ltcValue;
|
||||
|
||||
#if defined(UTS_DEBUG_SELFSHADOW)
|
||||
|
||||
#else
|
||||
UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, s_lightData.lightType, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
s_lightData = FetchLight(lightStart, min(++i, last));
|
||||
@@ -940,8 +786,8 @@ void Frag(PackedVaryingsToPS packedInput,
|
||||
#endif
|
||||
|
||||
// Ambient
|
||||
utsAggregateLighting.indirectDiffuse = ComputeIndirectDiffuse(posInput, bsdfData, V) * _ID_Intensity;
|
||||
utsAggregateLighting.indirectSpecular = ComputeIndirectSpecular(context, posInput, preLightData, bsdfData, surfaceData, builtinData, V) * _IR_Intensity;
|
||||
utsAggregateLighting.indirectDiffuse = EvaluateIndirectDiffuse(posInput, bsdfData, V) * _ID_Intensity;
|
||||
utsAggregateLighting.indirectSpecular = EvaluateIndirectSpecular(context, posInput, preLightData, bsdfData, surfaceData, builtinData, V) * _IR_Intensity;
|
||||
|
||||
float3 finalColorWoEmissive = AccumulateAggregateLighting(utsAggregateLighting);
|
||||
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
//nobuyuki@unity3d.com
|
||||
//toshiyuki@unity3d.com (Universal RP/HDRP)
|
||||
|
||||
#include "PBR.hlsl"
|
||||
void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLightData utsLightData, SurfaceData surfaceData, BSDFData bsdfData, int lightType, float3 i_normalDir, float notDirectional, out float channelOutAlpha, inout UTSAggregateLighting utsAggregateLighting)
|
||||
#include "UtsPBR.hlsl"
|
||||
void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLightData utsLightData, SurfaceData surfaceData, BSDFData bsdfData, int lightType, float3 i_normalDir, float notDirectional,
|
||||
out float channelOutAlpha, inout UTSAggregateLighting utsAggregateLighting)
|
||||
{
|
||||
channelOutAlpha = 1.0f;
|
||||
|
||||
@@ -48,35 +49,38 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
|
||||
shadowAttenuation = saturate(shadowAttenuation);
|
||||
#endif
|
||||
|
||||
float _HalfLambert_var = 0.5 * dot(lerp(i_normalDir, normalDirection, _Is_NormalMapToBase), lightDirection) + 0.5;
|
||||
|
||||
//v.2.0.5:
|
||||
float3 addPassLightColor;
|
||||
|
||||
if (lightType == GPULIGHTTYPE_TUBE)
|
||||
{
|
||||
addPassLightColor = (0.5f * (preLightData.diffuseFGD * utsLightData.diffuseDimmer) + 0.5f) / PI * additionalLightColor.rgb;
|
||||
addPassLightColor = (0.5f * preLightData.diffuseFGD + 0.5f) / PI * additionalLightColor.rgb;
|
||||
}
|
||||
else if (lightType == GPULIGHTTYPE_RECTANGLE)
|
||||
{
|
||||
addPassLightColor = ((preLightData.diffuseFGD * utsLightData.diffuseDimmer)) * additionalLightColor.rgb;
|
||||
addPassLightColor = preLightData.diffuseFGD * additionalLightColor.rgb;
|
||||
}
|
||||
else
|
||||
{
|
||||
addPassLightColor = (0.5f * dot(lerp(i_normalDir, normalDirection, _Is_NormalMapToBase), lightDirection) + 0.5f) * additionalLightColor.rgb ;
|
||||
addPassLightColor = _HalfLambert_var * additionalLightColor.rgb;
|
||||
}
|
||||
|
||||
float pureIntencity = max(0.001, (0.299 * additionalLightColor.r + 0.587 * additionalLightColor.g + 0.114 * additionalLightColor.b));
|
||||
float3 lightColor = max(float3(0.0, 0.0, 0.0), lerp(addPassLightColor, lerp(float3(0.0, 0.0, 0.0), min(addPassLightColor, addPassLightColor / pureIntencity), notDirectional), _Is_Filter_LightColor));
|
||||
float pureIntensity = max(0.001, (0.299 * additionalLightColor.r + 0.587 * additionalLightColor.g + 0.114 * additionalLightColor.b));
|
||||
float3 lightColor = max(float3(0.0, 0.0, 0.0), lerp(addPassLightColor, lerp(float3(0.0, 0.0, 0.0), min(addPassLightColor, addPassLightColor / pureIntensity), notDirectional), _Is_Filter_LightColor));
|
||||
float3 halfDirection = normalize(viewDirection + lightDirection); // has to be recalced here.
|
||||
//v.2.0.5:
|
||||
//v.2.0.5:
|
||||
_1st_ShadeColor_Step = saturate(_1st_ShadeColor_Step + _StepOffset);
|
||||
_2nd_ShadeColor_Step = saturate(_2nd_ShadeColor_Step + _StepOffset);
|
||||
//
|
||||
//v.2.0.5: If Added lights is directional, set 0 as _LightIntensity
|
||||
float _LightIntensity = lerp(0, (0.299 * additionalLightColor.r + 0.587 * additionalLightColor.g + 0.114 * additionalLightColor.b), notDirectional);
|
||||
float _LightIntensity = lerp(0, pureIntensity, notDirectional);
|
||||
//v.2.0.5: Filtering the high intensity zone of PointLights
|
||||
float3 Set_LightColor = lightColor;
|
||||
//
|
||||
float3 Set_BaseColor = lerp((_BaseColor.rgb * _MainTex_var.rgb * _LightIntensity), ((_BaseColor.rgb * _MainTex_var.rgb) * Set_LightColor), _Is_LightColor_Base);
|
||||
|
||||
#ifdef UTS_LAYER_VISIBILITY
|
||||
float Set_BaseColorAlpha = _BaseColorVisible;
|
||||
float4 overridingColor = lerp(_BaseColorMaskColor, float4(_BaseColorMaskColor.w, _BaseColorMaskColor.w, _BaseColorMaskColor.w, 1.0f), _ComposerMaskMode);
|
||||
@@ -85,6 +89,7 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
|
||||
Set_BaseColor *= _BaseColorVisible;
|
||||
|
||||
#endif //#ifdef UTS_LAYER_VISIBILITY
|
||||
|
||||
//v.2.0.5
|
||||
float4 _1st_ShadeMap_var = lerp(SAMPLE_TEXTURE2D(_1st_ShadeMap, sampler_BaseColorMap, TRANSFORM_TEX(Set_UV0, _1st_ShadeMap)), _MainTex_var, _Use_BaseAs1st);
|
||||
float3 Set_1st_ShadeColor = lerp((_1st_ShadeColor.rgb * _1st_ShadeMap_var.rgb * _LightIntensity), ((_1st_ShadeColor.rgb * _1st_ShadeMap_var.rgb) * Set_LightColor), _Is_LightColor_1st_Shade);
|
||||
@@ -97,6 +102,7 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
|
||||
}
|
||||
float Set_1st_ShadeAlpha = _FirstShadeVisible;
|
||||
#endif //#ifdef UTS_LAYER_VISIBILITY //v.2.0.5
|
||||
|
||||
//v.2.0.5
|
||||
float4 _2nd_ShadeMap_var = lerp(SAMPLE_TEXTURE2D(_2nd_ShadeMap, sampler_BaseColorMap, TRANSFORM_TEX(Set_UV0, _2nd_ShadeMap)), _1st_ShadeMap_var, _Use_1stAs2nd);
|
||||
float3 Set_2nd_ShadeColor = lerp((_2nd_ShadeColor.rgb * _2nd_ShadeMap_var.rgb * _LightIntensity), ((_2nd_ShadeColor.rgb * _2nd_ShadeMap_var.rgb) * Set_LightColor), _Is_LightColor_2nd_Shade);
|
||||
@@ -110,8 +116,6 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
|
||||
}
|
||||
#endif //#ifdef UTS_LAYER_VISIBILITY
|
||||
|
||||
float _HalfLambert_var = 0.5 * dot(lerp(i_normalDir, normalDirection, _Is_NormalMapToBase), lightDirection) + 0.5;
|
||||
|
||||
// //v.2.0.5:
|
||||
//SGM
|
||||
//v.2.0.6
|
||||
@@ -131,8 +135,8 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
|
||||
float _2ndColorFeatherForMask = lerp(_2nd_ShadeColor_Feather, 0.0f, max(_SecondShadeOverridden, _ComposerMaskMode));
|
||||
|
||||
//
|
||||
float Set_FinalShadowMask = saturate((1.0 + ((Set_ShadingGrade - (_1st_ShadeColor_Step - _1stColorFeatherForMask)) * (0.0 - 1.0)) / (_1st_ShadeColor_Step - (_1st_ShadeColor_Step - _1stColorFeatherForMask))));
|
||||
float Set_ShadeShadowMask = saturate((1.0 + ((Set_ShadingGrade - (_2nd_ShadeColor_Step - _2ndColorFeatherForMask)) * (0.0 - 1.0)) / (_2nd_ShadeColor_Step - (_2nd_ShadeColor_Step - _2ndColorFeatherForMask)))); // 1st and 2nd Shades Mask
|
||||
float Set_FinalShadowMask = saturate(1.0 + (Set_ShadingGrade - (_1st_ShadeColor_Step - _1stColorFeatherForMask)) * (0.0 - 1.0) / (_1st_ShadeColor_Step - (_1st_ShadeColor_Step - _1stColorFeatherForMask)));
|
||||
float Set_ShadeShadowMask = saturate(1.0 + (Set_ShadingGrade - (_2nd_ShadeColor_Step - _2ndColorFeatherForMask)) * (0.0 - 1.0) / (_2nd_ShadeColor_Step - (_2nd_ShadeColor_Step - _2ndColorFeatherForMask))); // 1st and 2nd Shades Mask
|
||||
|
||||
//SGM
|
||||
|
||||
@@ -147,11 +151,13 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
|
||||
Set_ShadeShadowMask
|
||||
),
|
||||
Set_FinalShadowMask);
|
||||
|
||||
#ifdef UTS_LAYER_VISIBILITY
|
||||
float Set_2nd_ShadeAlpha = _SecondShadeVisible;
|
||||
channelOutAlpha =
|
||||
lerp(Set_BaseColorAlpha, lerp(Set_1st_ShadeAlpha, Set_2nd_ShadeAlpha, Set_ShadeShadowMask), Set_FinalShadowMask);
|
||||
#endif
|
||||
|
||||
//v.2.0.6: Add HighColor if _Is_Filter_HiCutPointLightColor is False
|
||||
|
||||
float4 _Set_HighColorMask_var = tex2D(_Set_HighColorMask, TRANSFORM_TEX(Set_UV0, _Set_HighColorMask));
|
||||
@@ -224,22 +230,25 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
|
||||
|
||||
//Specular Term
|
||||
float3 specularTerm = 0;
|
||||
|
||||
#ifndef _PBR_Mode_OFF
|
||||
if(lightType == GPULIGHTTYPE_RECTANGLE || lightType == GPULIGHTTYPE_TUBE)
|
||||
{
|
||||
specularTerm = preLightData.specularFGD * Set_LightColor * utsLightData.specularDimmer;
|
||||
specularTerm = preLightData.specularFGD * Set_LightColor;
|
||||
#ifdef _PBR_Mode_TOON
|
||||
specularTerm = StepFeatherToon(specularTerm, _ToonSpecularStep, _ToonSpecularFeather);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
specularTerm = ComputeSpecularTerm(V, lightDirection, bsdfData) * Set_LightColor * utsLightData.specularDimmer;
|
||||
specularTerm = ComputeSpecularTerm(V, lightDirection, bsdfData) * Set_LightColor;
|
||||
}
|
||||
#endif
|
||||
|
||||
specularTerm = specularTerm * (1.0 - Set_FinalShadowMask) * PI * surfaceData.specularColor;
|
||||
diffuseTerm = diffuseTerm * albedoIntensity;
|
||||
|
||||
utsAggregateLighting.directDiffuse += diffuseTerm;
|
||||
utsAggregateLighting.directSpecular += specularTerm;
|
||||
utsAggregateLighting.directDiffuse += diffuseTerm * utsLightData.diffuseDimmer;
|
||||
utsAggregateLighting.directSpecular += specularTerm * utsLightData.specularDimmer;
|
||||
#endif // _SDFShadow
|
||||
}
|
||||
165
Runtime/HDRP/Shaders/UtsAreaLight.hlsl
Normal file
165
Runtime/HDRP/Shaders/UtsAreaLight.hlsl
Normal file
@@ -0,0 +1,165 @@
|
||||
#ifndef UTS_AREA_LIGHT_INLCUDE
|
||||
#define UTS_AREA_LIGHT_INLCUDE
|
||||
|
||||
// The output is *not* normalized by the factor of 1/TWO_PI (this is done by the PolygonFormFactor function).
|
||||
real3 UTS_ComputeEdgeFactor(real3 V1, real3 V2)
|
||||
{
|
||||
real V1oV2 = dot(V1, V2);
|
||||
real3 V1xV2 = cross(V1, V2); // Plane normal (tangent to the unit sphere)
|
||||
real sqLen = saturate(1 - V1oV2 * V1oV2); // length(V1xV2) = abs(sin(angle))
|
||||
real rcpLen = rsqrt(max(FLT_EPS, sqLen)); // Make sure it is finite
|
||||
#if 0
|
||||
real y = rcpLen * acos(V1oV2);
|
||||
#else
|
||||
// Let y[x_] = ArcCos[x] / Sqrt[1 - x^2].
|
||||
// Range reduction: since ArcCos[-x] == Pi - ArcCos[x], we only need to consider x on [0, 1].
|
||||
real x = abs(V1oV2);
|
||||
// Limit[y[x], x -> 1] == 1,
|
||||
// Limit[y[x], x -> 0] == Pi/2.
|
||||
// The approximation is exact at the endpoints of [0, 1].
|
||||
// Max. abs. error on [0, 1] is 1.33e-6 at x = 0.0036.
|
||||
// Max. rel. error on [0, 1] is 8.66e-7 at x = 0.0037.
|
||||
real y = HALF_PI + x * (-0.99991 + x * (0.783393 + x * (-0.649178 + x * (0.510589 + x * (-0.326137 + x * (0.137528 + x * -0.0270813))))));
|
||||
|
||||
if (V1oV2 < 0)
|
||||
{
|
||||
y = rcpLen * PI - y;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return V1xV2 * y;
|
||||
}
|
||||
|
||||
// Input: 3-5 vertices in the coordinate frame centered at the shaded point.
|
||||
// Output: signed vector irradiance.
|
||||
// No horizon clipping is performed.
|
||||
real3 UTS_PolygonFormFactor(real4x3 L, real3 L4, uint n, bool isDiffuse)
|
||||
{
|
||||
// The length cannot be zero since we have already checked
|
||||
// that the light has a non-zero effective area,
|
||||
// and thus its plane cannot pass through the origin.
|
||||
L[0] = normalize(L[0]);
|
||||
L[1] = normalize(L[1]);
|
||||
L[2] = normalize(L[2]);
|
||||
|
||||
switch (n)
|
||||
{
|
||||
case 3:
|
||||
L[3] = L[0];
|
||||
break;
|
||||
case 4:
|
||||
L[3] = normalize(L[3]);
|
||||
L4 = L[0];
|
||||
break;
|
||||
case 5:
|
||||
L[3] = normalize(L[3]);
|
||||
L4 = normalize(L4);
|
||||
break;
|
||||
}
|
||||
|
||||
// If the magnitudes of a pair of edge factors are
|
||||
// nearly the same, catastrophic cancellation may occur:
|
||||
// https://en.wikipedia.org/wiki/Catastrophic_cancellation
|
||||
// For the same reason, the value of the cross product of two
|
||||
// nearly collinear vectors is prone to large errors.
|
||||
// Therefore, the algorithm is inherently numerically unstable
|
||||
// for area lights that shrink to a line (or a point) after
|
||||
// projection onto the unit sphere.
|
||||
real3 F = UTS_ComputeEdgeFactor(L[0], L[1]);
|
||||
F += UTS_ComputeEdgeFactor(L[1], L[2]);
|
||||
F += UTS_ComputeEdgeFactor(L[2], L[3]);
|
||||
if (n >= 4)
|
||||
F += UTS_ComputeEdgeFactor(L[3], L4);
|
||||
if (n == 5)
|
||||
F += UTS_ComputeEdgeFactor(L4, L[0]);
|
||||
|
||||
return lerp(INV_TWO_PI * F, PI * F, isDiffuse); // The output may be projected onto the tangent plane (F.z) to yield signed irradiance.
|
||||
}
|
||||
|
||||
// See "Real-Time Area Lighting: a Journey from Research to Production", slide 102.
|
||||
// Turns out, despite the authors claiming that this function "calculates an approximation of
|
||||
// the clipped sphere form factor", that is simply not true.
|
||||
// First of all, above horizon, the function should then just return 'F.z', which it does not.
|
||||
// Secondly, if we use the correct function called DiffuseSphereLightIrradiance(), it results
|
||||
// in severe light leaking if the light is placed vertically behind the camera.
|
||||
// So this function is clearly a hack designed to work around these problems.
|
||||
real UTS_PolygonIrradianceFromVectorFormFactor(float3 F)
|
||||
{
|
||||
float l = length(F);
|
||||
return max(0, (l * l) / (l + 1));
|
||||
}
|
||||
|
||||
// Expects non-normalized vertex positions.
|
||||
// Output: F is the signed vector irradiance.
|
||||
real UTS_PolygonIrradiance(real4x3 L, bool isDiffuse, out real3 F)
|
||||
{
|
||||
//APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
|
||||
F = UTS_PolygonFormFactor(L, float3(0,0,1), 4, isDiffuse);
|
||||
return UTS_PolygonIrradianceFromVectorFormFactor(F); // Accounts for the horizon.
|
||||
}
|
||||
|
||||
float4 UTS_EvaluateLTC_Area(bool isRectLight, float3 center, float3 right, float3 up, float halfLength, float halfHeight,
|
||||
float3x3 invM, float perceptualRoughness, bool isDiffuse, int cookieMode, float4 cookieScaleOffset)
|
||||
{
|
||||
float3 ortho = cross(center, right);
|
||||
float orthoSq = dot(ortho, ortho);
|
||||
|
||||
// Check whether the light is in a vertical orientation.
|
||||
bool quit = (orthoSq == 0);
|
||||
|
||||
// Check whether the light is entirely below the surface.
|
||||
// We must test twice, since a linear transformation
|
||||
// may bring the light above the surface (a side-effect).
|
||||
quit = quit || (center.z + halfLength * abs(right.z) + halfHeight * abs(up.z) <= 0);
|
||||
|
||||
float4 ltcValue = float4(1, 1, 1, 0);
|
||||
|
||||
if (quit && !isDiffuse)
|
||||
{
|
||||
return ltcValue;
|
||||
}
|
||||
|
||||
// Perform a sparse matrix multiplication.
|
||||
float3 C = mul(invM, center);
|
||||
float3 A = mul(invM, right);
|
||||
float3 B = mul(invM, up);
|
||||
|
||||
// Check whether the light is entirely below the surface.
|
||||
// We must test twice, since a linear transformation
|
||||
// may bring the light below the surface (as expected).
|
||||
if (C.z + halfLength * abs(A.z) + halfHeight * abs(B.z) <= 0 && !isDiffuse)
|
||||
{
|
||||
return ltcValue;
|
||||
}
|
||||
|
||||
if (isRectLight)
|
||||
{
|
||||
float4x3 lightVerts;
|
||||
|
||||
lightVerts[0] = C - halfLength * A - halfHeight * B; // LL
|
||||
lightVerts[1] = lightVerts[0] + (2 * halfHeight) * B; // UL
|
||||
lightVerts[2] = lightVerts[1] + (2 * halfLength) * A; // UR
|
||||
lightVerts[3] = lightVerts[2] - (2 * halfHeight) * B; // LR
|
||||
|
||||
float3 formFactor;
|
||||
|
||||
// Polygon irradiance in the transformed configuration.
|
||||
ltcValue.a = UTS_PolygonIrradiance(lightVerts, isDiffuse, formFactor);
|
||||
|
||||
if (cookieMode != COOKIEMODE_NONE)
|
||||
{
|
||||
ltcValue.rgb = SampleAreaLightCookie(cookieScaleOffset, lightVerts, formFactor, perceptualRoughness);
|
||||
}
|
||||
}
|
||||
else // Line light
|
||||
{
|
||||
float w = ComputeLineWidthFactor(invM, ortho, orthoSq);
|
||||
|
||||
ltcValue.a = I_diffuse_line(C, A, halfLength) * w;
|
||||
}
|
||||
|
||||
return ltcValue;
|
||||
}
|
||||
|
||||
#endif
|
||||
7
Runtime/HDRP/Shaders/UtsAreaLight.hlsl.meta
Normal file
7
Runtime/HDRP/Shaders/UtsAreaLight.hlsl.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: afada69a218dd594ea0f17e7c639c533
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,3 +1,6 @@
|
||||
#ifndef UTS_ENV
|
||||
#define UTS_ENV
|
||||
|
||||
// _preIntegratedFGD and _CubemapLD are unique for each BRDF
|
||||
IndirectLighting EvaluateBSDF_Env(LightLoopContext lightLoopContext,
|
||||
float3 V, PositionInputs posInput,
|
||||
@@ -127,7 +130,7 @@ float3 ComputeFresnelLerp(float3 c0, float3 c1, float cosA)
|
||||
return lerp(c0, c1, t);
|
||||
}
|
||||
|
||||
float3 ComputeIndirectDiffuse(PositionInputs posInput, BSDFData bsdfData, float3 V)
|
||||
float3 EvaluateIndirectDiffuse(PositionInputs posInput, BSDFData bsdfData, float3 V)
|
||||
{
|
||||
float3 indirectDiffuse = 0.0;
|
||||
|
||||
@@ -184,7 +187,7 @@ float3 ComputeIndirectDiffuse(PositionInputs posInput, BSDFData bsdfData, float3
|
||||
return indirectDiffuse;
|
||||
}
|
||||
|
||||
float3 ComputeIndirectSpecular(LightLoopContext lightLoopContext, PositionInputs posInput, PreLightData preLightData, BSDFData bsdfData, SurfaceData surfaceData, BuiltinData builtinData, float3 V)
|
||||
float3 EvaluateIndirectSpecular(LightLoopContext lightLoopContext, PositionInputs posInput, PreLightData preLightData, BSDFData bsdfData, SurfaceData surfaceData, BuiltinData builtinData, float3 V)
|
||||
{
|
||||
#if defined(_PBR_Mode_OFF) || defined(_PBR_Mode_TOON)
|
||||
return 0;
|
||||
@@ -235,3 +238,5 @@ float3 ComputeIndirectSpecular(LightLoopContext lightLoopContext, PositionInputs
|
||||
return indirectSpecular;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,9 +1,12 @@
|
||||
#ifndef UTS_PBR
|
||||
#define UTS_PBR
|
||||
|
||||
#define ColorSpaceDielectricSpec half4(0.22, 0.22, 0.22, 0.779)
|
||||
|
||||
float3 schlick(float f0, float hl) {
|
||||
real x = 1.0 - hl;
|
||||
real x2 = x * x;
|
||||
real x5 = x * x2 * x2;
|
||||
float x = 1.0 - hl;
|
||||
float x2 = x * x;
|
||||
float x5 = x * x2 * x2;
|
||||
return (1.0 - f0) * x5 + f0;
|
||||
}
|
||||
|
||||
@@ -187,3 +190,4 @@ half3 FitWithCurveApprox(half NdotL, half Curvature)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user