Folder clean up;

Added Emissive;
This commit is contained in:
Misaki
2025-01-29 12:27:09 +09:00
parent 1a82022a6f
commit 018300e046
81 changed files with 120 additions and 399 deletions

View File

@@ -0,0 +1,263 @@
#ifdef DEBUG_DISPLAY // Guard define here to be compliant with how shader graph generate code for include
#ifndef UNITY_DEBUG_DISPLAY_INCLUDED
#define UNITY_DEBUG_DISPLAY_INCLUDED
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Debug.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/MaterialDebug.cs.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/LightingDebug.cs.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/MipMapDebug.cs.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/ColorPickerDebug.cs.hlsl"
// Local shader variables
static SHADOW_TYPE g_DebugShadowAttenuation = 0;
StructuredBuffer<int2> _DebugDepthPyramidOffsets;
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/PBRValidator.hlsl"
// When displaying lux meter we compress the light in order to be able to display value higher than 65504
// The sun is between 100 000 and 150 000, so we use 4 to be able to cover such a range (4 * 65504)
#define LUXMETER_COMPRESSION_RATIO 4
TEXTURE2D(_DebugFont); // Debug font to write string in shader
TEXTURE2D(_DebugMatCapTexture);
void GetPropertiesDataDebug(uint paramId, inout float3 result, inout bool needLinearToSRGB)
{
switch (paramId)
{
case DEBUGVIEWPROPERTIES_TESSELLATION:
#ifdef TESSELLATION_ON
result = float3(1.0, 0.0, 0.0);
#else
result = float3(0.0, 0.0, 0.0);
#endif
break;
case DEBUGVIEWPROPERTIES_PIXEL_DISPLACEMENT:
#ifdef _PIXEL_DISPLACEMENT // Caution: This define is related to a shader features (But it may become a standard features for HD)
result = float3(1.0, 0.0, 0.0);
#else
result = float3(0.0, 0.0, 0.0);
#endif
break;
case DEBUGVIEWPROPERTIES_VERTEX_DISPLACEMENT:
#ifdef _VERTEX_DISPLACEMENT // Caution: This define is related to a shader features (But it may become a standard features for HD)
result = float3(1.0, 0.0, 0.0);
#else
result = float3(0.0, 0.0, 0.0);
#endif
break;
case DEBUGVIEWPROPERTIES_TESSELLATION_DISPLACEMENT:
#ifdef _TESSELLATION_DISPLACEMENT // Caution: This define is related to a shader features (But it may become a standard features for HD)
result = float3(1.0, 0.0, 0.0);
#else
result = float3(0.0, 0.0, 0.0);
#endif
break;
case DEBUGVIEWPROPERTIES_DEPTH_OFFSET:
#ifdef _DEPTHOFFSET_ON // Caution: This define is related to a shader features (But it may become a standard features for HD)
result = float3(1.0, 0.0, 0.0);
#else
result = float3(0.0, 0.0, 0.0);
#endif
break;
case DEBUGVIEWPROPERTIES_LIGHTMAP:
#if defined(LIGHTMAP_ON) || defined (DIRLIGHTMAP_COMBINED) || defined(DYNAMICLIGHTMAP_ON)
result = float3(1.0, 0.0, 0.0);
#else
result = float3(0.0, 0.0, 0.0);
#endif
break;
case DEBUGVIEWPROPERTIES_INSTANCING:
#if defined(UNITY_INSTANCING_ENABLED)
result = float3(1.0, 0.0, 0.0);
#else
result = float3(0.0, 0.0, 0.0);
#endif
break;
}
}
float3 GetTextureDataDebug(uint paramId, float2 uv, Texture2D tex, float4 texelSize, float4 mipInfo, float3 originalColor)
{
float3 outColor = originalColor;
switch (paramId)
{
case DEBUGMIPMAPMODE_MIP_RATIO:
outColor = GetDebugMipColorIncludingMipReduction(originalColor, tex, texelSize, uv, mipInfo);
break;
case DEBUGMIPMAPMODE_MIP_COUNT:
outColor = GetDebugMipCountColor(originalColor, tex);
break;
case DEBUGMIPMAPMODE_MIP_COUNT_REDUCTION:
outColor = GetDebugMipReductionColor(tex, mipInfo);
break;
case DEBUGMIPMAPMODE_STREAMING_MIP_BUDGET:
outColor = GetDebugStreamingMipColor(tex, mipInfo);
break;
case DEBUGMIPMAPMODE_STREAMING_MIP:
outColor = GetDebugStreamingMipColorBlended(originalColor, tex, mipInfo);
break;
}
return outColor;
}
// DebugFont code assume black and white font with texture size 256x128 with bloc of 16x16
#define DEBUG_FONT_TEXT_WIDTH 16
#define DEBUG_FONT_TEXT_HEIGHT 16
#define DEBUG_FONT_TEXT_COUNT_X 16
#define DEBUG_FONT_TEXT_COUNT_Y 8
#define DEBUG_FONT_TEXT_ASCII_START 32
#define DEBUG_FONT_TEXT_SCALE_WIDTH 10 // This control the spacing between characters (if a character fill the text block it will overlap).
// Only support ASCII symbol from DEBUG_FONT_TEXT_ASCII_START to 126
// return black or white depends if we hit font character or not
// currentUnormCoord is current unormalized screen position
// fixedUnormCoord is the position where we want to draw something, this will be incremented by block font size in provided direction
// color is current screen color
// color of the font to use
// direction is 1 or -1 and indicate fixedUnormCoord block shift
void DrawCharacter(uint asciiValue, float3 fontColor, uint2 currentUnormCoord, inout uint2 fixedUnormCoord, inout float3 color, int direction, int fontTextScaleWidth)
{
// Are we inside a font display block on the screen ?
uint2 localCharCoord = currentUnormCoord - fixedUnormCoord;
if (localCharCoord.x >= 0 && localCharCoord.x < DEBUG_FONT_TEXT_WIDTH && localCharCoord.y >= 0 && localCharCoord.y < DEBUG_FONT_TEXT_HEIGHT)
{
localCharCoord.y = DEBUG_FONT_TEXT_HEIGHT - localCharCoord.y;
asciiValue -= DEBUG_FONT_TEXT_ASCII_START; // Our font start at ASCII table 32;
uint2 asciiCoord = uint2(asciiValue % DEBUG_FONT_TEXT_COUNT_X, asciiValue / DEBUG_FONT_TEXT_COUNT_X);
// Unorm coordinate inside the font texture
uint2 unormTexCoord = asciiCoord * uint2(DEBUG_FONT_TEXT_WIDTH, DEBUG_FONT_TEXT_HEIGHT) + localCharCoord;
// normalized coordinate
float2 normTexCoord = float2(unormTexCoord) / float2(DEBUG_FONT_TEXT_WIDTH * DEBUG_FONT_TEXT_COUNT_X, DEBUG_FONT_TEXT_HEIGHT * DEBUG_FONT_TEXT_COUNT_Y);
#if UNITY_UV_STARTS_AT_TOP
normTexCoord.y = 1.0 - normTexCoord.y;
#endif
float charColor = SAMPLE_TEXTURE2D_LOD(_DebugFont, s_point_clamp_sampler, normTexCoord, 0).r;
color = color * (1.0 - charColor) + charColor * fontColor;
}
fixedUnormCoord.x += fontTextScaleWidth * direction;
}
void DrawCharacter(uint asciiValue, float3 fontColor, uint2 currentUnormCoord, inout uint2 fixedUnormCoord, inout float3 color, int direction)
{
DrawCharacter(asciiValue, fontColor, currentUnormCoord, fixedUnormCoord, color, direction, DEBUG_FONT_TEXT_SCALE_WIDTH);
}
// Shortcut to not have to file direction
void DrawCharacter(uint asciiValue, float3 fontColor, uint2 currentUnormCoord, inout uint2 fixedUnormCoord, inout float3 color)
{
DrawCharacter(asciiValue, fontColor, currentUnormCoord, fixedUnormCoord, color, 1);
}
// Draw a signed integer
// Can't display more than 16 digit
// The two following parameter are for float representation
// leading0 is used when drawing frac part of a float to draw the leading 0 (call is in charge of it)
// forceNegativeSign is used to force to display a negative sign as -0 is not recognize
void DrawInteger(int intValue, float3 fontColor, uint2 currentUnormCoord, inout uint2 fixedUnormCoord, inout float3 color, int leading0, bool forceNegativeSign)
{
const uint maxStringSize = 16;
uint absIntValue = abs(intValue);
// 1. Get size of the number of display
int numEntries = min((intValue == 0 ? 0 : log10(absIntValue)) + ((intValue < 0 || forceNegativeSign) ? 1 : 0) + leading0, maxStringSize);
// 2. Shift curseur to last location as we will go reverse
fixedUnormCoord.x += numEntries * DEBUG_FONT_TEXT_SCALE_WIDTH;
// 3. Display the number
bool drawCharacter = true; // bit weird, but it is to appease the compiler.
for (uint j = 0; j < maxStringSize; ++j)
{
// Numeric value incurrent font start on the second row at 0
if(drawCharacter)
DrawCharacter((absIntValue % 10) + '0', fontColor, currentUnormCoord, fixedUnormCoord, color, -1);
if (absIntValue < 10)
drawCharacter = false;
absIntValue /= 10;
}
// 4. Display leading 0
if (leading0 > 0)
{
for (int i = 0; i < leading0; ++i)
{
DrawCharacter('0', fontColor, currentUnormCoord, fixedUnormCoord, color, -1);
}
}
// 5. Display sign
if (intValue < 0 || forceNegativeSign)
{
DrawCharacter('-', fontColor, currentUnormCoord, fixedUnormCoord, color, -1);
}
// 6. Reset cursor at end location
fixedUnormCoord.x += (numEntries + 2) * DEBUG_FONT_TEXT_SCALE_WIDTH;
}
void DrawInteger(int intValue, float3 fontColor, uint2 currentUnormCoord, inout uint2 fixedUnormCoord, inout float3 color)
{
DrawInteger(intValue, fontColor, currentUnormCoord, fixedUnormCoord, color, 0, false);
}
void DrawFloatExplicitPrecision(float floatValue, float3 fontColor, uint2 currentUnormCoord, uint digitCount, inout uint2 fixedUnormCoord, inout float3 color)
{
if (IsNaN(floatValue))
{
DrawCharacter('N', fontColor, currentUnormCoord, fixedUnormCoord, color);
DrawCharacter('a', fontColor, currentUnormCoord, fixedUnormCoord, color);
DrawCharacter('N', fontColor, currentUnormCoord, fixedUnormCoord, color);
}
else
{
int intValue = int(floatValue);
bool forceNegativeSign = floatValue >= 0.0f ? false : true;
DrawInteger(intValue, fontColor, currentUnormCoord, fixedUnormCoord, color, 0, forceNegativeSign);
DrawCharacter('.', fontColor, currentUnormCoord, fixedUnormCoord, color);
int fracValue = int(frac(abs(floatValue)) * pow(10, digitCount));
int leading0 = digitCount - (int(log10(fracValue)) + 1); // Counting leading0 to add in front of the float
DrawInteger(fracValue, fontColor, currentUnormCoord, fixedUnormCoord, color, leading0, false);
}
}
void DrawFloat(float floatValue, float3 fontColor, uint2 currentUnormCoord, inout uint2 fixedUnormCoord, inout float3 color)
{
DrawFloatExplicitPrecision(floatValue, fontColor, currentUnormCoord, 6, fixedUnormCoord, color);
}
// Debug rendering is performed at the end of the frame (after post-processing).
// Debug textures are never flipped upside-down automatically. Therefore, we must always flip manually.
bool ShouldFlipDebugTexture()
{
#if UNITY_UV_STARTS_AT_TOP
return (_ProjectionParams.x > 0);
#else
return (_ProjectionParams.x < 0);
#endif
}
#endif
#endif // DEBUG_DISPLAY

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 8ab1498776c236c4da0411cc76a11bf6
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,246 @@
#ifndef UTS_COMMON
#define UTS_COMMON
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#define inverselerp(a, b, x) saturate(((x) - (a)) / ((b) - (a)))
#define APPLY_WEIGHT(x, y, t) lerp(x, x * y, t)
float2 GetWHRatio()
{
return float2(_ScreenParams.y / _ScreenParams.x, 1);
}
float StepAntiAliasing(float x, float y)
{
float v = x - y;
return saturate(v / fwidth(v) + HALF_MIN); //fwidth(x) = abs(ddx(x) + ddy(x))
}
float Remap(float In, float2 InMinMax, float2 OutMinMax)
{
return OutMinMax.x + (In - InMinMax.x) * (OutMinMax.y - OutMinMax.x) / (InMinMax.y - InMinMax.x);
}
float3 ToonMaping(float3 x)
{
x = x * (2.51 * x + 0.03) / (x * (2.43 * x + 0.59) + 0.14);
return x;
}
float3 GetSmoothedWorldNormal(float2 uv, float3x3 t_tbn)
{
float3 normal = float3(uv, 0);
normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy)));
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;
}
}
void ApplyExposureAdjustment(inout float3 color)
{
color = GetExposureAdjustedColor(color);
color = ApplyCompensation(color);
}
// ----------------------------------------------------------------------------
// Transform
// ----------------------------------------------------------------------------
float3 ProjectOnPlane(float3 vec, float3 normal)
{
return vec - normal * dot(vec, normal);
}
float2 RotateUV(float2 _uv, float _radian, float2 _piv, float _time)
{
float RotateUV_ang = _radian;
float RotateUV_cos = cos(_time * RotateUV_ang);
float RotateUV_sin = sin(_time * RotateUV_ang);
return(mul(_uv - _piv, float2x2(RotateUV_cos, -RotateUV_sin, RotateUV_sin, RotateUV_cos)) + _piv);
}
// Anti-perspective form Colin: Counteract perspective effects by replacing regular depth with uniform depth
uniform float _AntiPerspectiveIntensity;
void AntiPerspective(inout float4 clipPos)
{
float centerVSz = mul(UNITY_MATRIX_V, float4(UNITY_MATRIX_M._m03_m13_m23, 1.0)).z;
clipPos.xy *= lerp(1.0, abs(clipPos.w) / - centerVSz, _AntiPerspectiveIntensity);
}
// ASE
float2 UnStereo(float2 UV)
{
#if UNITY_SINGLE_PASS_STEREO
float4 scaleOffset = unity_StereoScaleOffset[ unity_StereoEyeIndex ];
UV.xy = (UV.xy - scaleOffset.zw) / scaleOffset.xy;
#endif
return UV;
}
// ----------------------------------------------------------------------------
// Color
// ----------------------------------------------------------------------------
float3 ShiftColorPurity(float3 color, float purity)
{
return lerp(Luminance(color), color, purity);
}
void AlphaGammaCorrection(inout float a1, inout float a2, inout float a3, inout float a4)
{
float4 a = float4(a1, a2, a3, a4);
a = pow(abs(a), 1 / 1.48);
a1 = a.x;
a2 = a.y;
a3 = a.z;
a4 = a.w;
}
void AlphaGammaCorrection(inout float alpha)
{
alpha = pow(abs(alpha), 1 / 1.48);
}
void AlphaGammaCorrection(inout float alpha, inout float alpha2)
{
AlphaGammaCorrection(alpha, alpha2, alpha, alpha);
}
void AlphaGammaCorrection(inout float alpha, inout float alpha2, inout float alpha3)
{
AlphaGammaCorrection(alpha, alpha2, alpha3, alpha3);
}
// ----------------------------------------------------------------------------
// Depth
// ----------------------------------------------------------------------------
float LinearEyeDepth(float z)
{
return LinearEyeDepth(z, _ZBufferParams);
}
// https://forum.unity.com/threads/what-does-unity-exactly-do-when-we-modify-z-buffer-value-using-sv_depth.526406/
float LinearEyeDepthToOutDepth(float z)
{
return(1 - _ZBufferParams.w * z) / (_ZBufferParams.z * z);
}
// Returns the forward (Right) direction of the current view in the world space.
float3 GetViewRightDir()
{
float4x4 viewMat = GetWorldToViewMatrix();
return viewMat[0].xyz;
}
// ASE
float3 InvertDepthDirHD(float3 In)
{
float3 result = In;
#if !defined(ASE_SRP_VERSION) || ASE_SRP_VERSION <= 70301 || ASE_SRP_VERSION == 70503 || ASE_SRP_VERSION >= 80301
result *= float3(1, 1, -1);
#endif
return result;
}
float4x4 unity_CameraProjection;
float4x4 unity_CameraInvProjection;
float4x4 unity_WorldToCamera;
float4x4 unity_CameraToWorld;
// ASE
float3 GetWorldPosFromDepthBuffer(float2 clipPos01, float cameraDepth)
{
#ifdef UNITY_REVERSED_Z
float depth = (1.0 - cameraDepth);
#else
float depth = cameraDepth;
#endif
float3 screenPos_DepthBuffer = (float3(clipPos01, depth));
float4 clipPos = (float4((screenPos_DepthBuffer * 2.0 - 1.0), 1.0));
float4 viewPos = mul(unity_CameraInvProjection, clipPos);
float3 viewPosNorm = viewPos.xyz / viewPos.w;
float3 localInvertDepthDirHD = InvertDepthDirHD(viewPosNorm);
return mul(unity_CameraToWorld, float4(localInvertDepthDirHD, 1.0)).xyz;
}
#endif

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: ac88fd7420b835748990a40f42a2478f
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,593 @@
//Unity Toon Shader/HDRP
//nobuyuki@unity3d.com
//toshiyuki@unity3d.com (Universal RP/HDRP)
#ifndef UCTS_HDRP_INCLUDED
#define UCTS_HDRP_INCLUDED
#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Common/UtsCommon.hlsl"
#define UTS_LAYER_VISIBILITY
#ifndef DIRECTIONAL
# define DIRECTIONAL
#endif
#define FP_BUFFER 1
#if defined(UNITY_PASS_PREPASSBASE) || defined(UNITY_PASS_DEFERRED) || defined(UNITY_PASS_SHADOWCASTER)
#undef FOG_LINEAR
#undef FOG_EXP
#undef FOG_EXP2
#endif
#define Uts_ColorSpaceDielectricSpec half4(0.04, 0.04, 0.04, 1.0 - 0.04)
#if 1
struct UTSData
{
};
struct UTSSurfaceData
{
uint materialFeatures;
real3 baseColor;
real3 firstShadingColor;
real3 secondShadingColor;
real alpha;
float3 normalWS;
real perceptualSmoothness;
real metallic;
real specularOcclusion;
real ambientOcclusion;
real3 specularColor;
float3 geomNormalWS;
float3 tangentWS;
real4 subsurfaceColor;
real anisotropy;
};
struct UtsBSDFData
{
uint materialFeatures;
real3 diffuseColor;
real3 firstShadingDiffuseColor;
real3 secondShadingDiffuseColor;
real3 fresnel0;
real fresnel90;
real reflectivity;
real ambientOcclusion;
real specularOcclusion;
real perceptualRoughness;
real3 subsurfaceColor;
float3 geomNormalWS;
float3 normalWS;
float3 tangentWS;
float3 bitangentWS;
real anisotropy;
real roughnessT;
real roughnessB;
};
UTSSurfaceData ConvertSurfaceDataToUTSSurfaceData(SurfaceData surfaceData)
{
UTSSurfaceData output;
ZERO_INITIALIZE(UTSSurfaceData, output);
output.materialFeatures = surfaceData.materialFeatures;
output.baseColor = surfaceData.baseColor;
output.alpha = 1.0;
output.normalWS = surfaceData.normalWS;
output.perceptualSmoothness = surfaceData.perceptualSmoothness;
output.metallic = surfaceData.metallic;
output.specularOcclusion = surfaceData.specularOcclusion;
output.ambientOcclusion = surfaceData.ambientOcclusion;
output.specularColor = surfaceData.specularColor;
output.geomNormalWS = surfaceData.geomNormalWS;
output.tangentWS = surfaceData.tangentWS;
output.subsurfaceColor.rgb = surfaceData.transmittanceColor;
output.subsurfaceColor.a = surfaceData.subsurfaceMask;
output.anisotropy = surfaceData.anisotropy;
return output;
}
UTSSurfaceData GetUTSSurfaceData(FragInputs input, float3 V)
{
UTSSurfaceData output;
//ZERO_INITIALIZE(UTSSurfaceData, output);
output.materialFeatures = 0;
float4 mainTexture = SAMPLE_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap));
output.baseColor = mainTexture.rgb * _BaseColor.rgb;
output.alpha = mainTexture.a;
float4 firstShadingTexture = SAMPLE_TEXTURE2D(_1st_ShadeMap, sampler_BaseColorMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap));
float4 secondShadingTexture = SAMPLE_TEXTURE2D(_1st_ShadeMap, sampler_BaseColorMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap));
output.firstShadingColor = lerp(firstShadingTexture.rgb, mainTexture.rgb, _Use_BaseAs1st) * _1st_ShadeColor.rgb;
output.secondShadingColor = lerp(secondShadingTexture.rgb, output.firstShadingColor, _Use_1stAs2nd) * _2nd_ShadeColor.rgb;
float4 normalLocal = float4(0, 0, 1.0, 1.0);
#if _NORMAL_MAP
if (_Use_SSSLut)
{
normalLocal = SAMPLE_TEXTURE2D_LOD(_NormalMap, sampler_NormalMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap), _SSSIntensity);
}
else
{
normalLocal = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap));
normalLocal.rgb = UnpackNormalScale(normalLocal, _NormalScale);
}
#endif
float3 normalWS = normalize(mul(normalLocal.rgb, input.tangentToWorld));
#if _PBR_MODE_OFF
float smoothness = 0.0;
float metallic = 0.0;
#else
float smoothness = _Smoothness;
float metallic = _Metallic;
#endif
float ao = 1.0;
float3 specularColor = 1;
float anisotropy = 0;
#ifdef _MASK_MAP
float4 _MaskMap_var = SAMPLE_TEXTURE2D(_MaskMap, sampler_MaskMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap));
metallic = _MaskMap_var.x;
metallic = lerp(_MetallicRemapMin, _MetallicRemapMax, metallic);
ao = _MaskMap_var.y;
ao = lerp(_AORemapMin, _AORemapMax, ao);
smoothness = _MaskMap_var.w;
smoothness = lerp(_SmoothnessRemapMin, _SmoothnessRemapMax, smoothness);
#endif
#ifdef _ANISOTROPY_MAP
anisotropy = SAMPLE_TEXTURE2D(_AnisotropyMap, sampler_AnisotropyMap, TRANSFORM_TEX(input.texCoord0, _AnisotropyMap)).r;
#if _PBR_Mode_KK
anisotropy += _Anisotropy - 0.5;
#else
anisotropy *= _Anisotropy;
#endif
#else
anisotropy = 1.0;
anisotropy *= _Anisotropy;
#endif
#ifdef _PBR_Mode_KK
metallic = 0.0;
smoothness *=_BSDFContribution;
#endif
#ifdef _PBR_Mode_TOON
#ifdef _SPECULAR_COLOR_MAP
specularColor = SAMPLE_TEXTURE2D(_SpecularColorMap, sampler_SpecularColorMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap)).rgb * _SpecularColor;
#endif
specularColor = GetSpecularColor(_MainTex_var.rgb * _BaseColor.rgb, metallic);
#endif
output.metallic = metallic;
output.ambientOcclusion = ao;
output.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(dot(normalWS, V), ao, PerceptualRoughnessToRoughness(1 - smoothness));
output.perceptualSmoothness = smoothness;
output.normalWS = normalWS;
output.specularColor = specularColor;
output.geomNormalWS = input.tangentToWorld[2];
output.tangentWS = Orthonormalize(input.tangentToWorld[0].rgb, normalWS);
output.subsurfaceColor = SAMPLE_TEXTURE2D(_SSSLutMap, sampler_MainTex, TRANSFORM_TEX(input.texCoord0, _BaseColorMap)) * _SSSIntensity;
output.anisotropy = anisotropy;
return output;
}
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);
#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;
output.perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness);\
output.subsurfaceColor = surfaceData.subsurfaceColor.rgb * surfaceData.subsurfaceColor.a;
output.normalWS = surfaceData.normalWS;
output.geomNormalWS = surfaceData.geomNormalWS;
output.tangentWS = surfaceData.tangentWS;
output.bitangentWS = normalize(cross(surfaceData.normalWS, surfaceData.tangentWS));
output.anisotropy = surfaceData.anisotropy;
ConvertAnisotropyToRoughness(output.perceptualRoughness, surfaceData.anisotropy, output.roughnessT, output.roughnessB);
return output;
}
PreLightData GetPreLightData_UTS(float3 V, PositionInputs posInput, inout UtsBSDFData bsdfData)
{
PreLightData preLightData;
ZERO_INITIALIZE(PreLightData, preLightData);
float3 N = bsdfData.normalWS;
preLightData.NdotV = dot(N, V);
preLightData.iblPerceptualRoughness = bsdfData.perceptualRoughness;
float clampedNdotV = ClampNdotV(preLightData.NdotV);
// Handle IBL + area light + multiscattering.
// Note: use the not modified by anisotropy iblPerceptualRoughness here.
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
// Ref: Practical multiple scattering compensation for microfacet models.
// We only apply the formulation for metals.
// For dielectrics, the change of reflectance is negligible.
// We deem the intensity difference of a couple of percent for high values of roughness
// to not be worth the cost of another precomputed table.
// Note: this formulation bakes the BSDF non-symmetric!
preLightData.energyCompensation = 1.0 / specularReflectivity - 1.0;
#else
preLightData.energyCompensation = 0.0;
#endif // LIT_USE_GGX_ENERGY_COMPENSATION
float3 iblN;
#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);
// 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);
// Area light
#ifdef USE_DIFFUSE_LAMBERT_BRDF
preLightData.ltcTransformDiffuse = k_identity3x3;
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_SSS_DIFFUSE_POWER))
ModifyLambertLTCTransformForDiffusePower(preLightData.ltcTransformDiffuse, GetDiffusePower(bsdfData.diffusionProfileIndex));
#else
preLightData.ltcTransformDiffuse = SampleLtcMatrix(bsdfData.perceptualRoughness, clampedNdotV, LTCLIGHTINGMODEL_DISNEY_DIFFUSE);
#endif
float perceptualRoughnessA = bsdfData.perceptualRoughness;
preLightData.ltcTransformSpecular[0] = SampleLtcMatrix(perceptualRoughnessA, clampedNdotV, LTCLIGHTINGMODEL_GGX);
// Construct a right-handed view-dependent orthogonal basis around the normal
preLightData.orthoBasisViewNormal = GetOrthoBasisViewNormal(V, N, preLightData.NdotV);
preLightData.ltcTransformCoat = 0.0;
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
preLightData.ltcTransformCoat = SampleLtcMatrix(CLEAR_COAT_PERCEPTUAL_ROUGHNESS, clampedNdotV, LTCLIGHTINGMODEL_GGX);
}
return preLightData;
}
void UtsClampRoughness(inout PreLightData preLightData, inout UtsBSDFData bsdfData, float minRoughness)
{
bsdfData.roughnessT = max(minRoughness, bsdfData.roughnessT);
bsdfData.roughnessB = max(minRoughness, bsdfData.roughnessB);
}
// Legacy for compatibility with existing shaders
inline bool IsGammaSpace()
{
#ifdef UNITY_COLORSPACE_GAMMA
return true;
#else
return false;
#endif
}
// normal should be normalized, w=1.0
half3 SHEvalLinearL0L1(half4 normal)
{
half3 x;
// Linear (L1) + constant (L0) polynomial terms
x.r = dot(unity_SHAr, normal);
x.g = dot(unity_SHAg, normal);
x.b = dot(unity_SHAb, normal);
return x;
}
// normal should be normalized, w=1.0
half3 SHEvalLinearL2(half4 normal)
{
half3 x1, x2;
// 4 of the quadratic (L2) polynomials
half4 vB = normal.xyzz * normal.yzzx;
x1.r = dot(unity_SHBr, vB);
x1.g = dot(unity_SHBg, vB);
x1.b = dot(unity_SHBb, vB);
// Final (5th) quadratic (L2) polynomial
half vC = normal.x * normal.x - normal.y * normal.y;
x2 = unity_SHC.rgb * vC;
return x1 + x2;
}
// normal should be normalized, w=1.0
// output in active color space
half3 ShadeSH9(half4 normal)
{
// Linear + constant polynomial terms
half3 res = SHEvalLinearL0L1(normal);
// Quadratic polynomials
res += SHEvalLinearL2(normal);
# ifdef UNITY_COLORSPACE_GAMMA
res = LinearToGammaSpace(res);
# endif
return res;
}
float3 DecodeLightProbe(float3 N) {
return ShadeSH9(float4(N, 1));
}
inline float GammaToLinearSpaceExact(float value)
{
if (value <= 0.04045F)
return value / 12.92F;
else if (value < 1.0F)
return pow((value + 0.055F) / 1.055F, 2.4F);
else
return pow(value, 2.2F);
}
inline float3 GammaToLinearSpace(float3 sRGB)
{
// Approximate version from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
return sRGB * (sRGB * (sRGB * 0.305306011h + 0.682171111h) + 0.012522878h);
// Precise version, useful for debugging.
//return half3(GammaToLinearSpaceExact(sRGB.r), GammaToLinearSpaceExact(sRGB.g), GammaToLinearSpaceExact(sRGB.b));
}
inline float LinearToGammaSpaceExact(float value)
{
if (value <= 0.0F)
return 0.0F;
else if (value <= 0.0031308F)
return 12.92F * value;
else if (value < 1.0F)
return 1.055F * pow(value, 0.4166667F) - 0.055F;
else
return pow(value, 0.45454545F);
}
inline float3 LinearToGammaSpace(float3 linRGB)
{
linRGB = max(linRGB, float3(0.h, 0.h, 0.h));
// An almost-perfect approximation from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
return max(1.055h * pow(linRGB, 0.416666667h) - 0.055h, 0.h);
// Exact version, useful for debugging.
//return half3(LinearToGammaSpaceExact(linRGB.r), LinearToGammaSpaceExact(linRGB.g), LinearToGammaSpaceExact(linRGB.b));
}
#if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2)
#define UNITY_FOG_COORDS(idx) UNITY_FOG_COORDS_PACKED(idx, float1)
#if (SHADER_TARGET < 30) || defined(SHADER_API_MOBILE)
// mobile or SM2.0: calculate fog factor per-vertex
#define UNITY_TRANSFER_FOG(o,outpos) UNITY_CALC_FOG_FACTOR((outpos).z); o.fogCoord.x = unityFogFactor
#else
// SM3.0 and PC/console: calculate fog distance per-vertex, and fog factor per-pixel
#define UNITY_TRANSFER_FOG(o,outpos) o.fogCoord.x = (outpos).z
#endif
#else
#define UNITY_FOG_COORDS(idx)
#define UNITY_TRANSFER_FOG(o,outpos)
#endif
#define UNITY_FOG_LERP_COLOR(col,fogCol,fogFac) col.rgb = lerp((fogCol).rgb, (col).rgb, saturate(fogFac))
#if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2)
#if (SHADER_TARGET < 30) || defined(SHADER_API_MOBILE)
// mobile or SM2.0: fog factor was already calculated per-vertex, so just lerp the color
#define UNITY_APPLY_FOG_COLOR(coord,col,fogCol) UNITY_FOG_LERP_COLOR(col,fogCol,(coord).x)
#else
// SM3.0 and PC/console: calculate fog factor and lerp fog color
#define UNITY_APPLY_FOG_COLOR(coord,col,fogCol) UNITY_CALC_FOG_FACTOR((coord).x); UNITY_FOG_LERP_COLOR(col,fogCol,unityFogFactor)
#endif
#else
#define UNITY_APPLY_FOG_COLOR(coord,col,fogCol)
#endif
#ifdef UNITY_PASS_FORWARDADD
#define UNITY_APPLY_FOG(coord,col) UNITY_APPLY_FOG_COLOR(coord,col,fixed4(0,0,0,0))
#else
#define UNITY_APPLY_FOG(coord,col) UNITY_APPLY_FOG_COLOR(coord,col,unity_FogColor)
#endif
#endif //#if false
#ifdef DIRECTIONAL
#define LIGHTING_COORDS(idx1,idx2) SHADOW_COORDS(idx1)
#define TRANSFER_VERTEX_TO_FRAGMENT(a) TRANSFER_SHADOW(a)
#define LIGHT_ATTENUATION(a) SHADOW_ATTENUATION(a)
#endif
// Transforms 2D UV by scale/bias property
//#define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)
#define UCTS_TEXTURE2D(tex,name) SAMPLE_TEXTURE2D(tex,sampler##tex,TRANSFORM_TEX(name, tex));
inline float4 UnityObjectToClipPosInstanced(in float3 pos)
{
// return mul(UNITY_MATRIX_VP, mul(unity_ObjectToWorldArray[unity_InstanceID], float4(pos, 1.0)));
// todo. right?
return mul(UNITY_MATRIX_VP, mul(UNITY_MATRIX_M, float4(pos, 1.0)));
}
inline float4 UnityObjectToClipPosInstanced(float4 pos)
{
return UnityObjectToClipPosInstanced(pos.xyz);
}
#define UnityObjectToClipPos UnityObjectToClipPosInstanced
inline float3 UnityObjectToWorldNormal( in float3 norm )
{
#ifdef UNITY_ASSUME_UNIFORM_SCALING
return UnityObjectToWorldDir(norm);
#else
// mul(IT_M, norm) => mul(norm, I_M) => {dot(norm, I_M.col0), dot(norm, I_M.col1), dot(norm, I_M.col2)}
return normalize(mul(norm, (float3x3)UNITY_MATRIX_M));
#endif
}
// normal should be normalized, w=1.0
float3 SHEvalLinearL0L1 (float4 normal)
{
float3 x;
// Linear (L1) + constant (L0) polynomial terms
x.r = dot(unity_SHAr,normal);
x.g = dot(unity_SHAg,normal);
x.b = dot(unity_SHAb,normal);
return x;
}
// normal should be normalized, w=1.0
float3 SHEvalLinearL2 (float4 normal)
{
float3 x1, x2;
// 4 of the quadratic (L2) polynomials
float4 vB = normal.xyzz * normal.yzzx;
x1.r = dot(unity_SHBr,vB);
x1.g = dot(unity_SHBg,vB);
x1.b = dot(unity_SHBb,vB);
// Final (5th) quadratic (L2) polynomial
half vC = normal.x*normal.x - normal.y*normal.y;
x2 = unity_SHC.rgb * vC;
return x1 + x2;
}
// normal should be normalized, w=1.0
// output in active color space
float3 ShadeSH9 (float4 normal)
{
// Linear + constant polynomial terms
float3 res = SHEvalLinearL0L1 (normal);
// Quadratic polynomials
res += SHEvalLinearL2 (normal);
# ifdef UNITY_COLORSPACE_GAMMA
res = LinearToGammaSpace (res);
# endif
return res;
}
float3 SampleBakedGI_UTS(float3 positionRWS, float3 normalWS, float2 uvStaticLightmap, float2 uvDynamicLightmap, bool needToIncludeAPV = false)
{
float3 bakeDiffuseLighting = float3(0, 0, 0);
float3 backBakeDiffuseLighting = float3(0, 0, 0);
float3 backNormalWS = float3(0, 0, 0);
#if !defined(_SURFACE_TYPE_TRANSPARENT) && (SHADERPASS != SHADERPASS_RAYTRACING_INDIRECT) && (SHADERPASS != SHADERPASS_RAYTRACING_GBUFFER)
if (_IndirectDiffuseMode != INDIRECTDIFFUSEMODE_OFF
#if (SHADERPASS == SHADERPASS_GBUFER)
&& _IndirectDiffuseMode != INDIRECTDIFFUSEMODE_MIXED && _ReflectionsMode != REFLECTIONSMODE_MIXED
#endif
)
return bakeDiffuseLighting;
#endif
#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
EvaluateLightmap(positionRWS, normalWS, backNormalWS, uvStaticLightmap, uvDynamicLightmap, bakeDiffuseLighting, backBakeDiffuseLighting);
#elif (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2))
if (needToIncludeAPV)
{
EvaluateAdaptiveProbeVolume(GetAbsolutePositionWS(positionRWS), normalWS, backNormalWS, GetWorldSpaceNormalizeViewDir(positionRWS), 0.0, bakeDiffuseLighting, backBakeDiffuseLighting);
}
#else
EvaluateLightProbeBuiltin(positionRWS, normalWS, backNormalWS, bakeDiffuseLighting, backBakeDiffuseLighting);
#if defined(SHADER_STAGE_RAY_TRACING)
bakeDiffuseLighting *= _RayTracingAmbientProbeDimmer;
backBakeDiffuseLighting *= _RayTracingAmbientProbeDimmer;
#endif
#endif
return bakeDiffuseLighting;
}
float3 SampleBakedGI_UTS_OutLine(float3 positionRWS, float3 normalWS, float2 uvStaticLightmap, float2 uvDynamicLightmap)
{
float3 bakeDiffuseLighting = float3(0, 0, 0);
float3 backBakeDiffuseLighting = float3(0, 0, 0);
float3 backNormalWS = float3(0, 0, 0);
#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
EvaluateLightmap(positionRWS, normalWS, backNormalWS, uvStaticLightmap, uvDynamicLightmap, bakeDiffuseLighting, backBakeDiffuseLighting);
#elif (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2))
EvaluateAdaptiveProbeVolume(GetAbsolutePositionWS(positionRWS), normalWS, backNormalWS, GetWorldSpaceNormalizeViewDir(positionRWS), 0.0, bakeDiffuseLighting, backBakeDiffuseLighting);
#else
EvaluateLightProbeBuiltin(positionRWS, normalWS, backNormalWS, bakeDiffuseLighting, backBakeDiffuseLighting);
#if defined(SHADER_STAGE_RAY_TRACING)
bakeDiffuseLighting *= _RayTracingAmbientProbeDimmer;
backBakeDiffuseLighting *= _RayTracingAmbientProbeDimmer;
#endif
#endif
return bakeDiffuseLighting;
}
#endif //#ifndef UCTS_HDRP_INCLUDED

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: e2fc592d7e0eb2d47b07a315b3ec3ea8
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,297 @@
#ifndef UTS_MATERIAL_EVALUATION
#define UTS_MATERIAL_EVALUATION
#define ColorSpaceDielectricSpec half4(0.22, 0.22, 0.22, 0.779)
struct UtsShadeMask
{
float baseShadeMask;
float firstShadeMask;
};
float3 GetSpecularColor(float3 albedo, float metalic)
{
float3 specColor = lerp(ColorSpaceDielectricSpec.rgb, albedo, metalic);
return specColor;
}
float RoughnessToBlinnPhongSpecularExponent(float roughness)
{
return clamp(2 * rcp(roughness * roughness) - 2, FLT_EPS, rcp(FLT_EPS));
}
float StepFeatherToon(float value,float step,float feather)
{
return saturate((value - step + feather) / feather);
}
float3 ComputeSpecularTerm(UtsBSDFData bsdfData, PreLightData preLightData, float3 V, float3 L)
{
#ifdef _PBR_MODE_OFF
return 0;
#else
float3 specTerm;
float3 N = bsdfData.normalWS;
float3 H = normalize(L + V);
float NdotL = dot(N, L);
float NdotH = saturate(dot(N, H));
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);
#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);
#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));
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 * preLightData.specularFGD;
specTerm = specTerm * clampedNdotL;
return specTerm;
#endif
}
half3 FitWithCurveApprox(half NdotL, half Curvature)
{
half curva = (1.0 / mad(Curvature, 0.5 - 0.0625, 0.0625) - 2.0) / (16.0 - 2.0);
half oneMinusCurva = 1.0 - curva;
half3 curve0;
{
half3 rangeMin = half3(0.0, 0.3, 0.3);
half3 rangeMax = half3(1.0, 0.7, 0.7);
half3 offset = half3(0.0, 0.06, 0.06);
half3 t = saturate(mad(NdotL, 1.0 / (rangeMax - rangeMin), (offset + rangeMin) / (rangeMin - rangeMax)));
half3 lowerLine = (t * t) * half3(0.65, 0.5, 0.9);
lowerLine.r += 0.045;
lowerLine.b *= t.b;
half3 m = half3(1.75, 2.0, 1.97);
half3 upperLine = mad(NdotL, m, half3(0.99, 0.99, 0.99) - m);
upperLine = saturate(upperLine);
half3 lerpMin = half3(0.0, 0.35, 0.35);
half3 lerpMax = half3(1.0, 0.7, 0.6);
half3 lerpT = saturate(mad(NdotL, 1.0 / (lerpMax - lerpMin), lerpMin / (lerpMin - lerpMax)));
curve0 = lerp(lowerLine, upperLine, lerpT * lerpT);
}
half3 curve1;
{
half3 m = half3(1.95, 2.0, 2.0);
half3 upperLine = mad(NdotL, m, half3(0.99, 0.99, 1.0) - m);
curve1 = saturate(upperLine);
}
float oneMinusCurva2 = oneMinusCurva * oneMinusCurva;
return lerp(curve0, curve1, mad(oneMinusCurva2, -1.0 * oneMinusCurva2, 1.0));
}
float3 SampleSDFTexture(float3 L, float2 uv, out float angle)
{
float2 right_uv = float2(1 - uv.x, uv.y);
float3 left_SDFTex = SAMPLE_TEXTURE2D(_SDFShadowTex, sampler_SDFShadowTex, uv).rgb;
float3 right_SDFTex = SAMPLE_TEXTURE2D(_SDFShadowTex, sampler_SDFShadowTex, right_uv).rgb;
float2 leftVector = normalize(mul(UNITY_MATRIX_M, float4(1, 0, 0, 0)).xz);
float2 forwardVector = normalize(mul(UNITY_MATRIX_M, float4(0, 0, 1, 0)).xz);
float2 lightDirection = normalize(L.xz);
angle = 1.0 - (dot(forwardVector, lightDirection) * 0.5 + 0.5);
bool isRightSide = dot(lightDirection, leftVector) > 0;
return isRightSide ? right_SDFTex : left_SDFTex;
}
float GetHairShadow(PositionInputs posInput, float3 L)
{
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; // We have to including the scaling factor for our shadow map since we are not going to allocate new texture if the rendering resolution changed.
float hairDepth = SAMPLE_TEXTURE2D(_HairShadowTex, s_trilinear_clamp_sampler, scaledUVs).r;
float 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;
}
UtsShadeMask GetShadeMak(PositionInputs posInput, float3 normalWS, float3 L, SHADOW_TYPE shadow, float2 uv, out float additionalSpecular)
{
UtsShadeMask shadeMask;
#if _SHADOW_MODE_NORMAL
float NdotL = dot(normalWS, L);
float halfLambert = 0.5 * NdotL + 0.5;
//float systemShadows = saturate(max(0.0, shadow.x + 0.5 - 0.0001 + _Tweak_SystemShadowsLevel));
//float shadingGrade = lerp(halfLambert, halfLambert * systemShadows, _Set_SystemShadowsToBase);
float firstColorFeatherForMask = lerp(_1st_ShadeColor_Feather, 0.0, max(_ComposerMaskMode, _FirstShadeOverridden));
shadeMask.baseShadeMask = saturate((halfLambert - (_1st_ShadeColor_Step - firstColorFeatherForMask)) / (_1st_ShadeColor_Step - (_1st_ShadeColor_Step - firstColorFeatherForMask)));
float secondColorFeatherForMask = lerp(_2nd_ShadeColor_Feather, 0.0, max(_SecondShadeOverridden, _ComposerMaskMode));
shadeMask.firstShadeMask = saturate((halfLambert - (_2nd_ShadeColor_Step - secondColorFeatherForMask)) / (_2nd_ShadeColor_Step - (_2nd_ShadeColor_Step - secondColorFeatherForMask)));
additionalSpecular = 0;
#elif _SHADOW_MODE_SDF
float angle;
float smoothGamma = _SDFSmoothGamma / 10.0f;
float shadowLevel = _SDFShadowLevel / 10.0f;
float3 sdfTexture = SampleSDFTexture(L, uv, angle); // r: sdf shadow, g: sdf noise highlight, b: fixed shadow
float sdfShadowMask = 1.0 - smoothstep(sdfTexture.r - smoothGamma, sdfTexture.r + smoothGamma, angle - shadowLevel);
shadeMask.baseShadeMask = sdfShadowMask * sdfTexture.b;
shadeMask.firstShadeMask = 1.0;
additionalSpecular = sdfTexture.g;
#endif
shadow = smoothstep(0.4, 0.6, shadow);
#if _RECEIVE_HAIR_SHADOW_ON && ENABLE_UTS_HAIR_SHAOW
shadow *= GetHairShadow(posInput, L);
#endif
shadeMask.baseShadeMask = APPLY_WEIGHT(shadeMask.baseShadeMask, shadow, _Set_SystemShadowsToBase);
return shadeMask;
}
DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, PreLightData preLightData, SHADOW_TYPE shadow,
float3 lightColor, float3 V, float3 L, float2 uv,
float diffuseDimmer, float specularDimmer)
{
DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
if (Max3(lightColor.r, lightColor.g, lightColor.b) > 0.0)
{
float additionalSpecular;
UtsShadeMask shadeMask = GetShadeMak(posInput, bsdfData.normalWS, L, shadow, uv, additionalSpecular);
float3 diffuseTerm = lerp(lerp(bsdfData.secondShadingDiffuseColor, bsdfData.firstShadingDiffuseColor, shadeMask.firstShadeMask), bsdfData.diffuseColor, shadeMask.baseShadeMask);
float3 specularTerm = (ComputeSpecularTerm(bsdfData, preLightData, V, L) + additionalSpecular) * shadeMask.baseShadeMask;
lighting.diffuse += diffuseTerm * lightColor * diffuseDimmer;
lighting.specular += specularTerm * lightColor * specularDimmer;
}
return lighting;
}
// Todo: SDF nose high light
// #if define(_SDFShadow) || define(_SDFNoiseHelight)
#ifdef _SDFShadow
// Use main light XZ direction & world Left/Forward Vector to sample character face SDF
void SDFSample(out float4 lSDF_Tex, out float4 rSDF_Tex, out float2 leftVector, out float2 forwardVector, float2 UV)
{
lSDF_Tex = SAMPLE_TEXTURE2D(_SDFShadowTex, sampler_SDFShadowTex, UV);
float2 right_uv = float2(1 - UV.x, UV.y);
rSDF_Tex = SAMPLE_TEXTURE2D(_SDFShadowTex, sampler_SDFShadowTex, right_uv);
leftVector = normalize(mul(UNITY_MATRIX_M, float4(1, 0, 0, 0)).xz);
forwardVector = normalize(mul(UNITY_MATRIX_M, float4(0, 0, 1, 0)).xz);
}
// Return 1 -> right side
bool SDFPickSide(out float angle, float2 Left, float2 Front, float2 lightDir)
{
// Remap [-1,1] tp [0,1] | 0 <- Face Toward Light ---- Back Toward Light -> 1
angle = 1- clamp(0 , 1, dot(Front, lightDir) * 0.5 + 0.5);
// Pick side
return dot(lightDir,Left) > 0;
}
// Output: readjusted angle between light and pixel facing direction (Represented by a projection length) [Out Param, angle]
// Output: SDF Texel Color [Return Value]
float4 SDFResult(inout bool rightside, out float angle, float3 L, float2 UV)
{
float4 left_SDFTex;
float4 right_SDFTex;
float2 Left;
float2 Front;
SDFSample(left_SDFTex, right_SDFTex, Left, Front, UV);
float2 light_Dir = normalize(L.xz);
rightside = SDFPickSide(angle, Left, Front, light_Dir);
return rightside ? right_SDFTex : left_SDFTex;
}
float SDFMask(float angle, float tex_direct)
{
float smoothGamma = _SDFSmoothGamma / 10.0f;
float shadowLevel = _SDFShadowLevel / 10.0f;
float SDFMask = smoothstep(tex_direct - smoothGamma, tex_direct + smoothGamma, angle - shadowLevel);
return SDFMask;
}
float SDFNoseHighlight(float angle,float tex_value, bool rightside, float2 UV)
{
// REF: https://zhuanlan.zhihu.com/p/411188212 3.2.1
float highlightValue = 0;
//float cutU = step(0.5, UV.x);
float cutU = UV.x;
float uvMask=lerp(cutU, 1 - cutU, rightside);//discard half of the sdf we sampled (Only one side of highlight wanted)
float lightAtten = pow(max(0, angle - (_SDFShadowLevel / 10.0f)), 0.8);
return smoothstep(lightAtten-_SDFNoseHighlightSmoothRange,lightAtten+_SDFNoseHighlightSmoothRange , uvMask * tex_value) * tex_value; // Safeguard, return 0 when tex_value = 0
}
#endif
#endif

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 38093af06622fce4f85f440a6840c65f
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: