From eacbbc9b8b7962804ff6b2f9024b4872c1b47f66 Mon Sep 17 00:00:00 2001 From: Misaki Date: Tue, 4 Feb 2025 21:21:44 +0900 Subject: [PATCH] Organize folder structure; Update RimLighting; --- Runtime/Shaders/HDRPToon.shader | 4 - Runtime/Shaders/Includes/Common/UtsHead.hlsl | 4 - .../Shaders/Includes/Common/UtsLitData.hlsl | 224 +++++++++--------- .../Common/UtsSurfaceFeatureEvaluation.hlsl | 54 +++++ .../UtsSurfaceFeatureEvaluation.hlsl.meta | 7 + Runtime/Shaders/Includes/Deprecated.meta | 8 + .../ShaderPassForwardUTS.hlsl | 0 .../ShaderPassForwardUTS.hlsl.meta | 0 .../ShadingMainLight.hlsl | 0 .../ShadingMainLight.hlsl.meta | 0 .../ShadingOtherLight.hlsl | 0 .../ShadingOtherLight.hlsl.meta | 0 .../UtsAreaLight.hlsl | 0 .../UtsAreaLight.hlsl.meta | 0 .../{Lighting => Deprecated}/UtsEnvLight.hlsl | 0 .../UtsEnvLight.hlsl.meta | 0 .../UtsSelfShadowMainLight.hlsl | 0 .../UtsSelfShadowMainLight.hlsl.meta | 0 .../Includes/Lighting/UtsLightEvaluation.hlsl | 3 +- .../Includes/Lighting/UtsLightLoop.hlsl | 4 +- .../UtsMaterialEvaluation.hlsl | 107 +-------- .../UtsMaterialEvaluation.hlsl.meta | 0 .../Lighting/UtsShadowEvaluation.hlsl | 47 ++++ .../UTSToonmapping/UTSTonemapping.cs | 3 +- 24 files changed, 249 insertions(+), 216 deletions(-) create mode 100644 Runtime/Shaders/Includes/Common/UtsSurfaceFeatureEvaluation.hlsl create mode 100644 Runtime/Shaders/Includes/Common/UtsSurfaceFeatureEvaluation.hlsl.meta create mode 100644 Runtime/Shaders/Includes/Deprecated.meta rename Runtime/Shaders/Includes/{ShaderPass => Deprecated}/ShaderPassForwardUTS.hlsl (100%) rename Runtime/Shaders/Includes/{ShaderPass => Deprecated}/ShaderPassForwardUTS.hlsl.meta (100%) rename Runtime/Shaders/Includes/{Lighting => Deprecated}/ShadingMainLight.hlsl (100%) rename Runtime/Shaders/Includes/{Lighting => Deprecated}/ShadingMainLight.hlsl.meta (100%) rename Runtime/Shaders/Includes/{Lighting => Deprecated}/ShadingOtherLight.hlsl (100%) rename Runtime/Shaders/Includes/{Lighting => Deprecated}/ShadingOtherLight.hlsl.meta (100%) rename Runtime/Shaders/Includes/{Lighting => Deprecated}/UtsAreaLight.hlsl (100%) rename Runtime/Shaders/Includes/{Lighting => Deprecated}/UtsAreaLight.hlsl.meta (100%) rename Runtime/Shaders/Includes/{Lighting => Deprecated}/UtsEnvLight.hlsl (100%) rename Runtime/Shaders/Includes/{Lighting => Deprecated}/UtsEnvLight.hlsl.meta (100%) rename Runtime/Shaders/Includes/{Lighting => Deprecated}/UtsSelfShadowMainLight.hlsl (100%) rename Runtime/Shaders/Includes/{Lighting => Deprecated}/UtsSelfShadowMainLight.hlsl.meta (100%) rename Runtime/Shaders/Includes/{Common => Lighting}/UtsMaterialEvaluation.hlsl (60%) rename Runtime/Shaders/Includes/{Common => Lighting}/UtsMaterialEvaluation.hlsl.meta (100%) diff --git a/Runtime/Shaders/HDRPToon.shader b/Runtime/Shaders/HDRPToon.shader index 54b07b6..5db9530 100644 --- a/Runtime/Shaders/HDRPToon.shader +++ b/Runtime/Shaders/HDRPToon.shader @@ -1,7 +1,3 @@ -//Unity Toon Shader/HDRP -//nobuyuki@unity3d.com -//toshiyuki@unity3d.com (Universal RP/HDRP) - Shader "HDRP/Toon" { Properties diff --git a/Runtime/Shaders/Includes/Common/UtsHead.hlsl b/Runtime/Shaders/Includes/Common/UtsHead.hlsl index df1bff0..46729ad 100644 --- a/Runtime/Shaders/Includes/Common/UtsHead.hlsl +++ b/Runtime/Shaders/Includes/Common/UtsHead.hlsl @@ -1,7 +1,3 @@ -//Unity Toon Shader/HDRP -//nobuyuki@unity3d.com -//toshiyuki@unity3d.com (Universal RP/HDRP) - #ifndef UCTS_HDRP_INCLUDED #define UCTS_HDRP_INCLUDED diff --git a/Runtime/Shaders/Includes/Common/UtsLitData.hlsl b/Runtime/Shaders/Includes/Common/UtsLitData.hlsl index 5c4e88f..bad8071 100644 --- a/Runtime/Shaders/Includes/Common/UtsLitData.hlsl +++ b/Runtime/Shaders/Includes/Common/UtsLitData.hlsl @@ -1,35 +1,38 @@ -float ADD_IDX(UtsGetSurfaceData)(FragInputs input, LayerTexCoord layerTexCoord, out SurfaceData surfaceData, +#ifndef UTS_LIT_DATA +#define UTS_LIT_DATA + +float UtsGetSurfaceData(FragInputs input, LayerTexCoord layerTexCoord, out SurfaceData surfaceData, out float3 normalTS, out float3 bentNormalTS) { float3 detailNormalTS = float3(0.0, 0.0, 0.0); float detailMask = 0.0; - #ifdef _DETAIL_MAP_IDX +#ifdef _DETAIL_MAP_IDX detailMask = 1.0; - #ifdef _MASKMAP_IDX - detailMask = SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_MaskMap), SAMPLER_MASKMAP_IDX, ADD_IDX(layerTexCoord.base)).b; - #endif +#ifdef _MASKMAP_IDX + detailMask = SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_MaskMap), SAMPLER_MASKMAP_IDX, ADD_IDX(layerTexCoord.base)).b; +#endif float2 detailAlbedoAndSmoothness = SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_DetailMap), SAMPLER_DETAILMAP_IDX, ADD_IDX(layerTexCoord.details)).rb; float detailAlbedo = detailAlbedoAndSmoothness.r * 2.0 - 1.0; float detailSmoothness = detailAlbedoAndSmoothness.g * 2.0 - 1.0; // Resample the detail map but this time for the normal map. This call should be optimize by the compiler // We split both call due to trilinear mapping detailNormalTS = SAMPLE_UVMAPPING_NORMALMAP_AG(ADD_IDX(_DetailMap), SAMPLER_DETAILMAP_IDX, ADD_IDX(layerTexCoord.details), ADD_IDX(_DetailNormalScale)); - #endif +#endif float4 color = SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_BaseColorMap), ADD_ZERO_IDX(sampler_BaseColorMap), ADD_IDX(layerTexCoord.base)).rgba * ADD_IDX(_BaseColor).rgba; surfaceData.baseColor = color.rgb; float alpha = 1.0f; - #ifdef DEBUG_DISPLAY +#ifdef DEBUG_DISPLAY if (_DebugMipMapMode == DEBUGMIPMAPMODE_NONE) - #endif +#endif { alpha = color.a; alpha = lerp(ADD_IDX(_AlphaRemapMin), ADD_IDX(_AlphaRemapMax), alpha); } - #ifdef _DETAIL_MAP_IDX +#ifdef _DETAIL_MAP_IDX // Goal: we want the detail albedo map to be able to darken down to black and brighten up to white the surface albedo. // The scale control the speed of the gradient. We simply remap detailAlbedo from [0..1] to [-1..1] then perform a lerp to black or white // with a factor based on speed. @@ -39,7 +42,7 @@ float ADD_IDX(UtsGetSurfaceData)(FragInputs input, LayerTexCoord layerTexCoord, baseColorOverlay *= baseColorOverlay; // Lerp with details mask surfaceData.baseColor = lerp(surfaceData.baseColor, saturate(baseColorOverlay), detailMask); - #endif +#endif surfaceData.specularOcclusion = 1.0; // Will be setup outside of this function @@ -50,120 +53,121 @@ float ADD_IDX(UtsGetSurfaceData)(FragInputs input, LayerTexCoord layerTexCoord, normalTS = ADD_IDX(GetNormalTS)(input, layerTexCoord, detailNormalTS, detailMask); bentNormalTS = ADD_IDX(GetBentNormalTS)(input, layerTexCoord, normalTS, detailNormalTS, detailMask); - #if _PBR_MODE_OFF - surfaceData.perceptualSmoothness = 1; - #else +#if _PBR_MODE_OFF + surfaceData.perceptualSmoothness = 0.0; +#else #if defined(_MASKMAP_IDX) surfaceData.perceptualSmoothness = SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_MaskMap), SAMPLER_MASKMAP_IDX, ADD_IDX(layerTexCoord.base)).a; surfaceData.perceptualSmoothness = lerp(ADD_IDX(_SmoothnessRemapMin), ADD_IDX(_SmoothnessRemapMax), surfaceData.perceptualSmoothness); - #else +#else surfaceData.perceptualSmoothness = ADD_IDX(_Smoothness); - #endif - #endif +#endif +#endif - #ifdef _DETAIL_MAP_IDX +#ifdef _DETAIL_MAP_IDX // See comment for baseColorOverlay float smoothnessDetailSpeed = saturate(abs(detailSmoothness) * ADD_IDX(_DetailSmoothnessScale)); float smoothnessOverlay = lerp(surfaceData.perceptualSmoothness, (detailSmoothness < 0.0) ? 0.0 : 1.0, smoothnessDetailSpeed); // Lerp with details mask surfaceData.perceptualSmoothness = lerp(surfaceData.perceptualSmoothness, saturate(smoothnessOverlay), detailMask); - #endif +#endif - #if _PBR_MODE_OFF - surfaceData.metallic = 0; +#if _PBR_MODE_OFF + surfaceData.metallic = 0.0; + surfaceData.ambientOcclusion = 1.0; #else // MaskMap is RGBA: Metallic, Ambient Occlusion (Optional), detail Mask (Optional), Smoothness - #ifdef _MASKMAP_IDX +#ifdef _MASKMAP_IDX surfaceData.metallic = SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_MaskMap), SAMPLER_MASKMAP_IDX, ADD_IDX(layerTexCoord.base)).r; surfaceData.metallic = lerp(ADD_IDX(_MetallicRemapMin), ADD_IDX(_MetallicRemapMax), surfaceData.metallic); surfaceData.ambientOcclusion = SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_MaskMap), SAMPLER_MASKMAP_IDX, ADD_IDX(layerTexCoord.base)).g; surfaceData.ambientOcclusion = lerp(ADD_IDX(_AORemapMin), ADD_IDX(_AORemapMax), surfaceData.ambientOcclusion); - #else +#else surfaceData.metallic = ADD_IDX(_Metallic); surfaceData.ambientOcclusion = 1.0; - #endif - #endif +#endif +#endif surfaceData.diffusionProfileHash = asuint(ADD_IDX(_DiffusionProfileHash)); surfaceData.subsurfaceMask = ADD_IDX(_SubsurfaceMask); surfaceData.transmissionMask = ADD_IDX(_TransmissionMask); - #ifdef _SUBSURFACE_MASK_MAP_IDX +#ifdef _SUBSURFACE_MASK_MAP_IDX surfaceData.subsurfaceMask *= SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_SubsurfaceMaskMap), SAMPLER_SUBSURFACE_MASK_MAP_IDX, ADD_IDX(layerTexCoord.base)).r; - #endif - #ifdef _TRANSMISSION_MASK_MAP_IDX +#endif +#ifdef _TRANSMISSION_MASK_MAP_IDX surfaceData.transmissionMask *= SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_TransmissionMaskMap), SAMPLER_TRANSMISSION_MASK_MAP_IDX, ADD_IDX(layerTexCoord.base)).r; - #endif +#endif - #ifdef _THICKNESSMAP_IDX +#ifdef _THICKNESSMAP_IDX surfaceData.thickness = SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_ThicknessMap), SAMPLER_THICKNESSMAP_IDX, ADD_IDX(layerTexCoord.base)).r; surfaceData.thickness = ADD_IDX(_ThicknessRemap).x + ADD_IDX(_ThicknessRemap).y * surfaceData.thickness; - #else +#else surfaceData.thickness = ADD_IDX(_Thickness); - #endif +#endif // This part of the code is not used in case of layered shader but we keep the same macro system for simplicity - #if !defined(LAYERED_LIT_SHADER) +#if !defined(LAYERED_LIT_SHADER) // These static material feature allow compile time optimization surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD; - #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING +#ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING; - #endif - #ifdef _MATERIAL_FEATURE_TRANSMISSION +#endif +#ifdef _MATERIAL_FEATURE_TRANSMISSION surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION; - #endif +#endif #ifdef _MATERIAL_FEATURE_ANISOTROPY surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY; - #endif +#endif #ifdef _MATERIAL_FEATURE_CLEAR_COAT surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT; - #endif +#endif #ifdef _MATERIAL_FEATURE_IRIDESCENCE surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE; - #endif - #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR +#endif +#ifdef _MATERIAL_FEATURE_SPECULAR_COLOR surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR; - #endif +#endif - #ifdef _TANGENTMAP - #ifdef _NORMALMAP_TANGENT_SPACE_IDX // Normal and tangent use same space +#ifdef _TANGENTMAP +#ifdef _NORMALMAP_TANGENT_SPACE_IDX // Normal and tangent use same space // Tangent space vectors always use only 2 channels. float3 tangentTS = UnpackNormalmapRGorAG(SAMPLE_UVMAPPING_TEXTURE2D(_TangentMap, sampler_TangentMap, layerTexCoord.base), 1.0); surfaceData.tangentWS = TransformTangentToWorld(tangentTS, input.tangentToWorld); - #else // Object space +#else // Object space // Note: There is no such a thing like triplanar with object space normal, so we call directly 2D function float3 tangentOS = UnpackNormalRGB(SAMPLE_TEXTURE2D(_TangentMapOS, sampler_TangentMapOS, layerTexCoord.base.uv), 1.0); surfaceData.tangentWS = TransformObjectToWorldNormal(tangentOS); - #endif - #else +#endif +#else // Note we don't normalize tangentWS either with a tangentmap above or using the interpolated tangent from the TBN frame // as it will be normalized later with a call to Orthonormalize(): surfaceData.tangentWS = input.tangentToWorld[0].xyz; // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT - #endif +#endif - #ifdef _ANISOTROPYMAP +#ifdef _ANISOTROPYMAP surfaceData.anisotropy = SAMPLE_UVMAPPING_TEXTURE2D(_AnisotropyMap, sampler_AnisotropyMap, layerTexCoord.base).r; - #else +#else surfaceData.anisotropy = 1.0; - #endif +#endif surfaceData.anisotropy *= ADD_IDX(_Anisotropy); surfaceData.specularColor = _SpecularColor.rgb; - #ifdef _SPECULARCOLORMAP +#ifdef _SPECULARCOLORMAP surfaceData.specularColor *= SAMPLE_UVMAPPING_TEXTURE2D(_SpecularColorMap, sampler_SpecularColorMap, layerTexCoord.base).rgb; - #endif +#endif #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR // Require to have setup baseColor // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it surfaceData.baseColor *= _EnergyConservingSpecularColor > 0.0 ? (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b)) : 1.0; - #endif +#endif - #if HAS_REFRACTION +#if HAS_REFRACTION if (_EnableSSRefraction) { surfaceData.ior = _Ior; @@ -185,36 +189,36 @@ float ADD_IDX(UtsGetSurfaceData)(FragInputs input, LayerTexCoord layerTexCoord, surfaceData.transmittanceMask = 0.0; alpha = 1.0; } - #else +#else surfaceData.ior = 1.0; surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0); surfaceData.atDistance = 1.0; surfaceData.transmittanceMask = 0.0; - #endif +#endif - #ifdef _MATERIAL_FEATURE_CLEAR_COAT +#ifdef _MATERIAL_FEATURE_CLEAR_COAT surfaceData.coatMask = _CoatMask; // To shader feature for keyword to limit the variant surfaceData.coatMask *= SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_CoatMaskMap), ADD_ZERO_IDX(sampler_CoatMaskMap), ADD_IDX(layerTexCoord.base)).r; - #else +#else surfaceData.coatMask = 0.0; - #endif +#endif - #ifdef _MATERIAL_FEATURE_IRIDESCENCE - #ifdef _IRIDESCENCE_THICKNESSMAP +#ifdef _MATERIAL_FEATURE_IRIDESCENCE +#ifdef _IRIDESCENCE_THICKNESSMAP surfaceData.iridescenceThickness = SAMPLE_UVMAPPING_TEXTURE2D(_IridescenceThicknessMap, sampler_IridescenceThicknessMap, layerTexCoord.base).r; surfaceData.iridescenceThickness = _IridescenceThicknessRemap.x + _IridescenceThicknessRemap.y * surfaceData.iridescenceThickness; - #else +#else surfaceData.iridescenceThickness = _IridescenceThickness; - #endif +#endif surfaceData.iridescenceMask = _IridescenceMask; surfaceData.iridescenceMask *= SAMPLE_UVMAPPING_TEXTURE2D(_IridescenceMaskMap, sampler_IridescenceMaskMap, layerTexCoord.base).r; - #else +#else surfaceData.iridescenceThickness = 0.0; surfaceData.iridescenceMask = 0.0; - #endif +#endif - #else // #if !defined(LAYERED_LIT_SHADER) +#else // #if !defined(LAYERED_LIT_SHADER) // Mandatory to setup value to keep compiler quiet @@ -236,7 +240,7 @@ float ADD_IDX(UtsGetSurfaceData)(FragInputs input, LayerTexCoord layerTexCoord, surfaceData.atDistance = 1000000.0; surfaceData.transmittanceMask = 0.0; - #endif // #if !defined(LAYERED_LIT_SHADER) +#endif // #if !defined(LAYERED_LIT_SHADER) return alpha; } @@ -248,16 +252,16 @@ void UtsGetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInput // and UV1 is corrupt when we use surface gradient. In case UV1 aren't required we set them to 0, so we ensure there is no garbage. // When using lightmaps, the uv1 is always valid but we don't update _UVMappingMask.y to 1 // So when we are using them, we just need to keep the UVs as is. - #if !defined(LIGHTMAP_ON) && defined(SURFACE_GRADIENT) +#if !defined(LIGHTMAP_ON) && defined(SURFACE_GRADIENT) input.texCoord1 = (_UVMappingMask.y + _UVDetailsMappingMask.y + _UVMappingMaskEmissive.y) > 0 ? input.texCoord1 : 0; - #endif +#endif // Don't dither if displaced tessellation (we're fading out the displacement instead to match the next LOD) - #if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT) - #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group +#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT) +#ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x); - #endif - #endif +#endif +#endif float3 doubleSidedConstants = GetDoubleSidedConstants(); @@ -267,33 +271,33 @@ void UtsGetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInput ZERO_INITIALIZE(LayerTexCoord, layerTexCoord); GetLayerTexCoord(input, layerTexCoord); - #if !defined(SHADER_STAGE_RAY_TRACING) +#if !defined(SHADER_STAGE_RAY_TRACING) float depthOffset = ApplyPerPixelDisplacement(input, V, layerTexCoord); - #ifdef _DEPTHOFFSET_ON +#ifdef _DEPTHOFFSET_ON ApplyDepthOffsetPositionInput(V, depthOffset, GetViewForwardDir(), GetWorldToHClipMatrix(), posInput); - #endif - #else +#endif +#else float depthOffset = 0.0; - #endif +#endif - #if defined(_ALPHATEST_ON) +#if defined(_ALPHATEST_ON) float alphaTex = SAMPLE_UVMAPPING_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, layerTexCoord.base).a; alphaTex = lerp(_AlphaRemapMin, _AlphaRemapMax, alphaTex); float alphaValue = alphaTex * _BaseColor.a; // Perform alha test very early to save performance (a killed pixel will not sample textures) - #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS +#if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS float alphaCutoff = _AlphaCutoffPrepass; - #elif SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_POSTPASS +#elif SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_POSTPASS float alphaCutoff = _AlphaCutoffPostpass; - #elif (SHADERPASS == SHADERPASS_SHADOWS) || (SHADERPASS == SHADERPASS_RAYTRACING_VISIBILITY) +#elif (SHADERPASS == SHADERPASS_SHADOWS) || (SHADERPASS == SHADERPASS_RAYTRACING_VISIBILITY) float alphaCutoff = _UseShadowThreshold ? _AlphaCutoffShadow : _AlphaCutoff; - #else +#else float alphaCutoff = _AlphaCutoff; - #endif +#endif GENERIC_ALPHA_TEST(alphaValue, alphaCutoff); - #endif +#endif // We perform the conversion to world of the normalTS outside of the GetSurfaceData // so it allow us to correctly deal with detail normal map and optimize the code for the layered shaders @@ -306,83 +310,85 @@ void UtsGetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInput surfaceData.geomNormalWS = input.tangentToWorld[2]; surfaceData.specularOcclusion = 1.0; - #ifdef DECAL_NORMAL_BLENDING +#ifdef DECAL_NORMAL_BLENDING if (_EnableDecals) { - #ifndef SURFACE_GRADIENT +#ifndef SURFACE_GRADIENT normalTS = SurfaceGradientFromTangentSpaceNormalAndFromTBN(normalTS, input.tangentToWorld[0], input.tangentToWorld[1]); - #endif +#endif DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, input, alpha); ApplyDecalToSurfaceData(decalSurfaceData, input.tangentToWorld[2], surfaceData, normalTS); } GetNormalWS_SG(input, normalTS, surfaceData.normalWS, doubleSidedConstants); - #else +#else GetNormalWS(input, normalTS, surfaceData.normalWS, doubleSidedConstants); - #if HAVE_DECALS +#if HAVE_DECALS if (_EnableDecals) { // Both uses and modifies 'surfaceData.normalWS'. DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, input, alpha); ApplyDecalToSurfaceData(decalSurfaceData, input.tangentToWorld[2], surfaceData); } - #endif - #endif +#endif +#endif // Use bent normal to sample GI if available - #ifdef _BENTNORMALMAP +#ifdef _BENTNORMALMAP GetNormalWS(input, bentNormalTS, bentNormalWS, doubleSidedConstants); - #else +#else bentNormalWS = surfaceData.normalWS; - #endif +#endif - #if defined(DEBUG_DISPLAY) - #if !defined(SHADER_STAGE_RAY_TRACING) +#if defined(DEBUG_DISPLAY) +#if !defined(SHADER_STAGE_RAY_TRACING) // Mipmap mode debugging isn't supported with ray tracing as it relies on derivatives if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE) { surfaceData.baseColor = GET_TEXTURE_STREAMING_DEBUG(posInput.positionSS, input.texCoord0); surfaceData.metallic = 0; } - #endif +#endif // We need to call ApplyDebugToSurfaceData after filling the surfaceData and before filling builtinData // as it can modify attribute use for static lighting ApplyDebugToSurfaceData(input.tangentToWorld, surfaceData); - #endif +#endif // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion. // If user provide bent normal then we process a better term - #if defined(_SPECULAR_OCCLUSION_FROM_BENT_NORMAL_MAP) +#if defined(_SPECULAR_OCCLUSION_FROM_BENT_NORMAL_MAP) // If we have bent normal and ambient occlusion, process a specular occlusion surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness)); // Don't do spec occ from Ambient if there is no mask mask - #elif defined(_MASKMAP) && !defined(_SPECULAR_OCCLUSION_NONE) +#elif defined(_MASKMAP) && !defined(_SPECULAR_OCCLUSION_NONE) surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness)); - #endif +#endif // This is use with anisotropic material surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS); - #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING) +#if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING) // Specular AA - #ifdef PROJECTED_SPACE_NDF_FILTERING +#ifdef PROJECTED_SPACE_NDF_FILTERING surfaceData.perceptualSmoothness = ProjectedSpaceGeometricNormalFiltering(surfaceData.perceptualSmoothness, input.tangentToWorld[2], _SpecularAAScreenSpaceVariance, _SpecularAAThreshold); - #else +#else surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, input.tangentToWorld[2], _SpecularAAScreenSpaceVariance, _SpecularAAThreshold); - #endif - #endif +#endif +#endif // Caution: surfaceData must be fully initialize before calling GetBuiltinData GetBuiltinData(input, V, posInput, surfaceData, alpha, bentNormalWS, depthOffset, layerTexCoord.base, builtinData); - #ifdef _ALPHATEST_ON +#ifdef _ALPHATEST_ON // Used for sharpening by alpha to mask builtinData.alphaClipTreshold = alphaCutoff; - #endif +#endif RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS } + +#endif \ No newline at end of file diff --git a/Runtime/Shaders/Includes/Common/UtsSurfaceFeatureEvaluation.hlsl b/Runtime/Shaders/Includes/Common/UtsSurfaceFeatureEvaluation.hlsl new file mode 100644 index 0000000..f99deff --- /dev/null +++ b/Runtime/Shaders/Includes/Common/UtsSurfaceFeatureEvaluation.hlsl @@ -0,0 +1,54 @@ +#ifndef UTS_SURFACE_FEATURE_EVALUATION +#define UTS_SURFACE_FEATURE_EVALUATION + +// Rim light is calculated per light +float3 UtsEvaluateColor_RimLight(PositionInputs posInput, UtsBSDFData bsdfData, PreLightData preLightData, float3 L, float3 lightColor) +{ + float clampNdotV = ClampNdotV(preLightData.NdotV); + float rimLightWeight = 1.0 - clampNdotV; + rimLightWeight = pow(rimLightWeight, exp2(lerp(3.0, 0.0, _RimLightLevel))); + + float3 normalVS = normalize(mul((float3x3)UNITY_MATRIX_V, bsdfData.geomNormalWS)); + float2 depthUV = posInput.positionNDC.xy + normalVS * (_RimLightLevel * 0.05 / posInput.linearDepth); + float offsetedDepth = SampleCameraDepth(depthUV); + float depthDiff = saturate(posInput.deviceDepth - offsetedDepth); + + float halfLambert = 0.5 * dot(bsdfData.normalWS, L) + 0.5; + //float rimLightMask = lerp(0.5 * lambert + 0.5, saturate(lambert), _Tweak_LightDirection_MaskLevel * 2.0); + float rimLightMask = saturate(smoothstep(_Tweak_LightDirection_MaskLevel, 1.0, halfLambert)); + + rimLightWeight = step(0.0025 / posInput.linearDepth, depthDiff); + float3 outColor = rimLightWeight * lightColor * _RimLightColor * _RimLightStrength; + return outColor * rimLightMask; +} + +DirectLighting UtsEvaluateAngelRing(FragInputs input, float3 normalWS, float3 V) +{ + DirectLighting lighting; + ZERO_INITIALIZE(DirectLighting, lighting); + + // Should we scroll the angel ring texture on x? + float3 cameraRight = UNITY_MATRIX_V[0].xyz; + float3 cameraFront = UNITY_MATRIX_V[2].xyz; + float3 upVector = float3(0, 1, 0); + float3 rightAxis = cross(cameraFront, upVector); + float cameraRightMagnitude = sqrt(cameraRight.x * cameraRight.x + cameraRight.y * cameraRight.y + cameraRight.z * cameraRight.z); + float rightAxisMagnitude = sqrt(rightAxis.x * rightAxis.x + rightAxis.y * rightAxis.y + rightAxis.z * rightAxis.z); + float cameraRollCos = dot(rightAxis, cameraRight) / (rightAxisMagnitude * cameraRightMagnitude); + float3 cameraRoll = acos(clamp(cameraRollCos, -1.0, 1.0)); + float cameraDir = cameraRight.y < 0 ? -1.0 : 1.0; + + float2 arOffsetU = lerp(mul(UNITY_MATRIX_V, float4(normalWS, 0)).xyz, float3(0, 0, 1), _AngelRingOffsetU).xy; + arOffsetU = arOffsetU * 0.5 + 0.5; + float2 arvnRotate = RotateUV(arOffsetU, -(cameraDir * cameraRoll), 0.5, 1.0); + float2 arOffsetUV = float2(arvnRotate.x, lerp(input.texCoord0.y, arvnRotate.y, _AngelRingOffsetV)); + float4 angelRingColor = SAMPLE_TEXTURE2D(_AngelRingColorMap, sampler_AngelRingColorMap, TRANSFORM_TEX(arOffsetUV, _AngelRingColorMap)) * _AngelRingColor * _AngelRingIntensity; + + float weight = saturate(dot(normalize(V), normalWS)); + + lighting.specular += angelRingColor.r * angelRingColor.a * weight; + + return lighting; +} + +#endif \ No newline at end of file diff --git a/Runtime/Shaders/Includes/Common/UtsSurfaceFeatureEvaluation.hlsl.meta b/Runtime/Shaders/Includes/Common/UtsSurfaceFeatureEvaluation.hlsl.meta new file mode 100644 index 0000000..bd7f6ad --- /dev/null +++ b/Runtime/Shaders/Includes/Common/UtsSurfaceFeatureEvaluation.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0719f4875020bca4b8ccebbb1c92041f +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Shaders/Includes/Deprecated.meta b/Runtime/Shaders/Includes/Deprecated.meta new file mode 100644 index 0000000..634f19c --- /dev/null +++ b/Runtime/Shaders/Includes/Deprecated.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b4b440fa5514bff4089187ae3b07b338 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Shaders/Includes/ShaderPass/ShaderPassForwardUTS.hlsl b/Runtime/Shaders/Includes/Deprecated/ShaderPassForwardUTS.hlsl similarity index 100% rename from Runtime/Shaders/Includes/ShaderPass/ShaderPassForwardUTS.hlsl rename to Runtime/Shaders/Includes/Deprecated/ShaderPassForwardUTS.hlsl diff --git a/Runtime/Shaders/Includes/ShaderPass/ShaderPassForwardUTS.hlsl.meta b/Runtime/Shaders/Includes/Deprecated/ShaderPassForwardUTS.hlsl.meta similarity index 100% rename from Runtime/Shaders/Includes/ShaderPass/ShaderPassForwardUTS.hlsl.meta rename to Runtime/Shaders/Includes/Deprecated/ShaderPassForwardUTS.hlsl.meta diff --git a/Runtime/Shaders/Includes/Lighting/ShadingMainLight.hlsl b/Runtime/Shaders/Includes/Deprecated/ShadingMainLight.hlsl similarity index 100% rename from Runtime/Shaders/Includes/Lighting/ShadingMainLight.hlsl rename to Runtime/Shaders/Includes/Deprecated/ShadingMainLight.hlsl diff --git a/Runtime/Shaders/Includes/Lighting/ShadingMainLight.hlsl.meta b/Runtime/Shaders/Includes/Deprecated/ShadingMainLight.hlsl.meta similarity index 100% rename from Runtime/Shaders/Includes/Lighting/ShadingMainLight.hlsl.meta rename to Runtime/Shaders/Includes/Deprecated/ShadingMainLight.hlsl.meta diff --git a/Runtime/Shaders/Includes/Lighting/ShadingOtherLight.hlsl b/Runtime/Shaders/Includes/Deprecated/ShadingOtherLight.hlsl similarity index 100% rename from Runtime/Shaders/Includes/Lighting/ShadingOtherLight.hlsl rename to Runtime/Shaders/Includes/Deprecated/ShadingOtherLight.hlsl diff --git a/Runtime/Shaders/Includes/Lighting/ShadingOtherLight.hlsl.meta b/Runtime/Shaders/Includes/Deprecated/ShadingOtherLight.hlsl.meta similarity index 100% rename from Runtime/Shaders/Includes/Lighting/ShadingOtherLight.hlsl.meta rename to Runtime/Shaders/Includes/Deprecated/ShadingOtherLight.hlsl.meta diff --git a/Runtime/Shaders/Includes/Lighting/UtsAreaLight.hlsl b/Runtime/Shaders/Includes/Deprecated/UtsAreaLight.hlsl similarity index 100% rename from Runtime/Shaders/Includes/Lighting/UtsAreaLight.hlsl rename to Runtime/Shaders/Includes/Deprecated/UtsAreaLight.hlsl diff --git a/Runtime/Shaders/Includes/Lighting/UtsAreaLight.hlsl.meta b/Runtime/Shaders/Includes/Deprecated/UtsAreaLight.hlsl.meta similarity index 100% rename from Runtime/Shaders/Includes/Lighting/UtsAreaLight.hlsl.meta rename to Runtime/Shaders/Includes/Deprecated/UtsAreaLight.hlsl.meta diff --git a/Runtime/Shaders/Includes/Lighting/UtsEnvLight.hlsl b/Runtime/Shaders/Includes/Deprecated/UtsEnvLight.hlsl similarity index 100% rename from Runtime/Shaders/Includes/Lighting/UtsEnvLight.hlsl rename to Runtime/Shaders/Includes/Deprecated/UtsEnvLight.hlsl diff --git a/Runtime/Shaders/Includes/Lighting/UtsEnvLight.hlsl.meta b/Runtime/Shaders/Includes/Deprecated/UtsEnvLight.hlsl.meta similarity index 100% rename from Runtime/Shaders/Includes/Lighting/UtsEnvLight.hlsl.meta rename to Runtime/Shaders/Includes/Deprecated/UtsEnvLight.hlsl.meta diff --git a/Runtime/Shaders/Includes/Lighting/UtsSelfShadowMainLight.hlsl b/Runtime/Shaders/Includes/Deprecated/UtsSelfShadowMainLight.hlsl similarity index 100% rename from Runtime/Shaders/Includes/Lighting/UtsSelfShadowMainLight.hlsl rename to Runtime/Shaders/Includes/Deprecated/UtsSelfShadowMainLight.hlsl diff --git a/Runtime/Shaders/Includes/Lighting/UtsSelfShadowMainLight.hlsl.meta b/Runtime/Shaders/Includes/Deprecated/UtsSelfShadowMainLight.hlsl.meta similarity index 100% rename from Runtime/Shaders/Includes/Lighting/UtsSelfShadowMainLight.hlsl.meta rename to Runtime/Shaders/Includes/Deprecated/UtsSelfShadowMainLight.hlsl.meta diff --git a/Runtime/Shaders/Includes/Lighting/UtsLightEvaluation.hlsl b/Runtime/Shaders/Includes/Lighting/UtsLightEvaluation.hlsl index 474bbfe..842f327 100644 --- a/Runtime/Shaders/Includes/Lighting/UtsLightEvaluation.hlsl +++ b/Runtime/Shaders/Includes/Lighting/UtsLightEvaluation.hlsl @@ -9,8 +9,7 @@ #define SATURATE_BASE_COLOR_IF_SDR(x) saturate(x) #endif -#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Common/UtsMaterialEvaluation.hlsl" -#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Lighting/UtsShadowEvaluation.hlsl" +#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Lighting/UtsMaterialEvaluation.hlsl" const float rateR = 0.299; const float rateG = 0.587; diff --git a/Runtime/Shaders/Includes/Lighting/UtsLightLoop.hlsl b/Runtime/Shaders/Includes/Lighting/UtsLightLoop.hlsl index 02fbc49..cd918b8 100644 --- a/Runtime/Shaders/Includes/Lighting/UtsLightLoop.hlsl +++ b/Runtime/Shaders/Includes/Lighting/UtsLightLoop.hlsl @@ -3,8 +3,10 @@ #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/PhysicalCamera.hlsl" -#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Lighting/UtsLightEvaluation.hlsl" + #include "Packages/com.misaki.hdrp-toon/Runtime/Models/SurfaceFeature.cs.hlsl" +#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Common/UtsSurfaceFeatureEvaluation.hlsl" +#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Lighting/UtsLightEvaluation.hlsl" // Channel mask enum. // this must be same to UI cs code diff --git a/Runtime/Shaders/Includes/Common/UtsMaterialEvaluation.hlsl b/Runtime/Shaders/Includes/Lighting/UtsMaterialEvaluation.hlsl similarity index 60% rename from Runtime/Shaders/Includes/Common/UtsMaterialEvaluation.hlsl rename to Runtime/Shaders/Includes/Lighting/UtsMaterialEvaluation.hlsl index 6a324c0..146a67a 100644 --- a/Runtime/Shaders/Includes/Common/UtsMaterialEvaluation.hlsl +++ b/Runtime/Shaders/Includes/Lighting/UtsMaterialEvaluation.hlsl @@ -3,6 +3,8 @@ #define ColorSpaceDielectricSpec half4(0.22, 0.22, 0.22, 0.779) +#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Lighting/UtsShadowEvaluation.hlsl" + struct UtsShadeMask { float baseShadeMask; @@ -111,53 +113,6 @@ 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(_SDFShadingMap, sampler_SDFShadingMap, uv).rgb; - float3 right_SDFTex = SAMPLE_TEXTURE2D(_SDFShadingMap, sampler_SDFShadingMap, right_uv).rgb; - - float2 leftVector = normalize(mul(UNITY_MATRIX_M, float4(1.0, 0.0, 0.0, 0.0)).xz); - float2 forwardVector = normalize(mul(UNITY_MATRIX_M, float4(0.0, 0.0, 1.0, 0.0)).xz); - - float2 lightDirection = normalize(L.xz); - angle = saturate(dot(forwardVector, lightDirection) * -1.0 + _SDFShadowLevel); - bool isRightSide = dot(lightDirection, leftVector) > 0; - - return isRightSide ? right_SDFTex : left_SDFTex; -} - -float GetHairShadow(PositionInputs posInput, float3 L) -{ - float shadow = 1.0; - - // 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))); - - if (hairShadowOpacity > 0.0) - { - 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 = (posInput.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.xy; // 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_linear_clamp_sampler, scaledUVs).r; - float shadowMask = 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. - shadow = lerp(1, 1.0 - hairShadowOpacity, shadowMask); - } - - return shadow; -} - DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, PreLightData preLightData, SHADOW_TYPE shadow, float3 lightColor, float3 V, float3 L, float2 uv, float diffuseDimmer, float specularDimmer) @@ -183,7 +138,7 @@ DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, Pr float3 diffuseTerm = 0.0; float3 specularTerm = ComputeSpecularTerm(bsdfData, preLightData, V, L); #if _USE_SHADING_RAMP_MAP_ON - #if _SHADING_MODE_STANDARD + #if _SHADING_MODE_STANDARD float NdotL = dot(bsdfData.normalWS, L); float halfLambert = 0.5 * NdotL + 0.5; @@ -191,14 +146,14 @@ DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, Pr diffuseTerm = bsdfData.diffuseColor * rampColor; specularTerm *= saturate(NdotL) * shadow; - #elif _SHADING_MODE_SDF + #elif _SHADING_MODE_SDF float3 rampColor = SAMPLE_TEXTURE2D_ARRAY_LOD(_ShadingRampMap, s_linear_clamp_sampler, float2(sdfShadowMask * shadow.x, 0.0), _ShadingIndex, 0.0).rgb; diffuseTerm = bsdfData.diffuseColor * rampColor; specularTerm = (specularTerm + sdfHighlight) * sdfShadowMask * shadow; - #endif + #endif #else - #if _SHADING_MODE_STANDARD + #if _SHADING_MODE_STANDARD float NdotL = dot(bsdfData.normalWS, L); float halfLambert = 0.5 * NdotL + 0.5; @@ -211,60 +166,24 @@ DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, Pr diffuseTerm = lerp(lerp(bsdfData.secondShadingDiffuseColor, bsdfData.firstShadingDiffuseColor, firstShadeMask), bsdfData.diffuseColor, baseShadeMask); specularTerm *= baseShadeMask; - #elif _SHADING_MODE_SDF + #elif _SHADING_MODE_SDF float shadeMask = sdfShadowMask * sdfTexture.b * shadow; diffuseTerm = lerp(bsdfData.firstShadingDiffuseColor, bsdfData.diffuseColor, shadeMask); specularTerm = (specularTerm + sdfHighlight) * shadeMask; - #endif + #endif #endif lighting.diffuse += diffuseTerm * lightColor * diffuseDimmer; lighting.specular += specularTerm * lightColor * specularDimmer; + + if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_RIM_LIGHT)) + { + lighting.diffuse += UtsEvaluateColor_RimLight(posInput, bsdfData, preLightData, L, lightColor); + } } return lighting; } -float3 UtsEvaluateRimLight(UtsBSDFData bsdfData, PreLightData preLightData, float3 L, float3 lightColor) -{ - float clampNdotV = ClampNdotV(preLightData.NdotV); - float rimLightWeight = 1.0 - clampNdotV; - rimLightWeight = pow(rimLightWeight, exp2(lerp(3.0, 0.0, _RimLightLevel))); - - float3 rimlightColor = rimLightWeight * _RimLightColor * _RimLightStrength; - - float3 outColor = rimlightColor; - return outColor; -} - -DirectLighting UtsEvaluateAngelRing(FragInputs input, float3 normalWS, float3 V) -{ - DirectLighting lighting; - ZERO_INITIALIZE(DirectLighting, lighting); - - // Should we scroll the angel ring texture on x? - float3 cameraRight = UNITY_MATRIX_V[0].xyz; - float3 cameraFront = UNITY_MATRIX_V[2].xyz; - float3 upVector = float3(0, 1, 0); - float3 rightAxis = cross(cameraFront, upVector); - float cameraRightMagnitude = sqrt(cameraRight.x * cameraRight.x + cameraRight.y * cameraRight.y + cameraRight.z * cameraRight.z); - float rightAxisMagnitude = sqrt(rightAxis.x * rightAxis.x + rightAxis.y * rightAxis.y + rightAxis.z * rightAxis.z); - float cameraRollCos = dot(rightAxis, cameraRight) / (rightAxisMagnitude * cameraRightMagnitude); - float3 cameraRoll = acos(clamp(cameraRollCos, -1.0, 1.0)); - float cameraDir = cameraRight.y < 0 ? -1.0 : 1.0; - - float2 arOffsetU = lerp(mul(UNITY_MATRIX_V, float4(normalWS, 0)).xyz, float3(0, 0, 1), _AngelRingOffsetU).xy; - arOffsetU = arOffsetU * 0.5 + 0.5; - float2 arvnRotate = RotateUV(arOffsetU, -(cameraDir * cameraRoll), 0.5, 1.0); - float2 arOffsetUV = float2(arvnRotate.x, lerp(input.texCoord0.y, arvnRotate.y, _AngelRingOffsetV)); - float4 angelRingColor = SAMPLE_TEXTURE2D(_AngelRingColorMap, sampler_AngelRingColorMap, TRANSFORM_TEX(arOffsetUV, _AngelRingColorMap)) * _AngelRingColor * _AngelRingIntensity; - - float weight = saturate(dot(normalize(V), normalWS)); - - lighting.specular += angelRingColor.r * angelRingColor.a * weight; - - return lighting; -} - #endif \ No newline at end of file diff --git a/Runtime/Shaders/Includes/Common/UtsMaterialEvaluation.hlsl.meta b/Runtime/Shaders/Includes/Lighting/UtsMaterialEvaluation.hlsl.meta similarity index 100% rename from Runtime/Shaders/Includes/Common/UtsMaterialEvaluation.hlsl.meta rename to Runtime/Shaders/Includes/Lighting/UtsMaterialEvaluation.hlsl.meta diff --git a/Runtime/Shaders/Includes/Lighting/UtsShadowEvaluation.hlsl b/Runtime/Shaders/Includes/Lighting/UtsShadowEvaluation.hlsl index 05d05db..67736a6 100644 --- a/Runtime/Shaders/Includes/Lighting/UtsShadowEvaluation.hlsl +++ b/Runtime/Shaders/Includes/Lighting/UtsShadowEvaluation.hlsl @@ -10,6 +10,53 @@ float3 UtsGetShadowNormal(UtsBSDFData bsdfData) #endif } +float3 SampleSDFTexture(float3 L, float2 uv, out float angle) +{ + float2 right_uv = float2(1 - uv.x, uv.y); + float3 left_SDFTex = SAMPLE_TEXTURE2D(_SDFShadingMap, sampler_SDFShadingMap, uv).rgb; + float3 right_SDFTex = SAMPLE_TEXTURE2D(_SDFShadingMap, sampler_SDFShadingMap, right_uv).rgb; + + float2 leftVector = normalize(mul(UNITY_MATRIX_M, float4(1.0, 0.0, 0.0, 0.0)).xz); + float2 forwardVector = normalize(mul(UNITY_MATRIX_M, float4(0.0, 0.0, 1.0, 0.0)).xz); + + float2 lightDirection = normalize(L.xz); + angle = saturate(dot(forwardVector, lightDirection) * -1.0 + _SDFShadowLevel); + bool isRightSide = dot(lightDirection, leftVector) > 0; + + return isRightSide ? right_SDFTex : left_SDFTex; +} + +float GetHairShadow(PositionInputs posInput, float3 L) +{ + float shadow = 1.0; + + // 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))); + + if (hairShadowOpacity > 0.0) + { + 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 = (posInput.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.xy; // 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_linear_clamp_sampler, scaledUVs).r; + float shadowMask = 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. + shadow = lerp(1, 1.0 - hairShadowOpacity, shadowMask); + } + + return shadow; +} + // distances = {d, d^2, 1/d, d_proj}, where d_proj = dot(lightToSample, light.forward). SHADOW_TYPE UtsEvaluateShadow_Punctual(LightLoopContext lightLoopContext, PositionInputs posInput, LightData light, BuiltinData builtinData, float3 N, float3 L, float4 distances) { diff --git a/Runtime/UTS Renderer/UTSToonmapping/UTSTonemapping.cs b/Runtime/UTS Renderer/UTSToonmapping/UTSTonemapping.cs index 5137192..2baca39 100644 --- a/Runtime/UTS Renderer/UTSToonmapping/UTSTonemapping.cs +++ b/Runtime/UTS Renderer/UTSToonmapping/UTSTonemapping.cs @@ -13,7 +13,6 @@ public sealed class UTSTonemapping : CustomPostProcessVolumeComponent, IPostProc public bool IsActive() => _material != null && state.value; - // Do not forget to add this post process in the Custom Post Process Orders list (Project Settings > Graphics > HDRP Global Settings). public override CustomPostProcessInjectionPoint injectionPoint => CustomPostProcessInjectionPoint.AfterPostProcess; const string Shader_Name = "Hidden/Shader/UTSTonemapping"; @@ -38,7 +37,7 @@ public sealed class UTSTonemapping : CustomPostProcessVolumeComponent, IPostProc } _material.SetTexture("_MainTex", source); - HDUtils.DrawFullScreen(cmd, _material, destination, shaderPassId: 0); + HDUtils.DrawFullScreen(cmd, _material, destination); } public override void Cleanup()