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,8 @@
fileFormatVersion: 2
guid: 3642d3111f8bccb4180d12b99fa6de71
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

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:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 69cd89636d3fcd844b1f0381f929ca71
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,340 @@
//Unity Toon Shader/HDRP
//nobuyuki@unity3d.com
//toshiyuki@unity3d.com (Universal RP/HDRP)
#include "Packages/com.misaki.hdrp-toon/Runtime/HDRP/Shaders/Includes/Common/UtsPBR.hlsl"
#ifndef DirectionalShadowType
# if (SHADEROPTIONS_RAYTRACING && (defined(SHADER_API_D3D11) || defined(SHADER_API_D3D12)) && !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL))
# define DirectionalShadowType float3
# else
# define DirectionalShadowType float
# endif
#endif
void UTS_MainLight(LightLoopContext lightLoopContext, FragInputs input, UTSLightData utsLightData, SurfaceData surfaceData, BSDFData bsdfData, out float inverseClipping, out float channelOutAlpha, out UTSData utsData, inout UTSAggregateLighting utsAggregateLighting)
{
inverseClipping = 0;
channelOutAlpha = 1.0f;
ZERO_INITIALIZE(UTSData, utsData);
// We don't have to calculate lighting here if we are using sdf shadow
#ifndef _SDFShadow
#ifdef VARYINGS_NEED_POSITION_WS
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
#else
// Unused
float3 V = float3(1.0, 1.0, 1.0); // Avoid the division by 0
#endif
/* todo. these should be put int a struct */
float4 Set_UV0 = input.texCoord0;
float3x3 tangentTransform = input.tangentToWorld;
utsData.normalDirection = surfaceData.normalWS; // Perturbed normals
float4 _MainTex_var = float4(surfaceData.baseColor.r, surfaceData.baseColor.g, surfaceData.baseColor.b, surfaceData.coatMask);
utsData.viewDirection = V;
/* to here todo. these should be put int a struct */
//v.2.0.4
#ifdef _IS_TRANSCLIPPING_OFF
//
#elif _IS_TRANSCLIPPING_ON
float4 _ClippingMask_var = SAMPLE_TEXTURE2D(_ClippingMask, sampler_BaseColorMap, TRANSFORM_TEX(Set_UV0, _ClippingMask));
float Set_MainTexAlpha = _MainTex_var.a;
float _IsBaseMapAlphaAsClippingMask_var = lerp(_ClippingMask_var.r, Set_MainTexAlpha, _IsBaseMapAlphaAsClippingMask);
float _Inverse_Clipping_var = lerp(_IsBaseMapAlphaAsClippingMask_var, (1.0 - _IsBaseMapAlphaAsClippingMask_var), _Inverse_Clipping);
float Set_Clipping = saturate((_Inverse_Clipping_var + _Clipping_Level));
clip(Set_Clipping - 0.5);
inverseClipping = _Inverse_Clipping_var;
#endif
SHADOW_TYPE shadowAttenuation = lightLoopContext.shadowValue;
//v.2.0.6
//Minimal value is same as the Minimum Feather's value with the Minimum Step's value as threshold.
#if !defined (UTS_USE_RAYTRACING_SHADOW)
shadowAttenuation *= 2.0f;
shadowAttenuation = saturate(shadowAttenuation);
#endif
float3 mainLightDirection = utsLightData.lightDirection;
float3 mainLightColor = utsLightData.lightColor;
//v.2.0.4
float3 defaultLightDirection = normalize(UNITY_MATRIX_V[2].xyz + UNITY_MATRIX_V[1].xyz);
//v.2.0.5
float3 defaultLightColor = saturate(max(float3(0.05, 0.05, 0.05) * _Unlit_Intensity, max(ShadeSH9(float4(0.0, 0.0, 0.0, 1.0)), ShadeSH9(float4(0.0, -1.0, 0.0, 1.0)).rgb) * _Unlit_Intensity));
float3 customLightDirection = normalize(mul(UNITY_MATRIX_M, float4(((float3(1.0, 0.0, 0.0) * _Offset_X_Axis_BLD * 10) + (float3(0.0, 1.0, 0.0) * _Offset_Y_Axis_BLD * 10) + (float3(0.0, 0.0, -1.0) * lerp(-1.0, 1.0, _Inverse_Z_Axis_BLD))), 0)).xyz);
float3 lightDirection = normalize(lerp(defaultLightDirection, mainLightDirection.xyz, any(mainLightDirection.xyz)));
lightDirection = lerp(lightDirection, customLightDirection, _Is_BLD);
float3 originalLightColor = mainLightColor.rgb;
originalLightColor = lerp(originalLightColor, clamp(originalLightColor, ConvertFromEV100(_ToonEvAdjustmentValueMin), ConvertFromEV100(_ToonEvAdjustmentValueMax)), _ToonEvAdjustmentCurve);
float3 lightColor = lerp(max(defaultLightColor, originalLightColor), max(defaultLightColor, saturate(originalLightColor)), max(_Is_Filter_LightColor, _ToonLightHiCutFilter)) * _Light_Intensity_Multiplier;
////// Lighting:
float3 halfDirection = normalize(utsData.viewDirection + lightDirection);
//v.2.0.5
_Color = _BaseColor;
float3 Set_LightColor = lightColor.rgb;
float3 Set_BaseColor = lerp((_BaseColor.rgb * _MainTex_var.rgb), ((_BaseColor.rgb * _MainTex_var.rgb) * Set_LightColor), _Is_LightColor_Base);
float Set_BaseColorAlpha = _BaseColorVisible;
#ifdef _IS_CLIPPING_MATTE
if (_ClippingMatteMode == 1)
{
clippingColor = Set_BaseColor;
return clippingColor;
}
#endif // _IS_CLIPPING_MATTE
#ifdef UTS_LAYER_VISIBILITY
float4 overridingColor = lerp(_BaseColorMaskColor, float4(_BaseColorMaskColor.w, _BaseColorMaskColor.w, _BaseColorMaskColor.w, 1.0f), _ComposerMaskMode);
float maskEnabled = max(_BaseColorOverridden, _ComposerMaskMode);
Set_BaseColor = lerp(Set_BaseColor, overridingColor.rgb, maskEnabled);
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 _Is_LightColor_1st_Shade_var = lerp((_1st_ShadeMap_var.rgb * _1st_ShadeColor.rgb), ((_1st_ShadeMap_var.rgb * _1st_ShadeColor.rgb) * Set_LightColor), _Is_LightColor_1st_Shade);
float _HalfLambert_var = 0.5 * dot(utsData.normalDirection, lightDirection) + 0.5; // Half Lambert
//v.2.0.6
float4 _ShadingGradeMap_var = tex2Dlod(_ShadingGradeMap, float4(TRANSFORM_TEX(Set_UV0, _ShadingGradeMap), 0.0, _BlurLevelSGM));
float _SystemShadowsLevel_var = (shadowAttenuation * 0.5f) + 0.5f + _Tweak_SystemShadowsLevel > 0.001f ? (shadowAttenuation * 0.5f)+0.5f+_Tweak_SystemShadowsLevel : 0.0001f;
float _ShadingGradeMapLevel_var = _ShadingGradeMap_var.r < 0.95 ? _ShadingGradeMap_var.r + _Tweak_ShadingGradeMapLevel : 1;
float Set_ShadingGrade = saturate(_ShadingGradeMapLevel_var) * lerp(_HalfLambert_var, (_HalfLambert_var * saturate(_SystemShadowsLevel_var)), _Set_SystemShadowsToBase );
// float Set_ShadingGrade = saturate(_ShadingGradeMapLevel_var) * lerp(_HalfLambert_var, (_HalfLambert_var * saturate(1.0 + _Tweak_SystemShadowsLevel)), _Set_SystemShadowsToBase);
float _1stColorFeatherForMask = lerp(_1st_ShadeColor_Feather, 0.0f, max(_ComposerMaskMode, _FirstShadeOverridden));
//
float Set_FinalShadowMask = saturate((1.0 + ((Set_ShadingGrade - (_1st_ShadeColor_Step - _1stColorFeatherForMask)) * -1) / (_1st_ShadeColor_Step - (_1st_ShadeColor_Step - _1stColorFeatherForMask)))); // Base and 1st Shade Mask
#ifdef _IS_CLIPPING_MATTE
if (_ClippingMatteMode == 2)
{
clippingColor = _Is_LightColor_1st_Shade_var;
return clippingColor;
}
#endif // _IS_CLIPPING_MATTE
#ifdef UTS_LAYER_VISIBILITY
{
float4 overridingColor = lerp(_FirstShadeMaskColor, float4(_FirstShadeMaskColor.w, _FirstShadeMaskColor.w, _FirstShadeMaskColor.w, 1.0f), _ComposerMaskMode);
float maskEnabled = max(_FirstShadeOverridden, _ComposerMaskMode);
_Is_LightColor_1st_Shade_var = lerp(_Is_LightColor_1st_Shade_var, overridingColor.rgb, maskEnabled);
_Is_LightColor_1st_Shade_var = lerp(_Is_LightColor_1st_Shade_var, Set_BaseColor, 1.0f - _FirstShadeVisible);
}
float Set_1st_ShadeAlpha = _FirstShadeVisible;
#endif //#ifdef UTS_LAYER_VISIBILITY
float3 _BaseColor_var = lerp(Set_BaseColor, _Is_LightColor_1st_Shade_var, Set_FinalShadowMask);
//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);
float _2ndColorFeatherForMask = lerp(_2nd_ShadeColor_Feather, 0.0f, max(_SecondShadeOverridden, _ComposerMaskMode));
float Set_ShadeShadowMask = saturate((1.0 + ((_HalfLambert_var - (_ShadeColor_Step - _2ndColorFeatherForMask)) * ((1.0 - 1).r - 1.0)) / (_ShadeColor_Step - (_ShadeColor_Step - _2ndColorFeatherForMask)))); // 1st and 2nd Shades Mask
//Composition: 3 Basic Colors as Set_FinalBaseColor
#ifdef UTS_LAYER_VISIBILITY
float3 diffuseTerm;
{
float4 overridingColor = lerp(_SecondShadeMaskColor, float4(_SecondShadeMaskColor.w, _SecondShadeMaskColor.w, _SecondShadeMaskColor.w, 1.0f), _ComposerMaskMode);
float maskEnabled = max(_SecondShadeOverridden, _ComposerMaskMode);
float3 _Is_LightColor_2nd_Shade_var = lerp((_2nd_ShadeMap_var.rgb * _2nd_ShadeColor.rgb), ((_2nd_ShadeMap_var.rgb * _2nd_ShadeColor.rgb) * Set_LightColor), _Is_LightColor_2nd_Shade);
_Is_LightColor_2nd_Shade_var = lerp(_Is_LightColor_2nd_Shade_var, overridingColor.rgb, maskEnabled);
_Is_LightColor_2nd_Shade_var = lerp(_Is_LightColor_2nd_Shade_var, Set_BaseColor, 1.0f - _SecondShadeVisible);
float Set_2nd_ShadeAlpha = _SecondShadeVisible;
diffuseTerm =
lerp(_BaseColor_var,
lerp(_Is_LightColor_1st_Shade_var, _Is_LightColor_2nd_Shade_var
, Set_ShadeShadowMask)
, Set_FinalShadowMask);
channelOutAlpha =
lerp(Set_BaseColorAlpha, lerp(Set_1st_ShadeAlpha, Set_2nd_ShadeAlpha, Set_ShadeShadowMask),Set_FinalShadowMask);
}
#else
float3 Set_FinalBaseColor =
lerp(_BaseColor_var,
lerp(_Is_LightColor_1st_Shade_var,
lerp((_2nd_ShadeMap_var.rgb * _2nd_ShadeColor.rgb), ((_2nd_ShadeMap_var.rgb * _2nd_ShadeColor.rgb) * Set_LightColor)
, _Is_LightColor_2nd_Shade)
, Set_ShadeShadowMask)
, Set_FinalShadowMask);
#endif //#ifdef UTS_LAYER_VISIBILITY
float albedoIntensity = max(0.1, (1 - sqrt(surfaceData.metallic)) * (1.7 - 0.7 * (1 - sqrt(surfaceData.metallic))));
diffuseTerm = diffuseTerm * albedoIntensity;
#ifdef _IS_CLIPPING_MATTE
if (_ClippingMatteMode == 3)
{
clippingColor = lerp((_2nd_ShadeMap_var.rgb * _2nd_ShadeColor.rgb), ((_2nd_ShadeMap_var.rgb * _2nd_ShadeColor.rgb) * Set_LightColor)
, _Is_LightColor_2nd_Shade);
return clippingColor;
}
#endif // _IS_CLIPPING_MATTE
float4 _Set_HighColorMask_var = tex2D(_Set_HighColorMask, TRANSFORM_TEX(Set_UV0, _Set_HighColorMask));
float _Specular_var = 0.5 * dot(halfDirection, utsData.normalDirection) + 0.5; // Specular
float _TweakHighColorMask_var = (saturate((_Set_HighColorMask_var.g + _Tweak_HighColorMaskLevel)) * lerp((1.0 - step(_Specular_var, (1.0 - pow(_HighColor_Power, 5)))), pow(_Specular_var, exp2(lerp(11, 1, _HighColor_Power))), _Is_SpecularToHighColor));
float4 _HighColor_Tex_var = tex2D(_HighColor_Tex, TRANSFORM_TEX(Set_UV0, _HighColor_Tex));
//Composition: 3 Basic Colors and HighColor as Set_HighColor
float3 _HighColorWithOutTweak_var = lerp((_HighColor_Tex_var.rgb * _HighColor.rgb), ((_HighColor_Tex_var.rgb * _HighColor.rgb) * Set_LightColor), _Is_LightColor_HighColor);
float3 _HighColor_var = _HighColorWithOutTweak_var * _TweakHighColorMask_var;
#ifdef _IS_CLIPPING_MATTE
if (_ClippingMatteMode == 4)
{
clippingColor = _HighColorWithOutTweak_var;
return clippingColor;
}
#endif // _IS_CLIPPING_MATTE
#ifdef UTS_LAYER_VISIBILITY
float3 Set_HighColor;
{
float4 overridingColor = lerp(_HighlightMaskColor, float4(_HighlightMaskColor.w, _HighlightMaskColor.w, _HighlightMaskColor.w, 1.0f), _ComposerMaskMode);
float maskEnabled = max(_HighlightOverridden, _ComposerMaskMode);
_HighColor_var *= _HighlightVisible;
Set_HighColor =
lerp(SATURATE_IF_SDR(diffuseTerm - _TweakHighColorMask_var), diffuseTerm,
lerp(_Is_BlendAddToHiColor, 1.0
, _Is_SpecularToHighColor));
float3 addColor =
lerp(_HighColor_var, (_HighColor_var * ((1.0 - Set_FinalShadowMask) + (Set_FinalShadowMask * _TweakHighColorOnShadow)))
, _Is_UseTweakHighColorOnShadow);
Set_HighColor += addColor;
if (any(addColor))
{
Set_HighColor = lerp(Set_HighColor, overridingColor.rgb, maskEnabled);
channelOutAlpha = _HighlightVisible;
}
}
#else
float3 Set_HighColor = (lerp(SATURATE_IF_SDR((Set_FinalBaseColor - _TweakHighColorMask_var)), Set_FinalBaseColor, lerp(_Is_BlendAddToHiColor, 1.0, _Is_SpecularToHighColor)) + lerp(_HighColor_var, (_HighColor_var * ((1.0 - Set_FinalShadowMask) + (Set_FinalShadowMask * _TweakHighColorOnShadow))), _Is_UseTweakHighColorOnShadow));
#endif
float4 _Set_RimLightMask_var = tex2D(_Set_RimLightMask, TRANSFORM_TEX(Set_UV0, _Set_RimLightMask));
float3 _Is_LightColor_RimLight_var = lerp(_RimLightColor.rgb, (_RimLightColor.rgb * Set_LightColor), _Is_LightColor_RimLight);
float _RimArea_var = dot(utsData.normalDirection, utsData.viewDirection);
_RimArea_var = lerp(_RimArea_var, 1 - _RimArea_var,_Is_BlendAddToRimColor);
float _RimLightPower_var = pow(_RimArea_var, exp2(lerp(3, 0, _RimLight_Power)));
float _Rimlight_InsideMask_var = saturate(lerp((0.0 + ((_RimLightPower_var - _RimLight_InsideMask) * (1.0 - 0.0)) / (1.0 - _RimLight_InsideMask)), step(_RimLight_InsideMask, _RimLightPower_var), _RimLight_FeatherOff));
float _VertHalfLambert_var = 0.5 * dot(utsData.normalDirection, lightDirection) + 0.5;
float3 _LightDirection_MaskOn_var = lerp((_Is_LightColor_RimLight_var * _Rimlight_InsideMask_var), (_Is_LightColor_RimLight_var * saturate((_Rimlight_InsideMask_var - ((1.0 - _VertHalfLambert_var) + _Tweak_LightDirection_MaskLevel)))), _LightDirection_MaskOn);
float _ApRimLightPower_var = pow(_RimArea_var, exp2(lerp(3, 0, _Ap_RimLight_Power)));
//Composition: HighColor and RimLight as _RimLight_var
#ifdef UTS_LAYER_VISIBILITY
float4 overridingRimColor = lerp(_RimLightMaskColor, float4(_RimLightMaskColor.w, _RimLightMaskColor.w, _RimLightMaskColor.w, 1.0f), _ComposerMaskMode);
float maskRimEnabled = max(_RimLightOverridden, _ComposerMaskMode);
float Set_RimLightAlpha = _RimLightVisible;
float3 Set_RimLight = (saturate((_Set_RimLightMask_var.g + _Tweak_RimLightMaskLevel)) * lerp(_LightDirection_MaskOn_var, (_LightDirection_MaskOn_var + (lerp(_Ap_RimLightColor.rgb, (_Ap_RimLightColor.rgb * Set_LightColor), _Is_LightColor_Ap_RimLight) * saturate((lerp((0.0 + ((_ApRimLightPower_var - _RimLight_InsideMask) * (1.0 - 0.0)) / (1.0 - _RimLight_InsideMask)), step(_RimLight_InsideMask, _ApRimLightPower_var), _Ap_RimLight_FeatherOff) - (saturate(_VertHalfLambert_var) + _Tweak_LightDirection_MaskLevel))))), _Add_Antipodean_RimLight));
Set_RimLight *= _RimLightVisible;
Set_RimLight *= _RimLight_Strength;
float3 _RimLight_var = lerp(lerp(Set_HighColor, (Set_HighColor * Set_RimLight), _RimLight), lerp(Set_HighColor, (Set_HighColor + Set_RimLight), _RimLight), _Is_BlendAddToRimColor);
if (any(Set_RimLight) * maskRimEnabled)
{
_RimLight_var = overridingRimColor;
channelOutAlpha = Set_RimLightAlpha;
}
_RimLight_var = lerp(_RimLight_var, (_RimLight_var * ((1.0 - Set_FinalShadowMask) + (Set_FinalShadowMask * _TweakHighColorOnShadow))), _Is_UseTweakHighColorOnShadow);
#else
float3 Set_RimLight = (saturate((_Set_RimLightMask_var.g + _Tweak_RimLightMaskLevel)) * lerp(_LightDirection_MaskOn_var, (_LightDirection_MaskOn_var + (lerp(_Ap_RimLightColor.rgb, (_Ap_RimLightColor.rgb * Set_LightColor), _Is_LightColor_Ap_RimLight) * saturate((lerp((0.0 + ((_ApRimLightPower_var - _RimLight_InsideMask) * (1.0 - 0.0)) / (1.0 - _RimLight_InsideMask)), step(_RimLight_InsideMask, _ApRimLightPower_var), _Ap_RimLight_FeatherOff) - (saturate(_VertHalfLambert_var) + _Tweak_LightDirection_MaskLevel))))), _Add_Antipodean_RimLight));
Set_RimLight *= _RimLight_Strength;
float3 _RimLight_var = lerp(lerp(Set_HighColor, (Set_HighColor * Set_RimLight), _RimLight), lerp(Set_HighColor, (Set_HighColor + Set_RimLight), _RimLight), _Is_BlendAddToRimColor);
_RimLight_var = lerp(_RimLight_var, (_RimLight_var * ((1.0 - Set_FinalShadowMask) + (Set_FinalShadowMask * _TweakHighColorOnShadow))), _Is_UseTweakHighColorOnShadow);
#endif
//v.2.0.4
#ifdef _IS_ANGELRING_OFF
#ifdef _IS_CLIPPING_MATTE
if (_ClippingMatteMode == 5)
{
clippingColor = float3(0.0f,0.0f,0.0f);
return clippingColor;
}
#endif // _IS_CLIPPING_MATTE
//float3 diffuseTerm = lerp(_RimLight_var, matCapColorFinal, _MatCap);// Final Composition before Emissive
//
#elif _IS_ANGELRING_ON
//float3 diffuseTerm = lerp(_RimLight_var, matCapColorFinal, _MatCap);// Final Composition before AR
//v.2.0.7 AR Camera Rolling Stabilizer
float3 _AR_OffsetU_var = lerp(mul(UNITY_MATRIX_V, float4(utsData.normalDirection, 0)).xyz, float3(0, 0, 1), _AR_OffsetU);
float2 AR_VN = _AR_OffsetU_var.xy * 0.5 + float2(0.5, 0.5);
float2 AR_VN_Rotate = RotateUV(AR_VN, -(utsData.cameraDir * utsData.cameraRoll), float2(0.5, 0.5), 1.0);
float2 _AR_OffsetV_var = float2(AR_VN_Rotate.x, lerp(input.texCoord1.y, AR_VN_Rotate.y, _AR_OffsetV));
float4 _AngelRing_Sampler_var = tex2D(_AngelRing_Sampler, TRANSFORM_TEX(_AR_OffsetV_var, _AngelRing_Sampler));
float3 _Is_LightColor_AR_var = lerp((_AngelRing_Sampler_var.rgb * _AngelRing_Color.rgb), ((_AngelRing_Sampler_var.rgb * _AngelRing_Color.rgb) * Set_LightColor), _Is_LightColor_AR);
_Is_LightColor_AR_var = _Is_LightColor_AR_var * max(_AR_ShadowIntensity, (1 - Set_FinalShadowMask));
float3 Set_AngelRing = _Is_LightColor_AR_var * _AR_Intensity;
float Set_ARtexAlpha = _AngelRing_Sampler_var.a;
float3 Set_AngelRingWithAlpha = (_Is_LightColor_AR_var * _AngelRing_Sampler_var.a);
//Composition: MatCap and AngelRing as diffuseTerm
# ifdef UTS_LAYER_VISIBILITY
{
float4 overridingColor = lerp(_AngelRingMaskColor, float4(_AngelRingMaskColor.w, _AngelRingMaskColor.w, _AngelRingMaskColor.w, 1.0f), _ComposerMaskMode);
float maskEnabled = max(_AngelRingOverridden, _ComposerMaskMode);
_AngelRing *= _AngelRingVisible;
diffuseTerm = lerp(diffuseTerm, lerp((diffuseTerm + Set_AngelRing), ((diffuseTerm * (1.0 - Set_ARtexAlpha)) + Set_AngelRingWithAlpha), _ARSampler_AlphaOn), _AngelRing);// Final Composition before Emissive
if (any(Set_AngelRing) * maskEnabled)
{
diffuseTerm = lerp(diffuseTerm, lerp(overridingColor.xyz, ((diffuseTerm * (1.0 - Set_ARtexAlpha)) + Set_AngelRingWithAlpha), _ARSampler_AlphaOn), _AngelRing);// Final Composition before Emissive
channelOutAlpha = _AngelRingVisible;
}
}
# else
diffuseTerm = lerp(diffuseTerm, lerp((diffuseTerm + Set_AngelRing), ((diffuseTerm * (1.0 - Set_ARtexAlpha)) + Set_AngelRingWithAlpha), _ARSampler_AlphaOn), _AngelRing);// Final Composition before Emissive
# endif //#ifdef UTS_LAYER_VISIBILITY
#ifdef _IS_CLIPPING_MATTE
if (_ClippingMatteMode == 5)
{
clippingColor = _Is_LightColor_AR_var;
return clippingColor;
}
#endif // _IS_CLIPPING_MATTE
//diffuseTerm = Set_AngelRing * 10 * (1 - Set_FinalShadowMask);
#endif //#ifdef _IS_ANGELRING_OFF
// PBR----------------------------------------------------------------------------------------------------------------
//Specular Term
//float3 specularTerm = ComputeSpecularTerm(V, lightDirection, bsdfData) * (1 - Set_FinalShadowMask) * PI * surfaceData.specularColor * Set_LightColor;
float3 specularTerm = 0;
//SSS
float3 sssColor = SAMPLE_TEXTURE2D(_SSSLutMap, s_linear_clamp_sampler, FitWithCurveApprox(1 - Set_FinalShadowMask, 1));
sssColor *= _BaseColor.rgb * _MainTex_var.rgb * Set_LightColor;
specularTerm *= lerp((1 - Set_FinalShadowMask), FitWithCurveApprox(1 - Set_FinalShadowMask, 1).r, _Use_SSSLut);
diffuseTerm = lerp(diffuseTerm, sssColor, _Use_SSSLut);
utsAggregateLighting.directDiffuse += diffuseTerm * utsLightData.diffuseDimmer;
utsAggregateLighting.directSpecular += specularTerm * utsLightData.specularDimmer;
#endif // _SDFShadow
}

View File

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

View File

@@ -0,0 +1,258 @@
//Unity Toon Shader/HDRP
//nobuyuki@unity3d.com
//toshiyuki@unity3d.com (Universal RP/HDRP)
#include "Packages/com.misaki.hdrp-toon/Runtime/HDRP/Shaders/Includes/Common/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;
// We dont have to calculate lighting here if we are using sdf shadow
#ifndef _SDFShadow
#ifdef _IS_CLIPPING_MATTE
if (_ClippingMatteMode != 0)
{
return float3(0.0f, 0.0f, 0.0f);
}
#endif // _IS_CLIPPING_MATTE
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
// input.positionSS is SV_Position
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);
/* todo. these should be put into struct */
#ifdef VARYINGS_NEED_POSITION_WS
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
#else
// Unused
float3 V = float3(1.0, 1.0, 1.0); // Avoid the division by 0
#endif
float3 lightDirection = utsLightData.lightDirection;
float3 additionalLightColor = utsLightData.lightColor * _Light_Intensity_Multiplier;
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);
float4 Set_UV0 = input.texCoord0;
float3x3 tangentTransform = input.tangentToWorld;
//UnpackNormalmapRGorAG(SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, texCoords))
float3 normalDirection = surfaceData.normalWS; // Perturbed normals
float3 viewDirection = V;
float4 _MainTex_var = float4(surfaceData.baseColor.r, surfaceData.baseColor.g, surfaceData.baseColor.b, surfaceData.coatMask);
/* end of todo.*/
SHADOW_TYPE shadowAttenuation = lightLoopContext.shadowValue;
#if !defined (UTS_USE_RAYTRACING_SHADOW)
shadowAttenuation *= 2.0f;
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 + 0.5f) / PI * additionalLightColor.rgb;
}
else if (lightType == GPULIGHTTYPE_RECTANGLE)
{
addPassLightColor = preLightData.diffuseFGD * additionalLightColor.rgb;
}
else
{
addPassLightColor = _HalfLambert_var * additionalLightColor.rgb;
}
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:
_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, 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);
float maskEnabled = max(_BaseColorOverridden, _ComposerMaskMode);
Set_BaseColor = lerp(Set_BaseColor, overridingColor, maskEnabled);
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);
#ifdef UTS_LAYER_VISIBILITY
{
float4 overridingColor = lerp(_FirstShadeMaskColor, float4(_FirstShadeMaskColor.w, _FirstShadeMaskColor.w, _FirstShadeMaskColor.w, 1.0f), _ComposerMaskMode);
float maskEnabled = max(_FirstShadeOverridden, _ComposerMaskMode);
Set_1st_ShadeColor = lerp(Set_1st_ShadeColor, overridingColor, maskEnabled);
Set_1st_ShadeColor = lerp(Set_1st_ShadeColor, Set_BaseColor, 1.0f - _FirstShadeVisible);
}
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);
#ifdef UTS_LAYER_VISIBILITY
{
float4 overridingColor = lerp(_SecondShadeMaskColor, float4(_SecondShadeMaskColor.w, _SecondShadeMaskColor.w, _SecondShadeMaskColor.w, 1.0f), _ComposerMaskMode);
float maskEnabled = max(_SecondShadeOverridden, _ComposerMaskMode);
Set_2nd_ShadeColor = lerp(Set_2nd_ShadeColor, overridingColor, maskEnabled);
Set_2nd_ShadeColor = lerp(Set_2nd_ShadeColor, Set_BaseColor, 1.0f - _SecondShadeVisible);
}
#endif //#ifdef UTS_LAYER_VISIBILITY
// //v.2.0.5:
//SGM
//v.2.0.6
float4 _ShadingGradeMap_var = tex2Dlod(_ShadingGradeMap, float4(TRANSFORM_TEX(Set_UV0, _ShadingGradeMap), 0.0, _BlurLevelSGM));
//v.2.0.6
//Minmimum value is same as the Minimum Feather's value with the Minimum Step's value as threshold.
float _SystemShadowsLevel_var = (shadowAttenuation * 0.5) + 0.5 + _Tweak_SystemShadowsLevel > 0.001 ? (shadowAttenuation * 0.5) + 0.5 + _Tweak_SystemShadowsLevel : 0.0001;
float _ShadingGradeMapLevel_var = _ShadingGradeMap_var.r < 0.95 ? _ShadingGradeMap_var.r + _Tweak_ShadingGradeMapLevel : 1;
float Set_ShadingGrade = saturate(_ShadingGradeMapLevel_var)*lerp( _HalfLambert_var, (_HalfLambert_var * saturate(_SystemShadowsLevel_var)), _Set_SystemShadowsToBase );
//float Set_ShadingGrade = saturate(_ShadingGradeMapLevel_var) * lerp(_HalfLambert_var, (_HalfLambert_var * saturate(1.0 + _Tweak_SystemShadowsLevel)), _Set_SystemShadowsToBase);
float _1stColorFeatherForMask = lerp(_1st_ShadeColor_Feather, 0.0f, max(_FirstShadeOverridden, _ComposerMaskMode));
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
//SGM
//Composition: 3 Basic Colors as diffuseTerm
float3 diffuseTerm =
lerp(
Set_BaseColor,
lerp(
Set_1st_ShadeColor,
Set_2nd_ShadeColor,
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));
float _Specular_var = 0.5 * dot(halfDirection, lerp(i_normalDir, normalDirection, _Is_NormalMapToHighColor)) + 0.5; // Specular
float _TweakHighColorMask_var = (saturate((_Set_HighColorMask_var.g + _Tweak_HighColorMaskLevel)) * lerp((1.0 - step(_Specular_var, (1.0 - pow(_HighColor_Power, 5)))), pow(_Specular_var, exp2(lerp(11, 1, _HighColor_Power))), _Is_SpecularToHighColor));
float4 _HighColor_Tex_var = tex2D(_HighColor_Tex, TRANSFORM_TEX(Set_UV0, _HighColor_Tex));
float3 _HighColor_var = lerp((_HighColor_Tex_var.rgb * _HighColor.rgb), ((_HighColor_Tex_var.rgb * _HighColor.rgb) * Set_LightColor), _Is_LightColor_HighColor);
float4 _Set_RimLightMask_var = tex2D(_Set_RimLightMask, TRANSFORM_TEX(Set_UV0, _Set_RimLightMask));
float3 _Is_LightColor_RimLight_var = lerp(_RimLightColor.rgb, (_RimLightColor.rgb * Set_LightColor), _Is_LightColor_RimLight);
float _RimArea_var = dot(surfaceData.normalWS, V);
_RimArea_var = lerp(_RimArea_var, 1 - _RimArea_var, _Is_BlendAddToRimColor);
float _RimLightPower_var = pow(_RimArea_var, exp2(lerp(3, 0, _RimLight_Power)));
float _Rimlight_InsideMask_var = saturate(lerp((0.0 + ((_RimLightPower_var - _RimLight_InsideMask) * (1.0 - 0.0)) / (1.0 - _RimLight_InsideMask)), step(_RimLight_InsideMask, _RimLightPower_var), _RimLight_FeatherOff));
float _VertHalfLambert_var = 0.5 * dot(surfaceData.normalWS, lightDirection) + 0.5;
float3 _LightDirection_MaskOn_var = lerp((_Is_LightColor_RimLight_var * _Rimlight_InsideMask_var), (_Is_LightColor_RimLight_var * saturate((_Rimlight_InsideMask_var - ((1.0 - _VertHalfLambert_var) + _Tweak_LightDirection_MaskLevel)))), _LightDirection_MaskOn);
float _ApRimLightPower_var = pow(_RimArea_var, exp2(lerp(3, 0, _Ap_RimLight_Power)));
//Composition: HighColor and RimLight as _RimLight_var
#ifdef UTS_LAYER_VISIBILITY
float4 overrideColor = lerp(_HighlightMaskColor, float4(_HighlightMaskColor.w, _HighlightMaskColor.w, _HighlightMaskColor.w, 1.0f), _ComposerMaskMode);
float isMaskEnabled = max(_HighlightOverridden, _ComposerMaskMode);
//_HighColor_var *= _TweakHighColorMask_var;
//_HighColor_var *= _HighlightVisible;
float4 overridingRimColor = lerp(_RimLightMaskColor, float4(_RimLightMaskColor.w, _RimLightMaskColor.w, _RimLightMaskColor.w, 1.0f), _ComposerMaskMode);
float maskRimEnabled = max(_RimLightOverridden, _ComposerMaskMode);
float Set_RimLightAlpha = _RimLightVisible;
float3 Set_RimLight = (saturate((_Set_RimLightMask_var.g + _Tweak_RimLightMaskLevel)) * lerp(_LightDirection_MaskOn_var, (_LightDirection_MaskOn_var + (lerp(_Ap_RimLightColor.rgb, (_Ap_RimLightColor.rgb * Set_LightColor), _Is_LightColor_Ap_RimLight) * saturate((lerp((0.0 + ((_ApRimLightPower_var - _RimLight_InsideMask) * (1.0 - 0.0)) / (1.0 - _RimLight_InsideMask)), step(_RimLight_InsideMask, _ApRimLightPower_var), _Ap_RimLight_FeatherOff) - (saturate(_VertHalfLambert_var) + _Tweak_LightDirection_MaskLevel))))), _Add_Antipodean_RimLight));
Set_RimLight *= _RimLightVisible;
Set_RimLight *= _RimLight_Strength;
if (any(Set_RimLight) * maskRimEnabled)
{
//_HighColor_var = overridingRimColor;
channelOutAlpha = Set_RimLightAlpha;
}
/*
diffuseTerm =
lerp(saturate(diffuseTerm - _TweakHighColorMask_var), diffuseTerm,
lerp(_Is_BlendAddToHiColor, 1.0
, _Is_SpecularToHighColor));
float3 addColor =
lerp(_HighColor_var, (_HighColor_var * ((1.0 - Set_FinalShadowMask) + (Set_FinalShadowMask * _TweakHighColorOnShadow)))
, _Is_UseTweakHighColorOnShadow);
diffuseTerm += addColor;
if (any(addColor))
{
diffuseTerm = lerp(diffuseTerm, overrideColor, isMaskEnabled);
channelOutAlpha = _HighlightVisible;
}
*/
// Rim light
diffuseTerm = lerp(lerp(diffuseTerm, (diffuseTerm * Set_RimLight), _RimLight), lerp(diffuseTerm, (diffuseTerm + Set_RimLight), _RimLight), _Is_BlendAddToRimColor);
#else
_HighColor_var *= _TweakHighColorMask_var;
float3 Set_RimLight = (saturate((_Set_RimLightMask_var.g + _Tweak_RimLightMaskLevel)) * lerp(_LightDirection_MaskOn_var, (_LightDirection_MaskOn_var + (lerp(_Ap_RimLightColor.rgb, (_Ap_RimLightColor.rgb * Set_LightColor), _Is_LightColor_Ap_RimLight) * saturate((lerp((0.0 + ((_ApRimLightPower_var - _RimLight_InsideMask) * (1.0 - 0.0)) / (1.0 - _RimLight_InsideMask)), step(_RimLight_InsideMask, _ApRimLightPower_var), _Ap_RimLight_FeatherOff) - (saturate(_VertHalfLambert_var) + _Tweak_LightDirection_MaskLevel))))), _Add_Antipodean_RimLight));
Set_RimLight *= _RimLight_Strength;
diffuseTerm = diffuseTerm + lerp(lerp(_HighColor_var, (_HighColor_var * ((1.0 - Set_FinalShadowMask) + (Set_FinalShadowMask * _TweakHighColorOnShadow))), _Is_UseTweakHighColorOnShadow), float3(0, 0, 0), _Is_Filter_HiCutPointLightColor);
// Rim light
diffuseTerm = lerp(lerp(diffuseTerm, (diffuseTerm * Set_RimLight), _RimLight), lerp(diffuseTerm, (diffuseTerm + Set_RimLight), _RimLight), _Is_BlendAddToRimColor);
#endif
// PBR----------------------------------------------------------------------------------------------------------------
float albedoIntensity = max(0.1, (1 - sqrt(surfaceData.metallic)) * (1.7 - 0.7 * (1 - sqrt(surfaceData.metallic))));
//Specular Term
float3 specularTerm = 0;
#ifndef _PBR_Mode_OFF
if(lightType == GPULIGHTTYPE_RECTANGLE || lightType == GPULIGHTTYPE_TUBE)
{
specularTerm = preLightData.specularFGD * Set_LightColor;
#ifdef _PBR_Mode_TOON
specularTerm = StepFeatherToon(specularTerm, _ToonSpecularStep, _ToonSpecularFeather);
#endif
}
else
{
//specularTerm = ComputeSpecularTerm(V, lightDirection, bsdfData) * Set_LightColor;
}
#endif
specularTerm = specularTerm * (1.0 - Set_FinalShadowMask) * PI * surfaceData.specularColor;
diffuseTerm = diffuseTerm * albedoIntensity;
utsAggregateLighting.directDiffuse += diffuseTerm * utsLightData.diffuseDimmer;
utsAggregateLighting.directSpecular += specularTerm * utsLightData.specularDimmer;
#endif // _SDFShadow
}

View File

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

View File

@@ -0,0 +1,220 @@
#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, HALF_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, bool isDiffuse)
{
float l = length(F);
float z = lerp(F.z , INV_TWO_PI * F.z, isDiffuse);
return max(0, (l * l + z) / (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, isDiffuse); // Accounts for the horizon.
}
// This function assumes that inputs are well-behaved, e.i.
// that the line does not pass through the origin and
// that the light is (at least partially) above the surface.
float UTS_Diffuse_Line(float3 C, float3 A, float hl)
{
// Solve C.z + h * A.z = 0.
float h = -C.z * rcp(A.z); // May be Inf, but never NaN
// Clip the line segment against the z-plane if necessary.
float h2 = (A.z >= 0) ? max( hl, h)
: min( hl, h); // P2 = C + h2 * A
float h1 = (A.z >= 0) ? max(-hl, h)
: min(-hl, h); // P1 = C + h1 * A
// Normalize the tangent.
float as = dot(A, A); // |A|^2
float ar = rsqrt(as); // 1/|A|
float a = as * ar; // |A|
float3 T = A * ar; // A/|A|
// Orthogonal 2D coordinates:
// P(n, t) = n * N + t * T.
float tc = dot(T, C); // C = n * N + tc * T
float3 P0 = C - tc * T; // P(n, 0) = n * N
float ns = dot(P0, P0); // |P0|^2
float nr = rsqrt(ns); // 1/|P0|
float n = ns * nr; // |P0|
float Nz = P0.z * nr; // N.z = P0.z/|P0|
// P(n, t) - C = P0 + t * T - P0 - tc * T
// = (t - tc) * T = h * A = (h * a) * T.
float t2 = tc + h2 * a; // P2.t
float t1 = tc + h1 * a; // P1.t
float s2 = ns + t2 * t2; // |P2|^2
float s1 = ns + t1 * t1; // |P1|^2
float mr = rsqrt(s1 * s2); // 1/(|P1|*|P2|)
float r2 = s1 * (mr * mr); // 1/|P2|^2
float r1 = s2 * (mr * mr); // 1/|P1|^2
// I = (i1 + i2 + i3) / Pi.
// i1 = N.z * (P2.t / |P2|^2 - P1.t / |P1|^2).
// i2 = -T.z * (P2.n / |P2|^2 - P1.n / |P1|^2).
// i3 = N.z * ArcCos[Dot[P1, P2] / (|P1| * |P2|)] / |P0|.
float i12 = (Nz * t2 - (T.z * n)) * r2
- (Nz * t1 - (T.z * n)) * r1;
// Guard against numerical errors.
float dt = min(1, (ns + t1 * t2) * mr);
float i3 = acos(dt) * (Nz * nr); // angle * cos(θ) / r^2
//return T.z * n ;
// Guard against numerical errors.
return INV_PI * max(0, i12 + i3);
}
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
// Polygon irradiance in the transformed configuration.
float3 fromFactor;
ltcValue.a = UTS_PolygonIrradiance(lightVerts, isDiffuse, fromFactor);
if (cookieMode != COOKIEMODE_NONE)
{
ltcValue.rgb = SampleAreaLightCookie(cookieScaleOffset, lightVerts, fromFactor, perceptualRoughness);
}
}
else // Line light
{
float w = ComputeLineWidthFactor(invM, ortho, orthoSq);
ltcValue.a = UTS_Diffuse_Line(C, A, halfLength) * w;
}
return ltcValue;
}
#endif

View File

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

View File

@@ -0,0 +1,231 @@
#ifndef UTS_ENV
#define UTS_ENV
#include "Packages/com.misaki.hdrp-toon/Runtime/HDRP/Shaders/Includes/Common/UtsCommon.hlsl"
// _preIntegratedFGD and _CubemapLD are unique for each BRDF
float3 EvaluateBSDF_ReflectionProbe(LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, EnvLightData lightData, UtsBSDFData bsdfData,
int influenceShapeType,
inout float hierarchyWeight)
{
float weight = 1.0;
float3 R = reflect(-V, bsdfData.normalWS);
EvaluateLight_EnvIntersection(posInput.positionWS, bsdfData.normalWS, lightData, influenceShapeType, R, weight);
// No distance based roughness for simple lit
float4 preLD = SampleEnv(lightLoopContext, lightData.envIndex, R, PerceptualRoughnessToMipmapLevel(preLightData.iblPerceptualRoughness) * lightData.roughReflections, lightData.rangeCompressionFactorCompensation, posInput.positionNDC);
weight *= preLD.a; // Used by planar reflection to discard pixel
//envLighting = F_Schlick(bsdfData.fresnel0, dot(bsdfData.normalWS, V)) * preLD.rgb;
float3 envLighting = preLD.rgb;
UpdateLightingHierarchyWeights(hierarchyWeight, weight);
envLighting *= weight * lightData.multiplier;
return envLighting;
}
float4 ComputeReflection(LightLoopContext context, PositionInputs posInput, PreLightData preLightData, BuiltinData builtinData, UtsBSDFData bsdfData, float3 V)
{
float3 refcolor = 0;
float reflectionHierarchyWeight = 0.0; // Max: 1.0
uint envLightStart, envLightCount;
// Fetch first env light to provide the scene proxy for screen space computation
#ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
GetCountAndStart(posInput, LIGHTCATEGORY_ENV, envLightStart, envLightCount);
#else // LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
envLightCount = _EnvLightCount;
envLightStart = 0;
#endif
bool fastPath = false;
#if SCALARIZE_LIGHT_LOOP
uint envStartFirstLane;
fastPath = IsFastPath(envLightStart, envStartFirstLane);
#endif
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
#if SCALARIZE_LIGHT_LOOP
if (fastPath)
{
envLightStart = envStartFirstLane;
}
#endif
// Scalarized loop, same rationale of the punctual light version
uint v_envLightListOffset = 0;
uint v_envLightIdx = envLightStart;
#if NEED_TO_CHECK_HELPER_LANE
// On some platform helper lanes don't behave as we'd expect, therefore we prevent them from entering the loop altogether.
// IMPORTANT! This has implications if ddx/ddy is used on results derived from lighting, however given Lightloop is called in compute we should be
// sure it will not happen.
bool isHelperLane = WaveIsHelperLane();
while (!isHelperLane && v_envLightListOffset < envLightCount)
#else
while (v_envLightListOffset < envLightCount)
#endif
{
v_envLightIdx = FetchIndex(envLightStart, v_envLightListOffset);
#if SCALARIZE_LIGHT_LOOP
uint s_envLightIdx = ScalarizeElementIndex(v_envLightIdx, fastPath);
#else
uint s_envLightIdx = v_envLightIdx;
#endif
if (s_envLightIdx == -1)
break;
EnvLightData s_envLightData = FetchEnvLight(s_envLightIdx); // Scalar load.
// If current scalar and vector light index match, we process the light. The v_envLightListOffset for current thread is increased.
// Note that the following should really be ==, however, since helper lanes are not considered by WaveActiveMin, such helper lanes could
// end up with a unique v_envLightIdx value that is smaller than s_envLightIdx hence being stuck in a loop. All the active lanes will not have this problem.
if (s_envLightIdx >= v_envLightIdx)
{
v_envLightListOffset++;
if (reflectionHierarchyWeight < 1.0)
{
if (IsMatchingLightLayer(s_envLightData.lightLayers, builtinData.renderingLayers))
{
float RefProbeLighting = EvaluateBSDF_ReflectionProbe(context, V, posInput, preLightData, s_envLightData, bsdfData, s_envLightData.influenceShapeType, reflectionHierarchyWeight);
#if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)
float3 lightInReflDir = float3(-1, -1, -1);
if (s_envLightData.normalizeWithAPV > 0 && all(lightInReflDir >= 0))
{
float factor = GetReflectionProbeNormalizationFactor(lightInReflDir, bsdfData.normalWS, s_envLightData.L0L1, s_envLightData.L2_1, s_envLightData.L2_2);
RefProbeLighting *= factor;
}
#endif
refcolor += RefProbeLighting;
}
}
}
}
return float4(refcolor.r, refcolor.g, refcolor.b, reflectionHierarchyWeight);
}
float3 ComputeFresnelLerp(float3 c0, float3 c1, float cosA)
{
float t = pow(1 - cosA, 5);
return lerp(c0, c1, t);
}
float3 EvaluateIndirectDiffusePBR(PositionInputs posInput, UtsBSDFData bsdfData, float3 V)
{
float3 indirectDiffuse = 0.0;
#ifdef _PBR_Mode_ANISO
GetGGXAnisotropicModifiedNormalAndRoughness(bsdfData.bitangentWS, bsdfData.tangentWS , bsdfData.normalWS, V, bsdfData.anisotropy, bsdfData.perceptualRoughness, bsdfData.normalWS, bsdfData.perceptualRoughness);
#endif
float NdotV = saturate(dot(bsdfData.normalWS, V));
#if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)
BuiltinData apvBuiltinData;
ZERO_INITIALIZE(BuiltinData, apvBuiltinData);
#if defined(_PBR_Mode_OFF) || defined(_PBR_Mode_TOON)
EvaluateAdaptiveProbeVolume(GetAbsolutePositionWS(posInput.positionWS), 0.0, 0.0, V, posInput.positionSS, apvBuiltinData.bakeDiffuseLighting, apvBuiltinData.backBakeDiffuseLighting);
#else
EvaluateAdaptiveProbeVolume(GetAbsolutePositionWS(posInput.positionWS), bsdfData.normalWS, -bsdfData.normalWS, V, posInput.positionSS, apvBuiltinData.bakeDiffuseLighting, apvBuiltinData.backBakeDiffuseLighting);
#endif
float3 probeDiffuse = apvBuiltinData.bakeDiffuseLighting * GetCurrentExposureMultiplier();
indirectDiffuse = probeDiffuse;
#else
#if defined(_PBR_Mode_OFF) || defined(_PBR_Mode_TOON)
indirectDiffuse = EvaluateAmbientProbe(0.0) * GetCurrentExposureMultiplier();
#else
indirectDiffuse = EvaluateAmbientProbe(bsdfData.normalWS) * GetCurrentExposureMultiplier();
#endif
#endif
//SSGI
if(_ReceivesSSGI == 1)
{
float4 ssgiLighting = LOAD_TEXTURE2D_X(_IndirectDiffuseTexture, posInput.positionSS);
ssgiLighting *= _GIMultiplier;
indirectDiffuse = lerp(indirectDiffuse, ssgiLighting.rgb, ssgiLighting.a);
}
//Complete the indirect lighting
indirectDiffuse *= bsdfData.diffuseColor.rgb * _BaseColor.rgb;
//SSAO
if(_ReceivesSSAO == 1)
{
AmbientOcclusionFactor aoFactor;
GetScreenSpaceAmbientOcclusionMultibounce(posInput.positionSS, NdotV, bsdfData.perceptualRoughness, bsdfData.ambientOcclusion, bsdfData.specularOcclusion, bsdfData.diffuseColor, bsdfData.fresnel0, aoFactor);
indirectDiffuse *= lerp(_AO_Factor, 1, aoFactor.indirectAmbientOcclusion);
}
indirectDiffuse *= bsdfData.ambientOcclusion;
return indirectDiffuse;
}
float3 EvaluateIndirectDiffuse(PositionInputs posInput, UtsBSDFData bsdfData, float3 V)
{
float3 indirectDiffuse = 0.0;
indirectDiffuse = EvaluateIndirectDiffusePBR(posInput, bsdfData,V);
return indirectDiffuse * _ID_Intensity;
}
float3 EvaluateIndirectSpecular(LightLoopContext lightLoopContext, PositionInputs posInput, PreLightData preLightData, UtsBSDFData bsdfData, BuiltinData builtinData, float3 V)
{
#if defined(_PBR_Mode_OFF) || defined(_PBR_Mode_TOON)
return 0;
#else
float3 indirectSpecular = 0;
#ifdef _PBR_Mode_ANISO
GetGGXAnisotropicModifiedNormalAndRoughness(bsdfData.bitangentWS, bsdfData.tangentWS , bsdfData.normalWS, V, bsdfData.anisotropy, bsdfData.perceptualRoughness, bsdfData.normalWS, bsdfData.perceptualRoughness);
#endif
float mip = PerceptualRoughnessToMipmapLevel(bsdfData.perceptualRoughness);
float NdotV = saturate(dot(bsdfData.normalWS, V));
indirectSpecular = SampleSkyTexture(reflect(-V, bsdfData.normalWS), mip, 0).rgb;\
//Reflection Probe
float4 refProbe = ComputeReflection(lightLoopContext, posInput, preLightData, builtinData, bsdfData, V);
indirectSpecular = lerp(indirectSpecular, refProbe.rgb, refProbe.a);
//SSR
if(_ReceivesSSR == 1)
{
float4 ssrLighting = LOAD_TEXTURE2D_X(_SsrLightingTexture, posInput.positionSS);
InversePreExposeSsrLighting(ssrLighting);
ApplyScreenSpaceReflectionWeight(ssrLighting);
indirectSpecular = lerp(indirectSpecular, ssrLighting.rgb * preLightData.specularFGD, ssrLighting.a);
}
//Complete the indirect lighting
float grazingTerm = saturate((1 - bsdfData.perceptualRoughness) + (1 - bsdfData.reflectivity));
indirectSpecular *= ComputeFresnelLerp(bsdfData.fresnel0, grazingTerm, NdotV) * GetCurrentExposureMultiplier();
// Occlusion
if(_ReceivesSSAO == 1)
{
AmbientOcclusionFactor aoFactor;
GetScreenSpaceAmbientOcclusionMultibounce(posInput.positionSS, NdotV, bsdfData.perceptualRoughness, bsdfData.ambientOcclusion, bsdfData.specularOcclusion, bsdfData.diffuseColor, bsdfData.fresnel0, aoFactor);
indirectSpecular *= lerp(_AO_Factor, 1, aoFactor.indirectSpecularOcclusion);
}
indirectSpecular *= bsdfData.specularOcclusion;
return indirectSpecular * _IR_Intensity;
#endif
}
#endif

View File

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

View File

@@ -0,0 +1,264 @@
#ifndef UTS_LIGHT_EVALUATION
#define UTS_LIGHT_EVALUATION
#if FP_BUFFER
#define SATURATE_IF_SDR(x) (x)
#define SATURATE_BASE_COLOR_IF_SDR(x) (x)
#else
#define SATURATE_IF_SDR(x) saturate(x)
#define SATURATE_BASE_COLOR_IF_SDR(x) saturate(x)
#endif
const float rateR = 0.299;
const float rateG = 0.587;
const float rateB = 0.114;
struct UTSLightData
{
float3 lightDirection;
float3 lightColor;
float diffuseDimmer;
float specularDimmer;
float3 shadowTint;
float penumbraTint;
SHADOW_TYPE shadowValue;
};
float GetColorAttenuation(float3 lightColor)
{
float lightAttenuation = rateR * lightColor.r + rateG * lightColor.g + rateB * lightColor.b;
return lightAttenuation;
}
float3 GetLimitedLightColor(float3 lightColor)
{
lightColor = ApplyCurrentExposureMultiplier(lightColor);
float3 result = lerp(lightColor, saturate(lightColor), _Is_Filter_LightColor);
return result;
}
DirectLighting UtsEvaluateBSDF_Directional(LightLoopContext lightLoopContext, PositionInputs posInput, BuiltinData builtinData, DirectionalLightData lightData, UtsBSDFData bsdfData, PreLightData preLightData, float3 V, float2 uv0)
{
DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
float3 L = -lightData.forward;
SHADOW_TYPE shadow = EvaluateShadow_Directional(lightLoopContext, posInput, lightData, builtinData, bsdfData.geomNormalWS);
if (lightData.lightDimmer > 0.0)
{
// TODO: Colored shadow will overwrite the first and second shading diffuse color
//float3 shadowColor = ComputeShadowColor(shadow, lightData.shadowTint, lightData.penumbraTint);
float4 lightColor = EvaluateLight_Directional(lightLoopContext, posInput, lightData);
lightColor.rgb = GetLimitedLightColor(lightColor.rgb * lightColor.a * _Light_Intensity_Multiplier);
UtsClampRoughness(preLightData, bsdfData, lightData.minRoughness);
lighting = UtsShadeSurface(posInput, bsdfData, preLightData, shadow, lightColor.rgb, V, L, uv0, lightData.diffuseDimmer, lightData.specularDimmer);
}
return lighting;
}
DirectLighting UtsEvaluateBSDF_Punctual(LightLoopContext lightLoopContext, PositionInputs posInput, BuiltinData builtinData, LightData lightData, UtsBSDFData bsdfData, PreLightData preLightData, float3 V, float2 uv0)
{
DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
float3 L;
float4 distances; // {d, d^2, 1/d, d_proj}
GetPunctualLightVectors(posInput.positionWS, lightData, L, distances);
PositionInputs shadowPositionInputs = posInput;
shadowPositionInputs.positionWS = posInput.positionWS + L * _ShadowBias;
SHADOW_TYPE shadow = EvaluateShadow_Punctual(lightLoopContext, shadowPositionInputs, lightData, builtinData, bsdfData.geomNormalWS, L, distances);
if (lightData.lightDimmer > 0.0)
{
// TODO: Colored shadow will overwrite the first and second shading diffuse color
//float3 shadowColor = ComputeShadowColor(shadow, lightData.shadowTint, lightData.penumbraTint);
float4 lightColor = EvaluateLight_Punctual(lightLoopContext, posInput, lightData, L, distances);
lightColor.rgb = GetLimitedLightColor(lightColor.rgb * lightColor.a * _Light_Intensity_Multiplier);
UtsClampRoughness(preLightData, bsdfData, lightData.minRoughness);
lighting = UtsShadeSurface(posInput, bsdfData, preLightData, shadow, lightColor.rgb, V, L, uv0, lightData.diffuseDimmer, lightData.specularDimmer);
}
return lighting;
}
IndirectLighting UtsEvaluateBSDF_ScreenSpaceReflection(PositionInputs posInput, PreLightData preLightData, inout float reflectionHierarchyWeight)
{
IndirectLighting lighting;
ZERO_INITIALIZE(IndirectLighting, lighting);
// TODO: this texture is sparse (mostly black). Can we avoid reading every texel? How about using Hi-S?
float4 ssrLighting = LOAD_TEXTURE2D_X(_SsrLightingTexture, posInput.positionSS);
InversePreExposeSsrLighting(ssrLighting);
// Apply the weight on the ssr contribution (if required)
ApplyScreenSpaceReflectionWeight(ssrLighting);
reflectionHierarchyWeight = ssrLighting.a;
lighting.specularReflected = ssrLighting.rgb * preLightData.specularFGD;
return lighting;
}
void UtsEvaluateBSDF_BakeDiffuse(PositionInputs posInput, PreLightData preLightData, UtsBSDFData bsdfData, float3 V, inout BuiltinData builtinData, out float3 lightInReflDir)
{
lightInReflDir = 0.0;
#if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)
lightInReflDir = float3(-1, -1, -1); // This variable is used with APV for reflection probe normalization - see code for LIGHTFEATUREFLAGS_ENV
#endif
#if !defined(_SURFACE_TYPE_TRANSPARENT) && !defined(SCREEN_SPACE_INDIRECT_DIFFUSE_DISABLED)
if (_IndirectDiffuseMode != INDIRECTDIFFUSEMODE_OFF)
{
builtinData.bakeDiffuseLighting = LOAD_TEXTURE2D_X(_IndirectDiffuseTexture, posInput.positionSS).xyz * GetInverseCurrentExposureMultiplier();
}
else
#endif
{
#if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)
if (_EnableProbeVolumes)
{
// Reflect normal to get lighting for reflection probe tinting
float3 R = reflect(-V, bsdfData.normalWS);
#if defined(_PBR_Mode_OFF) || defined(_PBR_Mode_TOON)
float3 normalWS = 0.0;
float3 backNormalWS = 0.0;
#else
float3 normalWS = bsdfData.normalWS;
float3 backNormalWS = -bsdfData.normalWS;
#endif
EvaluateAdaptiveProbeVolume(GetAbsolutePositionWS(posInput.positionWS),
bsdfData.normalWS, -bsdfData.normalWS,
R, V,
posInput.positionSS, builtinData.renderingLayers,
builtinData.bakeDiffuseLighting, builtinData.backBakeDiffuseLighting, lightInReflDir);
}
else // If probe volume is disabled we fallback on the ambient probes
{
builtinData.bakeDiffuseLighting = EvaluateAmbientProbe(bsdfData.normalWS);
builtinData.backBakeDiffuseLighting = EvaluateAmbientProbe(-bsdfData.normalWS);
}
#endif
}
}
void UtsEvaluateBSDF_MatCapDiffuse(float3 positionWS, float3 normalWS, inout BuiltinData builtinData)
{
float3 positionVS = mul(UNITY_MATRIX_V, float4(positionWS, 1.0)).xyz;
float3 normalVS = mul(UNITY_MATRIX_V, float4(normalWS, 1.0)).xyz;
float3 PcrossN = cross(normalize(positionVS), normalVS);
float2 uv = PcrossN.yx;
uv.x *= -1;
uv = uv * 0.5 + 0.5;
builtinData.bakeDiffuseLighting = SAMPLE_TEXTURE2D_LOD(_MatCapMap, s_linear_clamp_sampler, uv, UNITY_SPECCUBE_LOD_STEPS).rgb * GetInverseCurrentExposureMultiplier();
}
IndirectLighting UtsEvaluateBSDF_MatCapSpecular(float3 positionWS, UtsBSDFData bsdfData, PreLightData preLightData)
{
IndirectLighting lighting;
ZERO_INITIALIZE(IndirectLighting, lighting);
float3 positionVS = mul(UNITY_MATRIX_V, float4(positionWS, 1.0)).xyz;
float3 normalVS = mul(UNITY_MATRIX_V, float4(bsdfData.normalWS, 1.0)).xyz;
float3 PcrossN = cross(normalize(positionVS), normalVS);
float2 uv = PcrossN.yx;
uv.x *= -1;
uv = uv * 0.5 + 0.5;
lighting.specularReflected = SAMPLE_TEXTURE2D_LOD(_MatCapMap, s_linear_clamp_sampler, uv, PerceptualRoughnessToMipmapLevel(bsdfData.perceptualRoughness)).rgb;
lighting.specularReflected *= preLightData.specularFGD * GetInverseCurrentExposureMultiplier();
return lighting;
}
void UtsEvaluateBSDF_Ramp(PositionInputs posInput, UtsBSDFData bsdfData, float3 L, inout BuiltinData builtinData)
{
// TODO
}
IndirectLighting UtsEvaluateBSDF_Env(LightLoopContext lightLoopContext, PositionInputs posInput, PreLightData preLightData, EnvLightData lightData, UtsBSDFData bsdfData, int influenceShapeType, int GPUImageBasedLightingType, inout float hierarchyWeight)
{
IndirectLighting lighting;
ZERO_INITIALIZE(IndirectLighting, lighting);
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
{
return lighting;
}
float3 envLighting;
float3 positionWS = posInput.positionWS;
float weight = 1.0;
float3 R = preLightData.iblR;
if (!IsEnvIndexTexture2D(lightData.envIndex)) // ENVCACHETYPE_CUBEMAP
{
R = GetSpecularDominantDir(bsdfData.normalWS, R, preLightData.iblPerceptualRoughness, ClampNdotV(preLightData.NdotV));
// When we are rough, we tend to see outward shifting of the reflection when at the boundary of the projection volume
// Also it appear like more sharp. To avoid these artifact and at the same time get better match to reference we lerp to original unmodified reflection.
// Formula is empirical.
float roughness = PerceptualRoughnessToRoughness(preLightData.iblPerceptualRoughness);
R = lerp(R, preLightData.iblR, saturate(smoothstep(0, 1, roughness * roughness)));
}
// Note: using influenceShapeType and projectionShapeType instead of (lightData|proxyData).shapeType allow to make compiler optimization in case the type is know (like for sky)
float intersectionDistance = EvaluateLight_EnvIntersection(positionWS, bsdfData.normalWS, lightData, influenceShapeType, R, weight);
float3 F = preLightData.specularFGD;
float4 preLD = SampleEnvWithDistanceBaseRoughness(lightLoopContext, posInput, lightData, R, preLightData.iblPerceptualRoughness, intersectionDistance);
weight *= preLD.a; // Used by planar reflection to discard pixel
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION)
{
envLighting = F * preLD.rgb;
// Apply the main lobe weight and update main reflection hierarchyWeight:
UpdateLightingHierarchyWeights(hierarchyWeight, weight);
envLighting *= weight;
}
envLighting *= lightData.multiplier;
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION)
{
lighting.specularReflected = envLighting;
}
return lighting;
}
void UtsPostEvaluateBSDF(PositionInputs posInput, PreLightData preLightData, UtsBSDFData bsdfData, BuiltinData builtinData, AggregateLighting lighting, out LightLoopOutput lightLoopOutput)
{
AmbientOcclusionFactor aoFactor;
GetScreenSpaceAmbientOcclusionMultibounce(posInput.positionSS, preLightData.NdotV, bsdfData.perceptualRoughness, bsdfData.ambientOcclusion, bsdfData.specularOcclusion, bsdfData.diffuseColor, bsdfData.fresnel0, aoFactor);
builtinData.bakeDiffuseLighting = APPLY_WEIGHT(builtinData.bakeDiffuseLighting, aoFactor.indirectAmbientOcclusion, _AO_Factor);
lighting.indirect.specularReflected = APPLY_WEIGHT(lighting.indirect.specularReflected, aoFactor.indirectSpecularOcclusion, _AO_Factor);
lighting.direct.diffuse = APPLY_WEIGHT(lighting.direct.diffuse, aoFactor.directAmbientOcclusion, _AO_Factor);
lighting.direct.specular = APPLY_WEIGHT(lighting.direct.specular, aoFactor.directSpecularOcclusion, _AO_Factor);
builtinData.bakeDiffuseLighting = ApplyCurrentExposureMultiplier(builtinData.bakeDiffuseLighting * bsdfData.diffuseColor * preLightData.diffuseFGD * _ID_Intensity);
lighting.indirect.specularReflected = ApplyCurrentExposureMultiplier(lighting.indirect.specularReflected * bsdfData.fresnel0 * _IR_Intensity);
lightLoopOutput.diffuseLighting = lighting.direct.diffuse + builtinData.bakeDiffuseLighting;
lightLoopOutput.specularLighting = lighting.direct.specular + lighting.indirect.specularReflected;
// Rescale the GGX to account for the multiple scattering.
lightLoopOutput.specularLighting *= 1.0 + bsdfData.fresnel0 * preLightData.energyCompensation;
ApplyExposureAdjustment(lightLoopOutput.diffuseLighting);
ApplyExposureAdjustment(lightLoopOutput.specularLighting);
lightLoopOutput.diffuseLighting += builtinData.emissiveColor;
}
#endif

View File

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

View File

@@ -0,0 +1,474 @@
//Unity Toon Shader/HDRP
//nobuyuki@unity3d.com
//toshiyuki@unity3d.com (Universal RP/HDRP)
#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/Common/UtsMaterialEvaluation.hlsl"
#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Lighting/UtsLightEvaluation.hlsl"
// Channel mask enum.
// this must be same to UI cs code
// HDRPToonGUI._ChannelEnum
int eBaseColor = 0;
int eFirstShade = 1;
int eSecondShade = 2;
int eHighlight = 3;
int eAngelRing = 4;
int eRimLight = 5;
int eOutline = 6;
int GetNextDirectionalLightIndex(BuiltinData builtinData, int currentIndex, int mainLightIndex)
{
int i = 0; // Declare once to avoid the D3D11 compiler warning.
for (i = 0; i < (int)_DirectionalLightCount; ++i)
{
if (IsMatchingLightLayer(_DirectionalLightDatas[i].lightLayers, builtinData.renderingLayers))
{
if (mainLightIndex != i)
{
if (currentIndex < i)
{
return i;
}
}
}
}
return -1; // not found
}
int GetUtsMainLightIndex(BuiltinData builtinData)
{
int mainLightIndex = -1;
float3 lightColor = float3(0.0f, 0.0f, 0.0f);
float lightAttenuation = 0.0f;
uint i = 0; // Declare once to avoid the D3D11 compiler warning.
for (i = 0; i < _DirectionalLightCount; ++i)
{
if (IsMatchingLightLayer(_DirectionalLightDatas[i].lightLayers, builtinData.renderingLayers))
{
float3 currentLightColor = _DirectionalLightDatas[i].color;
float currentLightAttenuation = GetColorAttenuation(currentLightColor);
if (mainLightIndex == -1 || (currentLightAttenuation > lightAttenuation))
{
mainLightIndex = i;
lightAttenuation = currentLightAttenuation;
lightColor = currentLightColor;
}
}
}
return mainLightIndex;
}
bool UtsUseScreenSpaceShadow(DirectionalLightData light, float3 normalWS)
{
#if defined(RAY_TRACED_SCREEN_SPACE_SHADOW_FLAG)
// Two different options are possible here
// - We have a ray trace shadow in which case we have no valid signal for a transmission and we need to fallback on the rasterized shadow
// - We have a screen space shadow and it already contains the transmission shadow and we can use it straight away
bool visibleLight = 0.5 * dot(normalWS, -light.forward) + 0.5 > 0.0;
bool validScreenSpaceShadow = (light.screenSpaceShadowIndex & SCREEN_SPACE_SHADOW_INDEX_MASK) != INVALID_SCREEN_SPACE_SHADOW;
bool rayTracedShadow = (light.screenSpaceShadowIndex & RAY_TRACED_SCREEN_SPACE_SHADOW_FLAG) != 0.0;
return (validScreenSpaceShadow && ((rayTracedShadow && visibleLight) || !rayTracedShadow));
#else
return ( (light.screenSpaceShadowIndex & SCREEN_SPACE_SHADOW_INDEX_MASK) != INVALID_SCREEN_SPACE_SHADOW);
#endif
}
void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bsdfData, BuiltinData builtinData,
float3 V, uint featureFlags, out LightLoopOutput lightLoopOutput)
{
LightLoopContext context;
context.shadowContext = InitShadowContext();
context.shadowValue = 1;
context.sampleReflection = 0;
#ifdef APPLY_FOG_ON_SKY_REFLECTIONS
context.positionWS = posInput.positionWS;
#endif
// Initialize the contactShadow and contactShadowFade fields
InitContactShadow(posInput, context);
// First of all we compute the shadow value of the directional light to reduce the VGPR pressure
if (featureFlags & LIGHTFEATUREFLAGS_DIRECTIONAL)
{
// Evaluate sun shadows.
if (_DirectionalShadowIndex >= 0)
{
DirectionalLightData light = _DirectionalLightDatas[_DirectionalShadowIndex];
#if defined(SCREEN_SPACE_SHADOWS_ON) && !defined(_SURFACE_TYPE_TRANSPARENT)
if (UseScreenSpaceShadow(light, bsdfData.normalWS))
{
context.shadowValue = GetScreenSpaceColorShadow(posInput, light.screenSpaceShadowIndex).SHADOW_TYPE_SWIZZLE;
}
else
#endif
{
float3 L = -light.forward;
// Is it worth sampling the shadow map?
if ((light.lightDimmer > 0) && (light.shadowDimmer > 0) && // Note: Volumetric can have different dimmer, thus why we test it here
dot(bsdfData.normalWS, L) > 0.0)
{
context.shadowValue = GetDirectionalShadowAttenuation(context.shadowContext,
posInput.positionSS, posInput.positionWS + L * _ShadowBias, bsdfData.normalWS,
light.shadowIndex, L);
}
}
}
}
PreLightData preLightData = GetPreLightData_UTS(V, posInput, bsdfData);
AggregateLighting aggregateLighting;
ZERO_INITIALIZE(AggregateLighting, aggregateLighting);
// Evaluate the punctual lights.
if (featureFlags & LIGHTFEATUREFLAGS_PUNCTUAL)
{
uint lightCount, lightStart;
#ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
GetCountAndStart(posInput, LIGHTCATEGORY_PUNCTUAL, lightStart, lightCount);
#else // LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
lightCount = _PunctualLightCount;
lightStart = 0;
#endif
bool fastPath = false;
#if SCALARIZE_LIGHT_LOOP
uint lightStartLane0;
fastPath = IsFastPath(lightStart, lightStartLane0);
if (fastPath)
{
lightStart = lightStartLane0;
}
#endif
// Scalarized loop. All lights that are in a tile/cluster touched by any pixel in the wave are loaded (scalar load), only the one relevant to current thread/pixel are processed.
// For clarity, the following code will follow the convention: variables starting with s_ are meant to be wave uniform (meant for scalar register),
// v_ are variables that might have different value for each thread in the wave (meant for vector registers).
// This will perform more loads than it is supposed to, however, the benefits should offset the downside, especially given that light data accessed should be largely coherent.
// Note that the above is valid only if wave intriniscs are supported.
uint v_lightListOffset = 0;
uint v_lightIdx = lightStart;
[loop] // vulkan shader compiler can not unroll.
#if NEED_TO_CHECK_HELPER_LANE
// On some platform helper lanes don't behave as we'd expect, therefore we prevent them from entering the loop altogether.
// IMPORTANT! This has implications if ddx/ddy is used on results derived from lighting, however given Lightloop is called in compute we should be
// sure it will not happen.
bool isHelperLane = WaveIsHelperLane();
while (!isHelperLane && v_lightListOffset < lightCount)
#else
while (v_lightListOffset < lightCount)
#endif
{
v_lightIdx = FetchIndex(lightStart, v_lightListOffset);
#if SCALARIZE_LIGHT_LOOP
uint s_lightIdx = ScalarizeElementIndex(v_lightIdx, fastPath);
#else
uint s_lightIdx = v_lightIdx;
#endif
if (s_lightIdx == -1)
{
break;
}
LightData s_lightData = FetchLight(s_lightIdx);
// If current scalar and vector light index match, we process the light. The v_lightListOffset for current thread is increased.
// Note that the following should really be ==, however, since helper lanes are not considered by WaveActiveMin, such helper lanes could
// end up with a unique v_lightIdx value that is smaller than s_lightIdx hence being stuck in a loop. All the active lanes will not have this problem.
if (s_lightIdx >= v_lightIdx)
{
v_lightListOffset++;
if (IsMatchingLightLayer(s_lightData.lightLayers, builtinData.renderingLayers))
{
DirectLighting lighting = UtsEvaluateBSDF_Punctual(context, posInput, builtinData, s_lightData, bsdfData, preLightData, V, fragInputs.texCoord0.xy);
AccumulateDirectLighting(lighting, aggregateLighting);
}
}
}
}
// Evaluate the directional lights.
if (featureFlags & LIGHTFEATUREFLAGS_DIRECTIONAL)
{
uint i = 0; // Declare once to avoid the D3D11 compiler warning.
for (i = 0; i < _DirectionalLightCount; ++i)
{
if (IsMatchingLightLayer(_DirectionalLightDatas[i].lightLayers, builtinData.renderingLayers))
{
DirectLighting direct = UtsEvaluateBSDF_Directional(context, posInput, builtinData, _DirectionalLightDatas[i], bsdfData, preLightData, V, fragInputs.texCoord0.xy);
AccumulateDirectLighting(direct, aggregateLighting);
}
}
}
// Evaluate the environment lights.
if (featureFlags & (LIGHTFEATUREFLAGS_ENV | LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_SSREFRACTION | LIGHTFEATUREFLAGS_SSREFLECTION))
{
float reflectionHierarchyWeight = 0.0; // Max: 1.0
uint envLightStart, envLightCount;
// Fetch first env light to provide the scene proxy for screen space computation
#ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
GetCountAndStart(posInput, LIGHTCATEGORY_ENV, envLightStart, envLightCount);
#else
envLightCount = _EnvLightCount;
envLightStart = 0;
#endif
bool fastPath = false;
#if SCALARIZE_LIGHT_LOOP
uint envStartFirstLane;
fastPath = IsFastPath(envLightStart, envStartFirstLane);
#endif
// Reflection hierarchy is
// 1. Screen Space Reflection
// 2. Environment Reflection
// 3. Sky Reflection
// Apply SSR.
#if (defined(_SURFACE_TYPE_TRANSPARENT) && !defined(_DISABLE_SSR_TRANSPARENT)) || (!defined(_SURFACE_TYPE_TRANSPARENT) && !defined(_DISABLE_SSR))
{
IndirectLighting lighting = UtsEvaluateBSDF_ScreenSpaceReflection(posInput, preLightData, reflectionHierarchyWeight);
AccumulateIndirectLighting(lighting, aggregateLighting);
}
#endif
float3 lightInReflDir = 0.0;
#ifdef _INDIRECT_DIFFUSE_OFF
#elif _INDIRECT_DIFFUSE_IBL
bool replaceBakeDiffuseLighting = false;
#if !defined(_SURFACE_TYPE_TRANSPARENT) // No SSGI/RTGI/Mixed effect on transparent
if (_IndirectDiffuseMode != INDIRECTDIFFUSEMODE_OFF)
{
replaceBakeDiffuseLighting = true;
}
#endif
#if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)
if (!builtinData.isLightmap)
{
replaceBakeDiffuseLighting = true;
}
#endif
#if defined(LIGHT_EVALUATION_SKIP_INDIRECT_DIFFUSE)
replaceBakeDiffuseLighting = false;
#endif
if (replaceBakeDiffuseLighting)
{
UtsEvaluateBSDF_BakeDiffuse(posInput, preLightData, bsdfData, V, builtinData, lightInReflDir);
}
#elif _INDIRECT_DIFFUSE_MATCAP
//builtinData.bakeDiffuseLighting = UtsEvaluateColor_MatCap(posInput.positionWS, bsdfData.normalWS, 0.0);
UtsEvaluateBSDF_MatCapDiffuse(posInput.positionWS, bsdfData.normalWS, builtinData);
#elif _INDIRECT_DIFFUSE_RAMP
UtsEvaluateBSDF_Ramp(posInput, bsdfData, builtinData);
#endif
if (featureFlags & LIGHTFEATUREFLAGS_ENV)
{
#if _INDIRECT_SPECULAR_OFF
#elif _INDIRECT_SPECULAR_IBL
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
#if SCALARIZE_LIGHT_LOOP
if (fastPath)
{
envLightStart = envStartFirstLane;
}
#endif
// Scalarized loop, same rationale of the punctual light version
uint v_envLightListOffset = 0;
uint v_envLightIdx = envLightStart;
#if NEED_TO_CHECK_HELPER_LANE
// On some platform helper lanes don't behave as we'd expect, therefore we prevent them from entering the loop altogether.
// IMPORTANT! This has implications if ddx/ddy is used on results derived from lighting, however given Lightloop is called in compute we should be
// sure it will not happen.
bool isHelperLane = WaveIsHelperLane();
while (!isHelperLane && v_envLightListOffset < envLightCount)
#else
while (v_envLightListOffset < envLightCount)
#endif
{
v_envLightIdx = FetchIndex(envLightStart, v_envLightListOffset);
#if SCALARIZE_LIGHT_LOOP
uint s_envLightIdx = ScalarizeElementIndex(v_envLightIdx, fastPath);
#else
uint s_envLightIdx = v_envLightIdx;
#endif
if (s_envLightIdx == -1)
{
break;
}
EnvLightData s_envLightData = FetchEnvLight(s_envLightIdx);
// If current scalar and vector light index match, we process the light. The v_envLightListOffset for current thread is increased.
// Note that the following should really be ==, however, since helper lanes are not considered by WaveActiveMin, such helper lanes could
// end up with a unique v_envLightIdx value that is smaller than s_envLightIdx hence being stuck in a loop. All the active lanes will not have this problem.
if (s_envLightIdx >= v_envLightIdx)
{
v_envLightListOffset++;
if (reflectionHierarchyWeight < 1.0)
{
if (IsMatchingLightLayer(s_envLightData.lightLayers, builtinData.renderingLayers))
{
IndirectLighting lighting = UtsEvaluateBSDF_Env(context, posInput, preLightData, s_envLightData, bsdfData, s_envLightData.influenceShapeType, GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION, reflectionHierarchyWeight);
#if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)
if (s_envLightData.normalizeWithAPV > 0 && all(lightInReflDir >= 0))
{
float factor = GetReflectionProbeNormalizationFactor(lightInReflDir, bsdfData.normalWS, s_envLightData.L0L1, s_envLightData.L2_1, s_envLightData.L2_2);
lighting.specularReflected *= factor;
}
#endif
AccumulateIndirectLighting(lighting, aggregateLighting);
}
}
}
}
#elif _INDIRECT_SPECULAR_MATCAP
IndirectLighting lighting = UtsEvaluateBSDF_MatCapSpecular(posInput.positionWS, bsdfData, preLightData);
AccumulateIndirectLighting(lighting, aggregateLighting);
#endif
}
#if _INDIRECT_SPECULAR_IBL
// Only apply the sky IBL if the sky texture is available
if ((featureFlags & LIGHTFEATUREFLAGS_SKY) && _EnvLightSkyEnabled)
{
// The sky is a single cubemap texture separate from the reflection probe texture array (different resolution and compression)
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_SKY;
// The sky data are generated on the fly so the compiler can optimize the code
EnvLightData envLightSky = InitSkyEnvLightData(0);
// Only apply the sky if we haven't yet accumulated enough IBL lighting.
if (reflectionHierarchyWeight < 1.0)
{
IndirectLighting lighting = UtsEvaluateBSDF_Env(context, posInput, preLightData, envLightSky, bsdfData, envLightSky.influenceShapeType, GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION, reflectionHierarchyWeight);
AccumulateIndirectLighting(lighting, aggregateLighting);
}
}
#endif
}
UtsPostEvaluateBSDF(posInput, preLightData, bsdfData, builtinData, aggregateLighting, lightLoopOutput);
}
// UTSLightData GetUTSMainPunctualLightData(BuiltinData builtinData, PositionInputs posInput)
// {
// UTSLightData mainPunctualLight;
// uint lightCount, lightStart;
// #ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
// GetCountAndStart(posInput, LIGHTCATEGORY_PUNCTUAL, lightStart, lightCount);
// #else // LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
// lightCount = _PunctualLightCount;
// lightStart = 0;
// #endif
// bool fastPath = false;
// #if SCALARIZE_LIGHT_LOOP
// uint lightStartLane0;
// fastPath = IsFastPath(lightStart, lightStartLane0);
// if (fastPath)
// {
// lightStart = lightStartLane0;
// }
// #endif
// uint v_lightListOffset = 0;
// uint v_lightIdx = lightStart;
// float channelAlpha = 0.0f;
// [loop] // vulkan shader compiler can not unroll.
// while (v_lightListOffset < lightCount)
// {
// v_lightIdx = FetchIndex(lightStart, v_lightListOffset);
// #if SCALARIZE_LIGHT_LOOP
// uint s_lightIdx = ScalarizeElementIndex(v_lightIdx, fastPath);
// #else
// uint s_lightIdx = v_lightIdx;
// #endif
// if (s_lightIdx == -1)
// break;
// LightData s_lightData = FetchLight(s_lightIdx);
// // If current scalar and vector light index match, we process the light. The v_lightListOffset for current thread is increased.
// // Note that the following should really be ==, however, since helper lanes are not considered by WaveActiveMin, such helper lanes could
// // end up with a unique v_lightIdx value that is smaller than s_lightIdx hence being stuck in a loop. All the active lanes will not have this problem.
// if (s_lightIdx >= v_lightIdx)
// {
// v_lightListOffset++;
// if (IsMatchingLightLayer(s_lightData.lightLayers, builtinData.renderingLayers))
// {
// float3 lightDirection;
// 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;
// const float notDirectional = 1.0f;
// UTSLightData utsLightData;
// utsLightData.lightColor = additionalLightColor;
// utsLightData.lightDirection = lightDirection;
// utsLightData.diffuseDimmer = s_lightData.diffuseDimmer;
// utsLightData.specularDimmer = s_lightData.specularDimmer;
// utsLightData.shadowTint = s_lightData.shadowTint;
// utsLightData.penumbraTint = s_lightData.penumbraTint;
// if(length(additionalLightColor) >= length(mainPunctualLight.lightColor))
// {
// mainPunctualLight = utsLightData;
// }
// }
// }
// }
// return mainPunctualLight;
// }
// Todo: calculate the acutal main lighboth dorectional and punctual)t based on the light attenuation, rather than using the main directional light
UTSLightData GetCustomMainLightData(BuiltinData builtinData, UTSLightData mainPunctualLight)
{
UTSLightData utsLightData;
int mainLightIndex;
mainLightIndex = GetUtsMainLightIndex(builtinData);
if (mainLightIndex == -1 || length(_DirectionalLightDatas[mainLightIndex].color) < length(mainPunctualLight.lightColor))
{
utsLightData = mainPunctualLight;
}
else
{
utsLightData.lightColor = ApplyCurrentExposureMultiplier(_DirectionalLightDatas[mainLightIndex].color);
utsLightData.lightDirection = -_DirectionalLightDatas[mainLightIndex].forward;
utsLightData.diffuseDimmer = _DirectionalLightDatas[mainLightIndex].diffuseDimmer;
utsLightData.specularDimmer = _DirectionalLightDatas[mainLightIndex].specularDimmer;
utsLightData.shadowTint = _DirectionalLightDatas[mainLightIndex].shadowTint;
utsLightData.penumbraTint = _DirectionalLightDatas[mainLightIndex].penumbraTint;
}
return utsLightData;
}

View File

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

View File

@@ -0,0 +1,83 @@
//Unity Toon Shader/HDRP
//nobuyuki@unity3d.com
//toshiyuki@unity3d.com (Universal RP/HDRP)
#ifndef DirectionalShadowType
# if (SHADEROPTIONS_RAYTRACING && (defined(SHADER_API_D3D11) || defined(SHADER_API_D3D12)) && !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL))
# define DirectionalShadowType float3
# else
# define DirectionalShadowType float
# endif
#endif
float3 UTS_SelfShdowMainLight(LightLoopContext lightLoopContext, FragInputs input, int mainLightIndex)
{
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
// input.positionSS is SV_Position
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);
#ifdef VARYINGS_NEED_POSITION_WS
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
#else
// Unused
float3 V = float3(1.0, 1.0, 1.0); // Avoid the division by 0
#endif
SurfaceData surfaceData;
BuiltinData builtinData;
GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(input.positionSS.xy, surfaceData);
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);
/* todo. these should be put int a struct */
float4 Set_UV0 = input.texCoord0;
float3x3 tangentTransform = input.tangentToWorld;
//UnpackNormalmapRGorAG(SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, texCoords))
float4 n = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, Set_UV0.xy);
// float3 _NormalMap_var = UnpackNormalScale(tex2D(_NormalMap, TRANSFORM_TEX(Set_UV0, _NormalMap)), _BumpScale);
float3 _NormalMap_var = UnpackNormalScale(n, _BumpScale);
float3 normalLocal = _NormalMap_var.rgb;
float3 i_normalDir = surfaceData.normalWS;
/* to here todo. these should be put int a struct */
float shadowAttenuation = (float)lightLoopContext.shadowValue;
float3 mainLihgtDirection = -_DirectionalLightDatas[mainLightIndex].forward;
float3 mainLightColor = ApplyCurrentExposureMultiplier(_DirectionalLightDatas[mainLightIndex].color);
// float4 tmpColor = EvaluateLight_Directional(context, posInput, _DirectionalLightDatas[mainLightIndex]);
// float3 mainLightColor = tmpColor.xyz;
float3 defaultLightDirection = normalize(UNITY_MATRIX_V[2].xyz + UNITY_MATRIX_V[1].xyz);
float3 defaultLightColor = saturate(max(float3(0.05, 0.05, 0.05) * _Unlit_Intensity, max(ShadeSH9(float4(0.0, 0.0, 0.0, 1.0)), ShadeSH9(float4(0.0, -1.0, 0.0, 1.0)).rgb) * _Unlit_Intensity));
float3 customLightDirection = normalize(mul(UNITY_MATRIX_M, float4(((float3(1.0, 0.0, 0.0) * _Offset_X_Axis_BLD * 10) + (float3(0.0, 1.0, 0.0) * _Offset_Y_Axis_BLD * 10) + (float3(0.0, 0.0, -1.0) * lerp(-1.0, 1.0, _Inverse_Z_Axis_BLD))), 0)).xyz);
float3 lightDirection = normalize(lerp(defaultLightDirection, mainLihgtDirection.xyz, any(mainLihgtDirection.xyz)));
lightDirection = lerp(lightDirection, customLightDirection, _Is_BLD);
////// Lighting:
float _HalfLambert_var = 0.5 * dot(i_normalDir, lightDirection) + 0.5;
float lambert = dot(i_normalDir, lightDirection);
_HalfLambert_var = lambert;
float baseColorStep = 0.00001;
float Set_FinalShadowMask = saturate(1.0 + (-_HalfLambert_var) / (baseColorStep));
float3 Set_FinalBaseColor = 1 - Set_FinalShadowMask;
return Set_FinalBaseColor;
}

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0ca2f1317714a1f42aec9cf88eaef1c5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,366 @@
// ===========================================================================
// WARNING:
// On PS4, texture/sampler declarations need to be outside of CBuffers
// Otherwise those parameters are not bound correctly at runtime.
// ===========================================================================
#define fixed half
#define UNITY_TEXTURE_STREAMING_DEBUG_VARS
float4 unity_MipmapStreaming_DebugTex_ST;
float4 unity_MipmapStreaming_DebugTex_TexelSize;
float4 unity_MipmapStreaming_DebugTex_MipInfo;
float4 unity_MipmapStreaming_DebugTex_StreamInfo;
// Unity Toon Shader
#include "UtsTextures.hlsl"
// Lit
TEXTURE2D(_DistortionVectorMap);
SAMPLER(sampler_DistortionVectorMap);
TEXTURE2D(_EmissiveColorMap);
SAMPLER(sampler_EmissiveColorMap);
#ifndef LAYERED_LIT_SHADER
TEXTURE2D(_DiffuseLightingMap);
SAMPLER(sampler_DiffuseLightingMap);
TEXTURE2D(_BaseColorMap);
SAMPLER(sampler_BaseColorMap);
TEXTURE2D(_HairBlendingMap);
SAMPLER(sampler_HairBlendingMap);
TEXTURE2D(_MaskMap);
SAMPLER(sampler_MaskMap);
TEXTURE2D(_BentNormalMap); // Reuse sampler from normal map
SAMPLER(sampler_BentNormalMap);
TEXTURE2D(_NormalMap);
SAMPLER(sampler_NormalMap);
TEXTURE2D(_NormalMapOS);
SAMPLER(sampler_NormalMapOS);
TEXTURE2D(_DetailMap);
SAMPLER(sampler_DetailMap);
TEXTURE2D(_HeightMap);
SAMPLER(sampler_HeightMap);
TEXTURE2D(_TangentMap);
SAMPLER(sampler_TangentMap);
TEXTURE2D(_TangentMapOS);
SAMPLER(sampler_TangentMapOS);
TEXTURE2D(_AnisotropyMap);
SAMPLER(sampler_AnisotropyMap);
TEXTURE2D(_SubsurfaceMaskMap);
SAMPLER(sampler_SubsurfaceMaskMap);
TEXTURE2D(_ThicknessMap);
SAMPLER(sampler_ThicknessMap);
TEXTURE2D(_IridescenceThicknessMap);
SAMPLER(sampler_IridescenceThicknessMap);
TEXTURE2D(_IridescenceMaskMap);
SAMPLER(sampler_IridescenceMaskMap);
TEXTURE2D(_SpecularColorMap);
SAMPLER(sampler_SpecularColorMap);
TEXTURE2D(_TransmittanceColorMap);
SAMPLER(sampler_TransmittanceColorMap);
TEXTURE2D(_CoatMaskMap);
SAMPLER(sampler_CoatMaskMap);
TEXTURE2D(_SSSLutMap);
//SAMPLER(sampler_SSSLutMap); //Use s_linear_clamp_sampler instead
TEXTURE2D(_SDFShadowTex);
SAMPLER(sampler_SDFShadowTex);
TEXTURE2D(_HairShadowTex);
TEXTURE2D(_HairBlendingTex);
#else
// Set of users variables
#define PROP_DECL(type, name) type name##0, name##1, name##2, name##3
// sampler are share by texture type inside a layered material but we need to support that a particualr layer have no texture, so we take the first sampler of available texture as the share one
// mean we must declare all sampler
#define PROP_DECL_TEX2D(name)\
TEXTURE2D(CALL_MERGE_NAME(name, 0)); \
SAMPLER(CALL_MERGE_NAME(CALL_MERGE_NAME(sampler, name), 0)); \
TEXTURE2D(CALL_MERGE_NAME(name, 1)); \
SAMPLER(CALL_MERGE_NAME(CALL_MERGE_NAME(sampler, name), 1)); \
TEXTURE2D(CALL_MERGE_NAME(name, 2)); \
SAMPLER(CALL_MERGE_NAME(CALL_MERGE_NAME(sampler, name), 2)); \
TEXTURE2D(CALL_MERGE_NAME(name, 3)); \
SAMPLER(CALL_MERGE_NAME(CALL_MERGE_NAME(sampler, name), 3))
PROP_DECL_TEX2D(_BaseColorMap);
PROP_DECL_TEX2D(_MaskMap);
PROP_DECL_TEX2D(_BentNormalMap);
PROP_DECL_TEX2D(_NormalMap);
PROP_DECL_TEX2D(_NormalMapOS);
PROP_DECL_TEX2D(_DetailMap);
PROP_DECL_TEX2D(_HeightMap);
PROP_DECL_TEX2D(_SubsurfaceMaskMap);
PROP_DECL_TEX2D(_ThicknessMap);
TEXTURE2D(_LayerMaskMap);
SAMPLER(sampler_LayerMaskMap);
TEXTURE2D(_LayerInfluenceMaskMap);
SAMPLER(sampler_LayerInfluenceMaskMap);
#endif
CBUFFER_START(UnityPerMaterial)
#include "UtsUnityPerMaterial.hlsl"
// shared constant between lit and layered lit
float _AlphaCutoff;
float _UseShadowThreshold;
float _AlphaCutoffShadow;
float _AlphaCutoffPrepass;
float _AlphaCutoffPostpass;
float4 _DoubleSidedConstants;
float _DistortionScale;
float _DistortionVectorScale;
float _DistortionVectorBias;
float _DistortionBlurScale;
float _DistortionBlurRemapMin;
float _DistortionBlurRemapMax;
float _PPDMaxSamples;
float _PPDMinSamples;
float _PPDLodThreshold;
float3 _EmissiveColor;
float _AlbedoAffectEmissive;
float _EmissiveExposureWeight;
float _ObjectSpaceUVMappingEmissive;
int _SpecularOcclusionMode;
// Transparency
float3 _TransmittanceColor;
float _Ior;
float _ATDistance;
// Caution: C# code in BaseLitUI.cs call LightmapEmissionFlagsProperty() which assume that there is an existing "_EmissionColor"
// value that exist to identify if the GI emission need to be enabled.
// In our case we don't use such a mechanism but need to keep the code quiet. We declare the value and always enable it.
// TODO: Fix the code in legacy unity so we can customize the beahvior for GI
float3 _EmissionColor;
float4 _EmissiveColorMap_ST;
float _TexWorldScaleEmissive;
float4 _UVMappingMaskEmissive;
float _ID_Intensity;
float _IR_Intensity;
float4 _InvPrimScale; // Only XY are used
// Wind
float _InitialBend;
float _Stiffness;
float _Drag;
float _ShiverDrag;
float _ShiverDirectionality;
// Specular AA
float _EnableGeometricSpecularAA;
float _SpecularAAScreenSpaceVariance;
float _SpecularAAThreshold;
#ifndef LAYERED_LIT_SHADER
// Set of users variables
float4 _BaseColor;
float4 _BaseColorMap_ST;
float4 _BaseColorMap_TexelSize;
float4 _BaseColorMap_MipInfo;
float _Metallic;
float _MetallicRemapMin;
float _MetallicRemapMax;
float _Smoothness;
float _SmoothnessRemapMin;
float _SmoothnessRemapMax;
float _Roughness;
float _RoughnessRemapMin;
float _RoughnessRemapMax;
float _AlphaRemapMin;
float _AlphaRemapMax;
float _AORemapMin;
float _AORemapMax;
float _SSSIntensity;
int _Use_SSSLut;
float4 _SpecularColor;
float _ToonSpecularStep;
float _ToonSpecularFeather;
float _ReceivesSSR;
float _ReceivesSSAO;
float _AO_Factor;
float _ReceivesSSGI;
float _GIMultiplier;
float _NormalScale;
float4 _DetailMap_ST;
float _DetailAlbedoScale;
float _DetailNormalScale;
float _DetailSmoothnessScale;
float4 _HeightMap_TexelSize; // Unity facility. This will provide the size of the heightmap to the shader
float _HeightAmplitude;
float _HeightCenter;
float _Anisotropy;
float4 _AnisotropyMap_ST;
int _Use_Anisotropy;
float4 _KKColor;
float _BSDFContribution;
float _DiffusionProfileHash;
float _SubsurfaceMask;
float _TransmissionMask;
float _Thickness;
float4 _ThicknessRemap;
float _IridescenceThickness;
float4 _IridescenceThicknessRemap;
float _IridescenceMask;
float _CoatMask;
//float4 _SpecularColor;
float _EnergyConservingSpecularColor;
float _TexWorldScale;
float _InvTilingScale;
float4 _UVMappingMask;
float4 _UVDetailsMappingMask;
float _LinkDetailsWithBase;
float _ObjectSpaceUVMapping;
#else // LAYERED_LIT_SHADER
// Set of users variables
PROP_DECL(float4, _BaseColor);
float4 _BaseColorMap0_ST;
float4 _BaseColorMap1_ST;
float4 _BaseColorMap2_ST;
float4 _BaseColorMap3_ST;
float4 _BaseColorMap0_TexelSize;
float4 _BaseColorMap0_MipInfo;
PROP_DECL(float, _Metallic);
PROP_DECL(float, _MetallicRemapMin);
PROP_DECL(float, _MetallicRemapMax);
PROP_DECL(float, _Smoothness);
PROP_DECL(float, _SmoothnessRemapMin);
PROP_DECL(float, _SmoothnessRemapMax);
PROP_DECL(float, _AORemapMin);
PROP_DECL(float, _AORemapMax);
PROP_DECL(float, _NormalScale);
float4 _NormalMap0_TexelSize; // Unity facility. This will provide the size of the base normal to the shader
float4 _HeightMap0_TexelSize;
float4 _HeightMap1_TexelSize;
float4 _HeightMap2_TexelSize;
float4 _HeightMap3_TexelSize;
float4 _DetailMap0_ST;
float4 _DetailMap1_ST;
float4 _DetailMap2_ST;
float4 _DetailMap3_ST;
PROP_DECL(float, _UVDetail);
PROP_DECL(float, _DetailAlbedoScale);
PROP_DECL(float, _DetailNormalScale);
PROP_DECL(float, _DetailSmoothnessScale);
PROP_DECL(float, _HeightAmplitude);
PROP_DECL(float, _HeightCenter);
PROP_DECL(float, _DiffusionProfileHash);
PROP_DECL(float, _SubsurfaceMask);
PROP_DECL(float, _Thickness);
PROP_DECL(float4, _ThicknessRemap);
PROP_DECL(float, _OpacityAsDensity);
float _InheritBaseNormal1;
float _InheritBaseNormal2;
float _InheritBaseNormal3;
float _InheritBaseHeight1;
float _InheritBaseHeight2;
float _InheritBaseHeight3;
float _InheritBaseColor1;
float _InheritBaseColor2;
float _InheritBaseColor3;
PROP_DECL(float, _HeightOffset);
float _HeightTransition;
float4 _LayerMaskMap_ST;
float _TexWorldScaleBlendMask;
PROP_DECL(float, _TexWorldScale);
PROP_DECL(float, _InvTilingScale);
float4 _UVMappingMaskBlendMask;
PROP_DECL(float4, _UVMappingMask);
PROP_DECL(float4, _UVDetailsMappingMask);
PROP_DECL(float, _LinkDetailsWithBase);
#endif // LAYERED_LIT_SHADER
// Tessellation specific
#ifdef TESSELLATION_ON
float _TessellationFactor;
float _TessellationFactorMinDistance;
float _TessellationFactorMaxDistance;
float _TessellationFactorTriangleSize;
float _TessellationShapeFactor;
float _TessellationBackFaceCullEpsilon;
float _TessellationObjectScale;
float _TessellationTilingScale;
#endif
// Following two variables are feeded by the C++ Editor for Scene selection
int _ObjectId;
int _PassValue;
CBUFFER_END
int _ToonLightHiCutFilter;
int _ToonEvAdjustmentCurve;
float _ToonEvAdjustmentValueArray[128];
float _ToonEvAdjustmentValueMin;
float _ToonEvAdjustmentValueMax;
float _ToonEvAdjustmentCompensation;
float _ToonIgnoreExposureMultiplier;
float _Outline_MaxWidth;
float4 _HairShadowRTHandleScale;
float4 _HairBlendingRTHandleScale;
float _HairShadowDistance;
float _HairShadowDistanceScaleFactor;
float _HairShadowDepthBias;
float _HairShadowFadeInDistance;
float _HairShadowFadeOutDistance;

View File

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

View File

@@ -0,0 +1,20 @@
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
TEXTURE2D(_1st_ShadeMap);
TEXTURE2D(_2nd_ShadeMap);
TEXTURE2D(_MatCapMap);
sampler _Set_1st_ShadePosition;
sampler _Set_2nd_ShadePosition;
sampler _ShadingGradeMap;
sampler _HighColor_Tex;
sampler _Set_HighColorMask;
sampler _Set_RimLightMask;
sampler _NormalMapForMatCap;
sampler _Set_MatcapMask;
// sampler2D _ClippingMask;
TEXTURE2D(_ClippingMask);
sampler _AngelRing_Sampler;
sampler _Outline_Sampler;
sampler _OutlineTex;
sampler _BakedNormal;

View File

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

View File

@@ -0,0 +1,205 @@
// cosntant in Unity Toon Shader
float _utsTechnique;
float4 _Color;
fixed _Use_BaseAs1st;
fixed _Use_1stAs2nd;
fixed _Is_LightColor_Base;
float4 _MainTex_ST;
float4 _1st_ShadeMap_ST;
float4 _1st_ShadeColor;
fixed _Is_LightColor_1st_Shade;
float4 _2nd_ShadeMap_ST;
float4 _2nd_ShadeColor;
fixed _Is_LightColor_2nd_Shade;
fixed _Is_NormalMapToBase;
fixed _Set_SystemShadowsToBase;
float _Tweak_SystemShadowsLevel;
float _ShadowBias;
float _SDFShadowLevel;
float _SDFSmoothGamma;
float _SDFNoseHighlightCoef;
float _SDFNoseHighlightSmoothRange;
float _EyeParallaxAmount;
float _HairBlendingFactor;
float _BaseColor_Step;
float _BaseShade_Feather;
float4 _Set_1st_ShadePosition_ST;
float _ShadeColor_Step;
float _1st2nd_Shades_Feather;
float4 _Set_2nd_ShadePosition_ST;
float4 _ShadingGradeMap_ST;
float _Tweak_ShadingGradeMapLevel;
fixed _BlurLevelSGM;
//
float _1st_ShadeColor_Step;
float _1st_ShadeColor_Feather;
float _2nd_ShadeColor_Step;
float _2nd_ShadeColor_Feather;
float4 _HighColor;
float4 _HighColor_Tex_ST;
fixed _Is_LightColor_HighColor;
fixed _Is_NormalMapToHighColor;
float _HighColor_Power;
fixed _Is_SpecularToHighColor;
fixed _Is_BlendAddToHiColor;
fixed _Is_BlendAddToRimColor;
fixed _Is_UseTweakHighColorOnShadow;
float _TweakHighColorOnShadow;
float4 _Set_HighColorMask_ST;
float _Tweak_HighColorMaskLevel;
fixed _RimLight;
float4 _RimLightColor;
float _RimLight_Strength;
fixed _Is_LightColor_RimLight;
fixed _Is_NormalMapToRimLight;
float _RimLight_Power;
float _RimLight_InsideMask;
fixed _RimLight_FeatherOff;
fixed _LightDirection_MaskOn;
float _Tweak_LightDirection_MaskLevel;
fixed _Add_Antipodean_RimLight;
float4 _Ap_RimLightColor;
fixed _Is_LightColor_Ap_RimLight;
float _Ap_RimLight_Power;
fixed _Ap_RimLight_FeatherOff;
float4 _Set_RimLightMask_ST;
float _Tweak_RimLightMaskLevel;
fixed _MatCap;
float4 _MatCap_Sampler_ST;
float4 _MatCapColor;
fixed _Is_LightColor_MatCap;
fixed _Is_BlendAddToMatCap;
float _Tweak_MatCapUV;
float _Rotate_MatCapUV;
fixed _Is_NormalMapForMatCap;
float4 _NormalMapForMatCap_ST;
float _Rotate_NormalMapForMatCapUV;
fixed _Is_UseTweakMatCapOnShadow;
float _TweakMatCapOnShadow;
float4 _Set_MatcapMask_ST;
float _Tweak_MatcapMaskLevel;
fixed _Is_Ortho;
float _CameraRolling_Stabilizer;
fixed _BlurLevelMatcap;
fixed _Inverse_MatcapMask;
float _BumpScale;
float _BumpScaleMatcap;
float4 _Emissive_Tex_ST;
float4 _Emissive_Color;
fixed _Is_ViewCoord_Scroll;
float _Rotate_EmissiveUV;
float _Base_Speed;
float _Scroll_EmissiveU;
float _Scroll_EmissiveV;
fixed _Is_PingPong_Base;
float4 _ColorShift;
float4 _ViewShift;
float _ColorShift_Speed;
fixed _Is_ColorShift;
fixed _Is_ViewShift;
float3 emissive;
//
float _Unlit_Intensity;
fixed _Is_Filter_HiCutPointLightColor;
fixed _Is_Filter_LightColor;
float _StepOffset;
fixed _Is_BLD;
float _Offset_X_Axis_BLD;
float _Offset_Y_Axis_BLD;
fixed _Inverse_Z_Axis_BLD;
float4 _ClippingMask_ST;
fixed _IsBaseMapAlphaAsClippingMask;
float _Clipping_Level;
fixed _Inverse_Clipping;
float _Tweak_transparency;
fixed _AngelRing;
float4 _AngelRing_Sampler_ST;
float _BaseColorVisible;
float _BaseColorOverridden;
float4 _BaseColorMaskColor;
float _FirstShadeVisible;
float _FirstShadeOverridden;
float4 _FirstShadeMaskColor;
float _SecondShadeVisible;
float _SecondShadeOverridden;
float4 _SecondShadeMaskColor;
float _HighlightVisible;
float _HighlightOverridden;
float4 _HighlightMaskColor;
float _AngelRingVisible;
float _AngelRingOverridden;
float4 _AngelRingMaskColor;
float _RimLightVisible;
float _RimLightOverridden;
float4 _RimLightMaskColor;
float _OutlineVisible;
float _OutlineOverridden;
float4 _OutlineMaskColor;
float _ComposerMaskMode;
int _ClippingMatteMode;
float _GI_Intensity;
float _Light_Intensity_Multiplier;
float4 _AngelRing_Color;
fixed _Is_LightColor_AR;
float _AR_Intensity;
float _AR_ShadowIntensity;
float _AR_OffsetU;
float _AR_OffsetV;
fixed _ARSampler_AlphaOn;
// Unity Toon Shader Outline
float _Outline_Width;
float _Farthest_Distance;
float _Nearest_Distance;
float4 _Outline_Sampler_ST;
float4 _Outline_Color;
fixed _Is_BlendBaseColor;
float _Offset_Z;
float4 _OutlineTex_ST;
fixed _Is_OutlineTex;
float4 _BakedNormal_ST;
fixed _Is_BakedNormal;
fixed _UseSmoothedNormal;
float _ZOverDrawMode;
//
#if defined(_UTS_TOON_EV_PER_MODEL)
// not in materials
int _ToonLightHiCutFilter;
int _ToonEvAdjustmentCurve;
float _ToonEvAdjustmentValueArray[128];
float _ToonEvAdjustmentValueMin;
float _ToonEvAdjustmentValueMax;
float _ToonEvAdjustmentCompensation;
#endif //#if !defined(_UTS_TOON_EV_PER_MODEL)
float _BlendMode;
float3 _ObjectCenterPositionWS;

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 020b85c83fd4ee540af1f62afb131d15
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,127 @@
#undef unity_ObjectToWorld
#undef unity_WorldToObject
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/MotionVectorVertexShaderCommon.hlsl"
// PackedVaryingsType
// https://github.com/Unity-Technologies/Graphics/blob/e4117c07b479adafed38237f3407a363eefb4590/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl#L120
PackedVaryingsType Vert(AttributesMesh inputMesh, AttributesPass inputPass)
{
// VaryingsType
// https://github.com/Unity-Technologies/Graphics/blob/e4117c07b479adafed38237f3407a363eefb4590/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl#L118
VaryingsType varyingsType;
varyingsType.vmesh = VertMesh(inputMesh);
return MotionVectorVS(varyingsType, inputMesh, inputPass);
}
#else // _WRITE_TRANSPARENT_MOTION_VECTOR
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl"
PackedVaryingsType Vert(AttributesMesh inputMesh)
{
VaryingsType varyingsType;
varyingsType.vmesh = VertMesh(inputMesh);
return PackVaryingsType(varyingsType);
}
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
#ifdef UNITY_VIRTUAL_TEXTURING
#define VT_BUFFER_TARGET SV_Target1
#define EXTRA_BUFFER_TARGET SV_Target2
#else
#define EXTRA_BUFFER_TARGET SV_Target1
#endif
void Frag(PackedVaryingsToPS packedInput,
#ifdef OUTPUT_SPLIT_LIGHTING
out float4 outColor : SV_Target0, // outSpecularLighting
#ifdef UNITY_VIRTUAL_TEXTURING
out float4 outVTFeedback : VT_BUFFER_TARGET,
#endif
out float4 outDiffuseLighting : EXTRA_BUFFER_TARGET,
OUTPUT_SSSBUFFER(outSSSBuffer)
#else
out float4 outColor : SV_Target0
#ifdef UNITY_VIRTUAL_TEXTURING
, out float4 outVTFeedback : VT_BUFFER_TARGET
#endif
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
, out float4 outMotionVec : EXTRA_BUFFER_TARGET
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
#endif // OUTPUT_SPLIT_LIGHTING
#ifdef _DEPTHOFFSET_ON
, out float outputDepth : SV_Depth
#endif
)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput);
FragInputs input = UnpackVaryingsMeshToFragInputs(packedInput.vmesh);
#ifdef _IS_CLIPPING_MASK
if (_ClippingMaskMode != 0)
{
discard;
}
#endif
#ifdef _IS_CLIPPING_MATTE
if (_ClippingMatteMode != 0)
{
discard;
}
#endif // _IS_CLIPPING_MATTE
#if defined(UTS_DEBUG_SHADOWMAP_NO_OUTLINE)
discard;
#endif
//v.2.0.5
if (_ZOverDrawMode > 0.99f)
{
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.deviceDepth;
#endif
#ifdef UNITY_VIRTUAL_TEXTURING
outVTFeedback = builtinData.vtPackedFeedback;
#endif
outColor = float4(1.0f, 1.0f, 1.0f, 1.0f); // but nothing should be drawn except Z value as colormask is set to 0
return;
}
_Color = _BaseColor;
float4 objPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1));
float4 Set_UV0 = input.texCoord0;
// The following temporary definition of unity_AmbientEquator is for HDRP only.
//float4 unity_AmbientEquator = float4(0.05, 0.05, 0.05, 1.0); //Todo.
//v.2.0.9
//float3 envLightSource_GradientEquator = unity_AmbientEquator.rgb > 0.05 ? unity_AmbientEquator.rgb : half3(0.05, 0.05, 0.05);
float3 envLightSource_GradientEquator = ShadeSH9(float4(0, 1, 0, 0));
float3 envLightSource_SkyboxIntensity = max(
SampleBakedGI_UTS_OutLine(objPos.xyz, float3(0.0, 0.0, 0.0), input.texCoord1.xy, input.texCoord2.xy),
SampleBakedGI_UTS_OutLine(objPos.xyz, float3(0.0, -1.0, 0.0), input.texCoord1.xy, input.texCoord2.xy)
).rgb;
float3 ambientSkyColor = envLightSource_SkyboxIntensity.rgb > 0.0 ? envLightSource_SkyboxIntensity : envLightSource_GradientEquator;
ambientSkyColor *= GetCurrentExposureMultiplier();
float4 _BlendingTex_var = SAMPLE_TEXTURE2D(_HairBlendingMap, sampler_HairBlendingMap, TRANSFORM_TEX(Set_UV0, _MainTex));
outColor = float4(_BlendingTex_var.rgb * ambientSkyColor, _BlendingTex_var.a);
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.deviceDepth;
#endif
#ifdef UNITY_VIRTUAL_TEXTURING
outVTFeedback = builtinData.vtPackedFeedback;
#endif
}
// End of File

View File

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

View File

@@ -0,0 +1,224 @@
//Unity Toon Shader/HDRP
//nobuyuki@unity3d.com
//toshiyuki@unity3d.com (Universal RP/HDRP)
#undef unity_ObjectToWorld
#undef unity_WorldToObject
float4 _LightColor0; // not referenced in c# code ??
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/MotionVectorVertexShaderCommon.hlsl"
// PackedVaryingsType
// https://github.com/Unity-Technologies/Graphics/blob/e4117c07b479adafed38237f3407a363eefb4590/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl#L120
PackedVaryingsType Vert(AttributesMesh inputMesh, AttributesPass inputPass)
{
// VaryingsType
// https://github.com/Unity-Technologies/Graphics/blob/e4117c07b479adafed38237f3407a363eefb4590/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl#L118
VaryingsType varyingsType;
varyingsType.vmesh = VertMesh(inputMesh);
varyingsType.vmesh.
#include "HDRPToonOutlineVertMain.hlsl"
return MotionVectorVS(varyingsType, inputMesh, inputPass);
}
#ifdef TESSELLATION_ON
PackedVaryingsToPS VertTesselation(VaryingsToDS input)
{
VaryingsToPS output;
output.vmesh = VertMeshTesselation(input.vmesh);
MotionVectorPositionZBias(output);
output.vpass.positionCS = input.vpass.positionCS;
output.vpass.previousPositionCS = input.vpass.previousPositionCS;
return PackVaryingsToPS(output);
}
#endif // TESSELLATION_ON
#else // _WRITE_TRANSPARENT_MOTION_VECTOR
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl"
PackedVaryingsType Vert(AttributesMesh inputMesh)
{
VaryingsType varyingsType;
varyingsType.vmesh = VertMesh(inputMesh);
#include "HDRPToonOutlineVertMain.hlsl"
return PackVaryingsType(varyingsType);
}
#ifdef TESSELLATION_ON
PackedVaryingsToPS VertTesselation(VaryingsToDS input)
{
VaryingsToPS output;
output.vmesh = VertMeshTesselation(input.vmesh);
return PackVaryingsToPS(output);
}
#endif // TESSELLATION_ON
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
#ifdef TESSELLATION_ON
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/TessellationShare.hlsl"
#endif
#ifdef UNITY_VIRTUAL_TEXTURING
#define VT_BUFFER_TARGET SV_Target1
#define EXTRA_BUFFER_TARGET SV_Target2
#else
#define EXTRA_BUFFER_TARGET SV_Target1
#endif
void Frag(PackedVaryingsToPS packedInput,
#ifdef OUTPUT_SPLIT_LIGHTING
out float4 outColor : SV_Target0, // outSpecularLighting
#ifdef UNITY_VIRTUAL_TEXTURING
out float4 outVTFeedback : VT_BUFFER_TARGET,
#endif
out float4 outDiffuseLighting : EXTRA_BUFFER_TARGET,
OUTPUT_SSSBUFFER(outSSSBuffer)
#else
out float4 outColor : SV_Target0
#ifdef UNITY_VIRTUAL_TEXTURING
, out float4 outVTFeedback : VT_BUFFER_TARGET
#endif
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
, out float4 outMotionVec : EXTRA_BUFFER_TARGET
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
#endif // OUTPUT_SPLIT_LIGHTING
#ifdef _DEPTHOFFSET_ON
, out float outputDepth : SV_Depth
#endif
)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput);
FragInputs input = UnpackVaryingsMeshToFragInputs(packedInput.vmesh);
#ifdef _IS_CLIPPING_MASK
if (_ClippingMaskMode != 0)
{
discard;
}
#endif
#ifdef _IS_CLIPPING_MATTE
if (_ClippingMatteMode != 0)
{
discard;
}
#endif // _IS_CLIPPING_MATTE
#if defined(UTS_DEBUG_SHADOWMAP_NO_OUTLINE)
discard;
#endif
//v.2.0.5
if (_ZOverDrawMode > 0.99f)
{
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.deviceDepth;
#endif
#ifdef UNITY_VIRTUAL_TEXTURING
outVTFeedback = builtinData.vtPackedFeedback;
#endif
outColor = float4(1.0f, 1.0f, 1.0f, 1.0f); // but nothing should be drawn except Z value as colormask is set to 0
return;
}
_Color = _BaseColor;
float4 objPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1));
float4 Set_UV0 = input.texCoord0;
// The following temporary definition of unity_AmbientEquator is for HDRP only.
//float4 unity_AmbientEquator = float4(0.05, 0.05, 0.05, 1.0); //Todo.
//v.2.0.9
//float3 envLightSource_GradientEquator = unity_AmbientEquator.rgb > 0.05 ? unity_AmbientEquator.rgb : half3(0.05, 0.05, 0.05);
float3 envLightSource_GradientEquator = ShadeSH9(float4(0, 1, 0, 0));
float3 envLightSource_SkyboxIntensity = max(
SampleBakedGI_UTS_OutLine(objPos.xyz, float3(0.0, 0.0, 0.0), input.texCoord1.xy, input.texCoord2.xy),
SampleBakedGI_UTS_OutLine(objPos.xyz, float3(0.0, -1.0, 0.0), input.texCoord1.xy, input.texCoord2.xy)
).rgb;
float3 ambientSkyColor = envLightSource_SkyboxIntensity.rgb > 0.0 ? envLightSource_SkyboxIntensity : envLightSource_GradientEquator;
ambientSkyColor *= GetCurrentExposureMultiplier() * 5.0f;
float4 _MainTex_var = SAMPLE_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, TRANSFORM_TEX(Set_UV0, _MainTex));
float3 Set_BaseColor = _BaseColor.rgb*_MainTex_var.rgb;
float3 _Is_BlendBaseColor_var = lerp(_Outline_Color.rgb * ambientSkyColor, (_Outline_Color.rgb * ambientSkyColor * Set_BaseColor * Set_BaseColor), _Is_BlendBaseColor);
//
float3 _OutlineTex_var = tex2D(_OutlineTex,TRANSFORM_TEX(Set_UV0, _OutlineTex)).xyz;
float4 overridingColor = lerp(_OutlineMaskColor, float4(_OutlineMaskColor.w, _OutlineMaskColor.w, _OutlineMaskColor.w, 1.0f), _ComposerMaskMode);
float maskEnabled = max(_OutlineOverridden, _ComposerMaskMode);
//v.2.0.7.5
#ifdef _IS_OUTLINE_CLIPPING_NO
float3 Set_Outline_Color = lerp(_Is_BlendBaseColor_var, _OutlineTex_var.rgb*_Outline_Color.rgb * ambientSkyColor, _Is_OutlineTex );
if (_OutlineVisible < 0.1)
{
// Todo.
// without this, something is drawn even if _OutlineVisible = 0, in AngelRing(HDRP)
discard;
}
Set_Outline_Color = lerp(Set_Outline_Color, overridingColor.xyz, maskEnabled);
float3 volColor, volOpacity;
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
// input.positionSS is SV_Position
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
EvaluateAtmosphericScattering(posInput, V, volColor, volOpacity); // Premultiplied alpha
Set_Outline_Color.xyz = Set_Outline_Color.xyz * (1 - volOpacity) + volColor * _OutlineVisible;
outColor =float4(Set_Outline_Color, _OutlineVisible );
#elif _IS_OUTLINE_CLIPPING_YES
float4 _ClippingMask_var = SAMPLE_TEXTURE2D(_ClippingMask, sampler_MainTex, TRANSFORM_TEX(Set_UV0, _ClippingMask));
float Set_MainTexAlpha = _MainTex_var.a;
float _IsBaseMapAlphaAsClippingMask_var = lerp( _ClippingMask_var.r, Set_MainTexAlpha, _IsBaseMapAlphaAsClippingMask );
float _Inverse_Clipping_var = lerp( _IsBaseMapAlphaAsClippingMask_var, (1.0 - _IsBaseMapAlphaAsClippingMask_var), _Inverse_Clipping );
float Set_Clipping = saturate((_Inverse_Clipping_var+_Clipping_Level));
clip(Set_Clipping - 0.5);
float4 Set_Outline_Color = lerp( float4(_Is_BlendBaseColor_var, Set_Clipping), float4((_OutlineTex_var.rgb * _Outline_Color.rgb * ambientSkyColor),Set_Clipping), _Is_OutlineTex );
Set_Outline_Color = lerp(Set_Outline_Color, overridingColor, maskEnabled);
Set_Outline_Color.w *= _OutlineVisible;
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
// input.positionSS is SV_Position
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
float3 volColor, volOpacity;
EvaluateAtmosphericScattering(posInput, V, volColor, volOpacity); // Premultiplied alpha
Set_Outline_Color.xyz = Set_Outline_Color.xyz * (1 - volOpacity.x) + volColor * Set_Outline_Color.w;
outColor = Set_Outline_Color;
#endif
//outColor.rgb = ambientSkyColor;
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.deviceDepth;
#endif
#ifdef UNITY_VIRTUAL_TEXTURING
outVTFeedback = builtinData.vtPackedFeedback;
#endif
}
// End of File

View File

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

View File

@@ -0,0 +1,65 @@
//Unity Toon Shader/HDRP
//nobuyuki@unity3d.com
//toshiyuki@unity3d.com (Universal RP/HDRP)
#if 1
float4 objPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1));
float2 Set_UV0 = inputMesh.uv0;
float4 _Outline_Sampler_var = tex2Dlod(_Outline_Sampler, float4(TRANSFORM_TEX(Set_UV0, _Outline_Sampler), 0.0, 0));
//v.2.0.4.3 baked Normal Texture for Outline
float3 normalDir = UnityObjectToWorldNormal(inputMesh.normalOS);
float3 tangentDir = normalize(mul(unity_ObjectToWorld, float4(inputMesh.tangentOS.xyz, 0.0)).xyz);
float3 bitangentDir = normalize(cross(normalDir, tangentDir) * inputMesh.tangentOS.w);
float3x3 tangentTransform = float3x3(tangentDir, bitangentDir, normalDir);
//UnpackNormal() can't be used, and so as follows. Do not specify a bump for the texture to be used.
float4 _BakedNormal_var = (tex2Dlod(_BakedNormal, float4(TRANSFORM_TEX(Set_UV0, _BakedNormal), 0.0, 0)) * 2 - 1);
float3 _BakedNormalDir = normalize(mul(_BakedNormal_var.rgb, tangentTransform));
//end
float Set_Outline_Width = (_Outline_Width * 0.01 * smoothstep(_Farthest_Distance, _Nearest_Distance, distance(objPos.rgb, _WorldSpaceCameraPos)) * _Outline_Sampler_var.rgb).r;
Set_Outline_Width *= (1.0f - _ZOverDrawMode);
//v.2.0.7.5
float4 _ClipCameraPos = mul(UNITY_MATRIX_VP, float4(_WorldSpaceCameraPos.xyz, 1));
//v.2.0.7
#if defined(UNITY_REVERSED_Z)
//v.2.0.4.2 (DX)
_Offset_Z = _Offset_Z * -0.01;
#else
//OpenGL
_Offset_Z = _Offset_Z * 0.01;
#endif
float3 FinalNormal;
if(_UseSmoothedNormal == 1)
{
float3 normal = float3(inputMesh.uv1, 0);
normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy)));
FinalNormal = mul(normal, tangentTransform);
}
else
{
FinalNormal = lerp(inputMesh.normalOS, _BakedNormalDir, _Is_BakedNormal);
}
//v2.0.4
#ifdef _OUTLINE_NML
//v.2.0.4.3 baked Normal Texture for Outline
float3 normal = mul((float3x3)transpose(mul(UNITY_MATRIX_I_M, UNITY_MATRIX_I_V)), FinalNormal);
#elif _OUTLINE_POS
Set_Outline_Width = Set_Outline_Width * 2;
float signVar = dot(normalize(inputMesh.positionOS), normalize(inputMesh.normalOS)) < 0 ? -1 : 1;
float3 normal = mul((float3x3)transpose(mul(UNITY_MATRIX_I_M, UNITY_MATRIX_I_V)), signVar * normalize(inputMesh.positionOS));
#endif
// screen space width
float2 extendDir = normalize(TransformWViewToHClip(normal).xy);
float4 clipPos = UnityObjectToClipPos(inputMesh.positionOS);
clipPos.xy += extendDir * min(_Outline_MaxWidth, (clipPos.w * Set_Outline_Width));
clipPos.z = clipPos.z + _Offset_Z * _ClipCameraPos.z;
float4 rws = mul(UNITY_MATRIX_I_P, clipPos); // use UNITY_MATRIX_I_P instead of unity_CameraInvProjection.
rws = mul(UNITY_MATRIX_I_V, rws); // use UNITY_MATRIX_I_V instead of unity_cameraToWorld.
#ifndef TESSELLATION_ON
varyingsType.vmesh.positionCS = clipPos;
#endif // TESSELLATION_ON
varyingsType.vmesh.positionRWS = rws.xyz;
#endif // #if 1

View File

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

View File

@@ -0,0 +1,269 @@
#if SHADERPASS != SHADERPASS_FORWARD
#error SHADERPASS_is_not_correctly_define
#endif
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/MotionVectorVertexShaderCommon.hlsl"
PackedVaryingsType Vert(AttributesMesh inputMesh, AttributesPass inputPass)
{
VaryingsType varyingsType;
varyingsType.vmesh = VertMesh(inputMesh);
return MotionVectorVS(varyingsType, inputMesh, inputPass);
}
#ifdef TESSELLATION_ON
PackedVaryingsToPS VertTesselation(VaryingsToDS input)
{
VaryingsToPS output;
output.vmesh = VertMeshTesselation(input.vmesh);
MotionVectorPositionZBias(output);
output.vpass.positionCS = input.vpass.positionCS;
output.vpass.previousPositionCS = input.vpass.previousPositionCS;
return PackVaryingsToPS(output);
}
#endif // TESSELLATION_ON
#else // _WRITE_TRANSPARENT_MOTION_VECTOR
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl"
PackedVaryingsType Vert(AttributesMesh inputMesh)
{
VaryingsType varyingsType;
#if defined(HAVE_RECURSIVE_RENDERING)
// If we have a recursive raytrace object, we will not render it.
// As we don't want to rely on renderqueue to exclude the object from the list,
// we cull it by settings position to NaN value.
// TODO: provide a solution to filter dyanmically recursive raytrace object in the DrawRenderer
if (_EnableRecursiveRayTracing && _RayTracing > 0.0)
{
ZERO_INITIALIZE(VaryingsType, varyingsType); // Divide by 0 should produce a NaN and thus cull the primitive.
}
else
#endif
{
varyingsType.vmesh = VertMesh(inputMesh);
}
return PackVaryingsType(varyingsType);
}
#ifdef TESSELLATION_ON
PackedVaryingsToPS VertTesselation(VaryingsToDS input)
{
VaryingsToPS output;
output.vmesh = VertMeshTesselation(input.vmesh);
return PackVaryingsToPS(output);
}
#endif // TESSELLATION_ON
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
#ifdef TESSELLATION_ON
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/TessellationShare.hlsl"
#endif
#ifdef UNITY_VIRTUAL_TEXTURING
#define VT_BUFFER_TARGET SV_Target1
#define EXTRA_BUFFER_TARGET SV_Target2
#else
#define EXTRA_BUFFER_TARGET SV_Target1
#endif
void Frag(PackedVaryingsToPS packedInput,
#ifdef OUTPUT_SPLIT_LIGHTING
out float4 outColor : SV_Target0, // outSpecularLighting
#ifdef UNITY_VIRTUAL_TEXTURING
out float4 outVTFeedback : VT_BUFFER_TARGET,
#endif
out float4 outDiffuseLighting : EXTRA_BUFFER_TARGET,
OUTPUT_SSSBUFFER(outSSSBuffer)
#else
out float4 outColor : SV_Target0
#ifdef UNITY_VIRTUAL_TEXTURING
,out float4 outVTFeedback : VT_BUFFER_TARGET
#endif
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
, out float4 outMotionVec : EXTRA_BUFFER_TARGET
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
#endif // OUTPUT_SPLIT_LIGHTING
#ifdef _DEPTHOFFSET_ON
, out float outputDepth : SV_Depth
#endif
)
{
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
// Init outMotionVector here to solve compiler warning (potentially unitialized variable)
// It is init to the value of forceNoMotion (with 2.0)
outMotionVec = float4(2.0, 0.0, 0.0, 0.0);
#endif
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput);
FragInputs input = UnpackVaryingsToFragInputs(packedInput);
// We need to readapt the SS position as our screen space positions are for a low res buffer, but we try to access a full res buffer.
input.positionSS.xy = _OffScreenRendering > 0 ? (input.positionSS.xy * _OffScreenDownsampleFactor) : input.positionSS.xy;
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
// input.positionSS is SV_Position
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);
#ifdef VARYINGS_NEED_POSITION_WS
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
#else
// Unused
float3 V = float3(1.0, 1.0, 1.0); // Avoid the division by 0
#endif
SurfaceData surfaceData;
BuiltinData builtinData;
GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(input.positionSS.xy, surfaceData);
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);
outColor = float4(0.0, 0.0, 0.0, 0.0);
// We need to skip lighting when doing debug pass because the debug pass is done before lighting so some buffers may not be properly initialized potentially causing crashes on PS4.
#ifdef DEBUG_DISPLAY
// Init in debug display mode to quiet warning
#ifdef OUTPUT_SPLIT_LIGHTING
outDiffuseLighting = 0;
ENCODE_INTO_SSSBUFFER(surfaceData, posInput.positionSS, outSSSBuffer);
#endif
float4 Set_UV0 = input.texCoord0;
float4 _MainTex_var = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, TRANSFORM_TEX(Set_UV0, _MainTex));
surfaceData.baseColor = _MainTex_var.xyz;
// Same code in ShaderPassForwardUnlit.shader
// Reminder: _DebugViewMaterialArray[i]
// i==0 -> the size used in the buffer
// i>0 -> the index used (0 value means nothing)
// The index stored in this buffer could either be
// - a gBufferIndex (always stored in _DebugViewMaterialArray[1] as only one supported)
// - a property index which is different for each kind of material even if reflecting the same thing (see MaterialSharedProperty)
bool viewMaterial = false;
int bufferSize = _DebugViewMaterialArray[0].x;
if (bufferSize != 0)
{
bool needLinearToSRGB = false;
float3 result = float3(1.0, 0.0, 1.0);
// Loop through the whole buffer
// Works because GetSurfaceDataDebug will do nothing if the index is not a known one
for (int index = 1; index <= bufferSize; index++)
{
int indexMaterialProperty = _DebugViewMaterialArray[index].x;
// skip if not really in use
if (indexMaterialProperty != 0)
{
viewMaterial = true;
GetPropertiesDataDebug(indexMaterialProperty, result, needLinearToSRGB);
GetVaryingsDataDebug(indexMaterialProperty, input, result, needLinearToSRGB);
GetBuiltinDataDebug(indexMaterialProperty, builtinData, posInput, result, needLinearToSRGB);
GetSurfaceDataDebug(indexMaterialProperty, surfaceData, result, needLinearToSRGB);
GetBSDFDataDebug(indexMaterialProperty, bsdfData, result, needLinearToSRGB);
}
}
// TEMP!
// For now, the final blit in the backbuffer performs an sRGB write
// So in the meantime we apply the inverse transform to linear data to compensate, unless we output to AOVs.
if (!needLinearToSRGB && _DebugAOVOutput == 0)
result = SRGBToLinear(max(0, result));
outColor = float4(result, 1.0);
}
if (!viewMaterial)
{
if (_DebugFullScreenMode == FULLSCREENDEBUGMODE_VALIDATE_DIFFUSE_COLOR || _DebugFullScreenMode == FULLSCREENDEBUGMODE_VALIDATE_SPECULAR_COLOR)
{
float3 result = float3(0.0, 0.0, 0.0);
GetPBRValidatorDebug(surfaceData, result);
outColor = float4(result, 1.0f);
}
else if (_DebugFullScreenMode == FULLSCREENDEBUGMODE_TRANSPARENCY_OVERDRAW)
{
float4 result = _DebugTransparencyOverdrawWeight * float4(TRANSPARENCY_OVERDRAW_COST, TRANSPARENCY_OVERDRAW_COST, TRANSPARENCY_OVERDRAW_COST, TRANSPARENCY_OVERDRAW_A);
outColor = result;
}
else
#endif
{
#ifdef _SURFACE_TYPE_TRANSPARENT
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_TRANSPARENT;
#else
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_OPAQUE;
#endif
LightLoopOutput lightLoopOutput;
LightLoop(V, posInput, preLightData, bsdfData, builtinData, featureFlags, lightLoopOutput);
// Alias
float3 diffuseLighting = lightLoopOutput.diffuseLighting;
float3 specularLighting = lightLoopOutput.specularLighting;
diffuseLighting *= GetCurrentExposureMultiplier();
specularLighting *= GetCurrentExposureMultiplier();
#ifdef OUTPUT_SPLIT_LIGHTING
if (_EnableSubsurfaceScattering != 0 && ShouldOutputSplitLighting(bsdfData))
{
outColor = float4(specularLighting, 1.0);
outDiffuseLighting = float4(TagLightingForSSS(diffuseLighting), 1.0);
}
else
{
outColor = float4(diffuseLighting + specularLighting, 1.0);
outDiffuseLighting = 0;
}
ENCODE_INTO_SSSBUFFER(surfaceData, posInput.positionSS, outSSSBuffer);
#else
outColor = ApplyBlendMode(diffuseLighting, specularLighting, builtinData.opacity);
outColor = EvaluateAtmosphericScattering(posInput, V, outColor);
#endif
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
VaryingsPassToPS inputPass = UnpackVaryingsPassToPS(packedInput.vpass);
bool forceNoMotion = any(unity_MotionVectorsParams.yw == 0.0);
// outMotionVec is already initialize at the value of forceNoMotion (see above)
if (!forceNoMotion)
{
float2 motionVec = CalculateMotionVector(inputPass.positionCS, inputPass.previousPositionCS);
EncodeMotionVector(motionVec * 0.5, outMotionVec);
outMotionVec.zw = 1.0;
}
#endif
}
#ifdef DEBUG_DISPLAY
}
#endif
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.deviceDepth;
#endif
#ifdef UNITY_VIRTUAL_TEXTURING
outVTFeedback = builtinData.vtPackedFeedback;
#endif
}

View File

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

View File

@@ -0,0 +1,785 @@
//Unity Toon Shader/HDRP
//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
#ifndef SCALARIZE_LIGHT_LOOP
// We perform scalarization only for forward rendering as for deferred loads will already be scalar since tiles will match waves and therefore all threads will read from the same tile.
// More info on scalarization: https://flashypixels.wordpress.com/2018/11/10/intro-to-gpu-scalarization-part-2-scalarize-all-the-lights/ .
// Note that it is currently disabled on gamecore platforms for issues with wave intrinsics and the new compiler, it will be soon investigated, but we disable it in the meantime.
#define SCALARIZE_LIGHT_LOOP (defined(PLATFORM_SUPPORTS_WAVE_INTRINSICS) && !defined(LIGHTLOOP_DISABLE_TILE_AND_CLUSTER) && !defined(SHADER_API_GAMECORE) && SHADERPASS == SHADERPASS_FORWARD)
#endif
//#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoopDef.hlsl"
#include "Packages/com.misaki.hdrp-toon/Runtime/HDRP/Shaders/Includes/Common/UtsCommon.hlsl"
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/MotionVectorVertexShaderCommon.hlsl"
PackedVaryingsType Vert(AttributesMesh inputMesh, AttributesPass inputPass)
{
VaryingsType varyingsType;
varyingsType.vmesh = VertMesh(inputMesh);
return MotionVectorVS(varyingsType, inputMesh, inputPass);
}
#else // _WRITE_TRANSPARENT_MOTION_VECTOR
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl"
PackedVaryingsType Vert(AttributesMesh inputMesh)
{
VaryingsType varyingsType;
varyingsType.vmesh = VertMesh(inputMesh);
return PackVaryingsType(varyingsType);
}
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
///////////////////////////////////////////////////////////////////////////////
// Attenuation Functions /
///////////////////////////////////////////////////////////////////////////////
// Grafted from URP
// Matches Unity Vanila attenuation
// Attenuation smoothly decreases to light range.
float DistanceAttenuation(float distanceSqr, half2 distanceAttenuation)
{
// We use a shared distance attenuation for additional directional and puctual lights
// for directional lights attenuation will be 1
float lightAtten = rcp(distanceSqr);
#if SHADER_HINT_NICE_QUALITY
// Use the smoothing factor also used in the Unity lightmapper.
half factor = distanceSqr * distanceAttenuation.x;
half smoothFactor = saturate(1.0h - factor * factor);
smoothFactor = smoothFactor * smoothFactor;
#else
// We need to smoothly fade attenuation to light range. We start fading linearly at 80% of light range
// Therefore:
// fadeDistance = (0.8 * 0.8 * lightRangeSq)
// smoothFactor = (lightRangeSqr - distanceSqr) / (lightRangeSqr - fadeDistance)
// We can rewrite that to fit a MAD by doing
// distanceSqr * (1.0 / (fadeDistanceSqr - lightRangeSqr)) + (-lightRangeSqr / (fadeDistanceSqr - lightRangeSqr)
// distanceSqr * distanceAttenuation.y + distanceAttenuation.z
half smoothFactor = saturate(distanceSqr * distanceAttenuation.x + distanceAttenuation.y);
#endif
return lightAtten * smoothFactor;
}
float ApplyChannelAlpha( float alpha)
{
return lerp(1.0, alpha, _ComposerMaskMode);
}
bool UtsUseScreenSpaceShadow(DirectionalLightData light, float3 normalWS)
{
#if defined(RAY_TRACED_SCREEN_SPACE_SHADOW_FLAG)
// Two different options are possible here
// - We have a ray trace shadow in which case we have no valid signal for a transmission and we need to fallback on the rasterized shadow
// - We have a screen space shadow and it already contains the transmission shadow and we can use it straight away
bool visibleLight = 0.5 * dot(normalWS, -light.forward) + 0.5 > 0.0;
bool validScreenSpaceShadow = (light.screenSpaceShadowIndex & SCREEN_SPACE_SHADOW_INDEX_MASK) != INVALID_SCREEN_SPACE_SHADOW;
bool rayTracedShadow = (light.screenSpaceShadowIndex & RAY_TRACED_SCREEN_SPACE_SHADOW_FLAG) != 0.0;
return (validScreenSpaceShadow && ((rayTracedShadow && visibleLight) || !rayTracedShadow));
#else
return ( (light.screenSpaceShadowIndex & SCREEN_SPACE_SHADOW_INDEX_MASK) != INVALID_SCREEN_SPACE_SHADOW);
#endif
}
#ifdef UNITY_VIRTUAL_TEXTURING
#define VT_BUFFER_TARGET SV_Target1
#define EXTRA_BUFFER_TARGET SV_Target2
#else
#define EXTRA_BUFFER_TARGET SV_Target1
#endif
uniform sampler2D _RaytracedHardShadow;
float4 _RaytracedHardShadow_TexelSize;
void Frag(PackedVaryingsToPS packedInput,
#ifdef OUTPUT_SPLIT_LIGHTING
out float4 outColor : SV_Target0, // outSpecularLighting
#ifdef UNITY_VIRTUAL_TEXTURING
out float4 outVTFeedback : VT_BUFFER_TARGET,
#endif
out float4 outDiffuseLighting : EXTRA_BUFFER_TARGET,
OUTPUT_SSSBUFFER(outSSSBuffer)
#else
out float4 outColor : SV_Target0
#ifdef UNITY_VIRTUAL_TEXTURING
,out float4 outVTFeedback : VT_BUFFER_TARGET
#endif
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
, out float4 outMotionVec : EXTRA_BUFFER_TARGET
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
#endif // OUTPUT_SPLIT_LIGHTING
#ifdef _DEPTHOFFSET_ON
, out float outputDepth : SV_Depth
#endif
)
{
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
// Init outMotionVector here to solve compiler warning (potentially unitialized variable)
// It is init to the value of forceNoMotion (with 2.0)
outMotionVec = float4(2.0, 0.0, 0.0, 0.0);
#endif
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput);
FragInputs input = UnpackVaryingsMeshToFragInputs(packedInput.vmesh);
#if defined(PLATFORM_SUPPORTS_PRIMITIVE_ID_IN_PIXEL_SHADER) && SHADER_STAGE_FRAGMENT
#if (defined(VARYINGS_NEED_PRIMITIVEID) || (SHADERPASS == SHADERPASS_FULL_SCREEN_DEBUG))
input.primitiveID = packedInput.primitiveID;
#endif
#endif
#if defined(VARYINGS_NEED_CULLFACE) && SHADER_STAGE_FRAGMENT
input.isFrontFace = IS_FRONT_VFACE(packedInput.cullFace, true, false);
#endif
float4 Set_UV0 = input.texCoord0;
UTSData utsData;
// We need to readapt the SS position as our screen space positions are for a low res buffer, but we try to access a full res buffer.
input.positionSS.xy = _OffScreenRendering > 0 ? (input.positionSS.xy * _OffScreenDownsampleFactor) : input.positionSS.xy;
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
// input.positionSS is SV_Position
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);
#ifdef VARYINGS_NEED_POSITION_WS
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
#ifdef _MATERIAL_TYPE_EYE
// Must have view Dir to work
float2 viewT = TransformObjectToTangent(V, input.tangentToWorld);
float2 parallaxOffset = viewT;
parallaxOffset.y = -parallaxOffset.y;
Set_UV0.xy = clamp(Set_UV0.xy -_EyeParallaxAmount * parallaxOffset, 0, 1);
#endif
#else
// Unused
float3 V = float3(1.0, 1.0, 1.0); // Avoid the division by 0
#endif
#ifdef _SURFACE_TYPE_TRANSPARENT
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_TRANSPARENT;
#else
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_OPAQUE;
#endif
SurfaceData surfaceData; // used to get normalWS;
BuiltinData builtinData; // used to get lightlayersAndSoOn
GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
outColor = float4(0.0, 0.0, 0.0, 0.0);
float3x3 tangentTransform = input.tangentToWorld;
float4 _MainTex_var = SAMPLE_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, TRANSFORM_TEX(Set_UV0, _BaseColorMap));
float4 normalLocal = 0;
if (_Use_SSSLut)
{
normalLocal = SAMPLE_TEXTURE2D_LOD(_NormalMap, sampler_NormalMap, TRANSFORM_TEX(Set_UV0, _BaseColorMap), _SSSIntensity);
}
else
{
normalLocal = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, TRANSFORM_TEX(Set_UV0, _BaseColorMap));
}
normalLocal.rgb = UnpackNormalScale(normalLocal, _NormalScale);
float3 _NormalMap_var = normalize(mul(normalLocal.rgb, tangentTransform));
float smoothness = _Smoothness;
float coatRoughness = 1;
float metallic = _Metallic;
float ao = 1.0;
float3 specularColor = 0;
#ifdef _MASKMAP
float4 _MaskMap_var = SAMPLE_TEXTURE2D(_MaskMap, sampler_MaskMap, TRANSFORM_TEX(Set_UV0, _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 _ANISOTROPYMAP
surfaceData.anisotropy = SAMPLE_TEXTURE2D(_AnisotropyMap, sampler_AnisotropyMap, TRANSFORM_TEX(Set_UV0, _AnisotropyMap)).r;
#if _PBR_Mode_KK
surfaceData.anisotropy += ADD_IDX(_Anisotropy) - 0.5;
#else
surfaceData.anisotropy *= ADD_IDX(_Anisotropy);
#endif
#else
surfaceData.anisotropy = 1.0;
surfaceData.anisotropy *= ADD_IDX(_Anisotropy);
#endif
#ifdef _PBR_Mode_KK
metallic = 0.0;
coatRoughness = 1 - smoothness;
smoothness *=_BSDFContribution;
#endif
#ifdef _PBR_Mode_TOON
float3 _SpecTex_var = 1;
#ifdef _SPECULARCOLORMAP
_SpecTex_var = SAMPLE_TEXTURE2D(_SpecularColorMap, sampler_SpecularColorMap, TRANSFORM_TEX(Set_UV0, _BaseColorMap)).rgb;
#endif
specularColor = _SpecTex_var * _SpecularColor;
#else
specularColor = GetSpecularColor(_MainTex_var.rgb * _BaseColor.rgb, metallic);
#endif
surfaceData.baseColor = _MainTex_var.rgb;
surfaceData.coatMask = _MainTex_var.a;
surfaceData.metallic = metallic;
surfaceData.ambientOcclusion = ao;
surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(dot(_NormalMap_var, V), ao, PerceptualRoughnessToRoughness(1 - smoothness));
surfaceData.perceptualSmoothness = smoothness;
surfaceData.normalWS = _NormalMap_var;
surfaceData.specularColor = specularColor;
float perceptualRoughness = 1 - surfaceData.perceptualSmoothness;
float3 tangentDir = Orthonormalize(tangentTransform[0].rgb, surfaceData.normalWS);
float3 bitangentDir = normalize(cross(surfaceData.normalWS, tangentDir));
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(input.positionSS.xy, surfaceData); // used to calc shadow
bsdfData.coatRoughness = coatRoughness;
bsdfData.normalWS = surfaceData.normalWS;
bsdfData.ambientOcclusion = surfaceData.ambientOcclusion;
bsdfData.specularOcclusion = surfaceData.specularOcclusion;
bsdfData.perceptualRoughness = perceptualRoughness;
bsdfData.anisotropy = surfaceData.anisotropy;
bsdfData.tangentWS = tangentDir;
bsdfData.bitangentWS = bitangentDir;
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData); // used to calc shadow
UTSAggregateLighting utsAggregateLighting;
ZERO_INITIALIZE(UTSAggregateLighting, utsAggregateLighting);
UTSLightData customMainLight;
customMainLight.shadowValue = 1.0f;
//UTSLightData mainPunctualLight;
//mainPunctualLight.lightColor = float3(0, 0, 0);
#define UNITY_PROJ_COORD(a) a
#define UNITY_SAMPLE_SCREEN_SHADOW(tex, uv) tex2Dproj( tex, UNITY_PROJ_COORD(uv) ).r
float inverseClipping = 0.0;
LightLoopContext context;
context.shadowContext = InitShadowContext();
context.shadowValue = 1;
context.sampleReflection = 0.0;
#if UNITY_VERSION >= 202120 && UNITY_VERSION < 202320
context.splineVisibility = -1;
#endif
#ifdef APPLY_FOG_ON_SKY_REFLECTIONS
context.positionWS = posInput.positionWS;
#endif
// With XR single-pass and camera-relative: offset position to do lighting computations from the combined center view (original camera matrix).
// This is required because there is only one list of lights generated on the CPU. Shadows are also generated once and shared between the instanced views.
ApplyCameraRelativeXR(posInput.positionWS);
// Initialize the contactShadow and contactShadowFade fields
InitContactShadow(posInput, context);
float3 i_normalDir = surfaceData.normalWS;
int mainLightIndex = -1;
float channelAlpha = 0.0f;
float3 finalColor = float3(0.0f, 0.0f, 0.0f);
if (featureFlags & LIGHTFEATUREFLAGS_DIRECTIONAL)
{
// because of light culling or light layer, we can not adopt this
// https://unity.slack.com/archives/C06V7HDDW/p1580959470180800
// int mainLightIndex = _DirectionalShadowIndex;
mainLightIndex = GetUtsMainLightIndex(builtinData);
DirectionalLightData lightData;
ZERO_INITIALIZE(DirectionalLightData, lightData);
if (mainLightIndex >= 0)
{
lightData = _DirectionalLightDatas[mainLightIndex];
}
float3 lightColor = ApplyCurrentExposureMultiplier(lightData.color);
float3 lightDirection = -lightData.forward;
#ifndef LIGHT_EVALUATION_NO_COOKIE
if (lightData.cookieMode != COOKIEMODE_NONE)
{
float3 lightToSample = input.positionRWS - lightData.positionRWS;
lightColor *= EvaluateCookie_Directional(context, lightData, lightToSample);
}
#endif
UTSLightData utsLightData;
utsLightData.lightDirection = lightDirection;
utsLightData.lightColor = lightColor;
utsLightData.diffuseDimmer = lightData.diffuseDimmer;
utsLightData.specularDimmer = lightData.specularDimmer;
utsLightData.shadowTint = lightData.shadowTint;
utsLightData.penumbraTint = lightData.penumbraTint;
customMainLight = utsLightData;
// Evaluate sun shadows.
if (_DirectionalShadowIndex >= 0)
{
DirectionalLightData light = _DirectionalLightDatas[_DirectionalShadowIndex];
#if defined(SCREEN_SPACE_SHADOWS_ON) && !defined(_SURFACE_TYPE_TRANSPARENT) && !defined(UTS_USE_RAYTRACING_SHADOW)
if (UtsUseScreenSpaceShadow(light, bsdfData.normalWS))
{
// HDRP Contact Shadow
context.shadowValue = GetScreenSpaceColorShadow(posInput, light.screenSpaceShadowIndex).SHADOW_TYPE_SWIZZLE;
}
else
#endif
{
// TODO: this will cause us to load from the normal buffer first. Does this cause a performance problem?
float3 L = -light.forward;
// Is it worth sampling the shadow map?
if ((light.lightDimmer > 0) && (light.shadowDimmer > 0) && // Note: Volumetric can have different dimmer, thus why we test it here
IsNonZeroBSDF(V, L, preLightData, bsdfData) &&
!ShouldEvaluateThickObjectTransmission(V, L, preLightData, bsdfData, light.shadowIndex))
{
#if defined(UTS_USE_RAYTRACING_SHADOW)
{
/*
struct PositionInputs
{
float3 positionWS; // World space position (could be camera-relative)
float2 positionNDC; // Normalized screen coordinates within the viewport : [0, 1) (with the half-pixel offset)
uint2 positionSS; // Screen space pixel coordinates : [0, NumPixels)
uint2 tileCoord; // Screen tile coordinates : [0, NumTiles)
float deviceDepth; // Depth from the depth buffer : [0, 1] (typically reversed)
float linearDepth; // View space Z coordinate : [Near, Far]
};
float4 size = _RaytracedHardShadow_TexelSize;
*/
float r = UNITY_SAMPLE_SCREEN_SHADOW(_RaytracedHardShadow, float4(posInput.positionNDC.xy, lightDirection * _ShadowBias, 1));
context.shadowValue = r;
}
#else
{
context.shadowValue = GetDirectionalShadowAttenuation(context.shadowContext,
posInput.positionSS, posInput.positionWS + lightDirection * _ShadowBias, GetNormalForShadowBias(bsdfData),
light.shadowIndex, L);
}
#endif // UTS_USE_RAYTRACING_SHADOW
}
#if defined (UTS_USE_RAYTRACING_SHADOW)
else
{
float r = UNITY_SAMPLE_SCREEN_SHADOW(_RaytracedHardShadow, float4(posInput.positionNDC.xy, lightDirection * _ShadowBias, 1));
context.shadowValue = r;
}
#endif // UTS_USE_RAYTRACING_SHADOW
}
context.shadowValue = lerp(1, context.shadowValue, lightData.shadowDimmer);
customMainLight.shadowValue = context.shadowValue;
}
#if defined(UTS_DEBUG_SELFSHADOW)
if (_DirectionalShadowIndex >= 0)
finalColor = UTS_SelfShdowMainLight(context, input, _DirectionalShadowIndex);
#else
UTS_MainLight(context, input, utsLightData, surfaceData, bsdfData, inverseClipping, channelAlpha, utsData, utsAggregateLighting);
#endif
int i = 0; // Declare once to avoid the D3D11 compiler warning.
for (i = 0; i < (int) _DirectionalLightCount; ++i)
{
if (IsMatchingLightLayer(_DirectionalLightDatas[i].lightLayers, builtinData.renderingLayers))
{
if (mainLightIndex != i)
{
float notDirectional = 0.0f;
UTSLightData utsLightData;
utsLightData.lightColor = ApplyCurrentExposureMultiplier(_DirectionalLightDatas[i].color);
utsLightData.lightDirection = -_DirectionalLightDatas[i].forward;
utsLightData.diffuseDimmer = _DirectionalLightDatas[i].diffuseDimmer;
utsLightData.specularDimmer = _DirectionalLightDatas[i].specularDimmer;
utsLightData.shadowTint = _DirectionalLightDatas[i].shadowTint;
utsLightData.penumbraTint = _DirectionalLightDatas[i].penumbraTint;
#if defined(UTS_DEBUG_SELFSHADOW)
#else
UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, 0, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting);
#endif
}
}
}
}
//#undef EVALUATE_BSDF_ENV
//#undef EVALUATE_BSDF_ENV_SKY
if (featureFlags & LIGHTFEATUREFLAGS_PUNCTUAL)
{
uint lightCount, lightStart;
#ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
GetCountAndStart(posInput, LIGHTCATEGORY_PUNCTUAL, lightStart, lightCount);
#else // LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
lightCount = _PunctualLightCount;
lightStart = 0;
#endif
bool fastPath = false;
#if SCALARIZE_LIGHT_LOOP
uint lightStartLane0;
fastPath = IsFastPath(lightStart, lightStartLane0);
if (fastPath)
{
lightStart = lightStartLane0;
}
#endif
// Scalarized loop. All lights that are in a tile/cluster touched by any pixel in the wave are loaded (scalar load), only the one relevant to current thread/pixel are processed.
// For clarity, the following code will follow the convention: variables starting with s_ are meant to be wave uniform (meant for scalar register),
// v_ are variables that might have different value for each thread in the wave (meant for vector registers).
// This will perform more loads than it is supposed to, however, the benefits should offset the downside, especially given that light data accessed should be largely coherent.
// Note that the above is valid only if wave intriniscs are supported.
uint v_lightListOffset = 0;
uint v_lightIdx = lightStart;
[loop] // vulkan shader compiler can not unroll.
while (v_lightListOffset < lightCount)
{
v_lightIdx = FetchIndex(lightStart, v_lightListOffset);
#if SCALARIZE_LIGHT_LOOP
uint s_lightIdx = ScalarizeElementIndex(v_lightIdx, fastPath);
#else
uint s_lightIdx = v_lightIdx;
#endif
if (s_lightIdx == -1)
break;
LightData s_lightData = FetchLight(s_lightIdx);
// If current scalar and vector light index match, we process the light. The v_lightListOffset for current thread is increased.
// Note that the following should really be ==, however, since helper lanes are not considered by WaveActiveMin, such helper lanes could
// end up with a unique v_lightIdx value that is smaller than s_lightIdx hence being stuck in a loop. All the active lanes will not have this problem.
if (s_lightIdx >= v_lightIdx)
{
v_lightListOffset++;
if (IsMatchingLightLayer(s_lightData.lightLayers, builtinData.renderingLayers))
{
float3 lightDirection;
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);
const float notDirectional = 1.0f;
UTSLightData utsLightData;
utsLightData.lightColor = additionalLightColor;
utsLightData.lightDirection = lightDirection;
utsLightData.diffuseDimmer = s_lightData.diffuseDimmer * lightColor.a;
utsLightData.specularDimmer = s_lightData.specularDimmer * lightColor.a;
utsLightData.shadowTint = s_lightData.shadowTint;
utsLightData.penumbraTint = s_lightData.penumbraTint;
#if defined(UTS_DEBUG_SELFSHADOW)
#else
posInput.positionWS = posInput.positionWS + lightDirection * _ShadowBias;
context.shadowValue = EvaluateShadow_Punctual(context, posInput, s_lightData, builtinData, GetNormalForShadowBias(bsdfData), lightDirection, distances);
posInput.positionWS = posInput.positionWS - lightDirection * _ShadowBias;
if (length(utsLightData.lightColor) >= length(customMainLight.lightColor))
{
float3 lightDirectionToObject;
float4 distancesToObject; // {d, d^2, 1/d, d_proj}
float3 objectCenter = (TransformObjectToWorld(float3(0, 0, 0)));
GetPunctualLightVectors(objectCenter, s_lightData, lightDirectionToObject, distancesToObject);
float4 lightColorToObject = EvaluateLight_Punctual(context, posInput, s_lightData, lightDirectionToObject, distancesToObject);
float3 additionalLightColorToObject = ApplyCurrentExposureMultiplier(lightColorToObject.rgb) * lightColorToObject.a;
customMainLight = utsLightData;
customMainLight.lightColor = additionalLightColorToObject;
customMainLight.lightDirection = lightDirectionToObject;
customMainLight.shadowValue = context.shadowValue;
}
UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, s_lightData.lightType, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting);
#endif
}
}
}
}
//v.2.0.7
#if SHADEROPTIONS_AREA_LIGHTS
if (featureFlags & LIGHTFEATUREFLAGS_AREA)
{
uint lightCount, lightStart;
#ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
GetCountAndStart(posInput, LIGHTCATEGORY_AREA, lightStart, lightCount);
#else
lightCount = _AreaLightCount;
lightStart = _PunctualLightCount;
#endif
if (lightCount > 0)
{
uint i = 0;
uint last = lightCount - 1;
LightData s_lightData = FetchLight(lightStart, i);
[loop] // vulkan shader compiler can not unroll.
while (i <= last)
{
if (IsMatchingLightLayer(s_lightData.lightLayers, builtinData.renderingLayers))
{
float3 lightDirection = -s_lightData.forward;
float3 areaLightColor = ApplyCurrentExposureMultiplier(s_lightData.color.rgb);
const float notDirectional = 1.0f;
UTSLightData utsLightData;
utsLightData.lightColor = areaLightColor;
utsLightData.lightDirection = lightDirection;
utsLightData.diffuseDimmer = s_lightData.diffuseDimmer;
utsLightData.specularDimmer = s_lightData.specularDimmer;
utsLightData.shadowTint = s_lightData.shadowTint;
utsLightData.penumbraTint = s_lightData.penumbraTint;
bool isRectLight = s_lightData.lightType == GPULIGHTTYPE_RECTANGLE;
float3 unL = s_lightData.positionRWS - posInput.positionWS;
utsLightData.lightDirection = normalize(unL);
float3 center = mul(preLightData.orthoBasisViewNormal, unL);
float3 right = mul(preLightData.orthoBasisViewNormal, s_lightData.right);
float3 up = mul(preLightData.orthoBasisViewNormal, s_lightData.up);
float halfWidth = s_lightData.size.x * 0.5;
float halfHeight = s_lightData.size.y * 0.5;
float intensity = PillowWindowing(unL, s_lightData.right, s_lightData.up, halfWidth, halfHeight, s_lightData.rangeAttenuationScale, s_lightData.rangeAttenuationBias);
// Make sure the light is front-facing (and has a non-zero effective area).
intensity *= (isRectLight && dot(unL, s_lightData.forward) >= 0) ? 0 : 1;
float4 ltcValue;
// Diffuse
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 *= ltcValue.a * intensity;
utsLightData.lightColor *= ltcValue.rgb;
// Specular
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 *= ltcValue.a * intensity;
if (isRectLight)
{
//Evaluate the shadow part
float shadow;
posInput.positionWS = posInput.positionWS + utsLightData.lightDirection * _ShadowBias;
context.shadowValue = EvaluateShadow_RectArea(context, posInput, s_lightData, builtinData, GetNormalForShadowBias(bsdfData), normalize(s_lightData.positionRWS), length(s_lightData.positionRWS));
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
}
s_lightData = FetchLight(lightStart, min(++i, last));
}
}
}
#endif // SHADEROPTIONS_AREA_LIGHTS
#ifdef _EMISSIVE_SIMPLE
float4 _Emissive_Tex_var = tex2D(_Emissive_Tex, TRANSFORM_TEX(Set_UV0, _Emissive_Tex));
float emissiveMask = _Emissive_Tex_var.a;
emissive = _Emissive_Tex_var.rgb * _Emissive_Color.rgb * emissiveMask;
#elif _EMISSIVE_ANIMATION
//v.2.0.7 Calculation View Coord UV for Scroll
float3 viewNormal_Emissive = (mul(UNITY_MATRIX_V, float4(i_normalDir, 0))).xyz;
float3 NormalBlend_Emissive_Detail = viewNormal_Emissive * float3(-1, -1, 1);
float3 NormalBlend_Emissive_Base = (mul(UNITY_MATRIX_V, float4(utsData.viewDirection, 0)).xyz * float3(-1, -1, 1)) + float3(0, 0, 1);
float3 noSknewViewNormal_Emissive = NormalBlend_Emissive_Base * dot(NormalBlend_Emissive_Base, NormalBlend_Emissive_Detail) / NormalBlend_Emissive_Base.z - NormalBlend_Emissive_Detail;
float2 _ViewNormalAsEmissiveUV = noSknewViewNormal_Emissive.xy * 0.5 + 0.5;
float2 _ViewCoord_UV = RotateUV(_ViewNormalAsEmissiveUV, -(utsData.cameraDir * utsData.cameraRoll), float2(0.5, 0.5), 1.0);
//Invert if it's "inside the mirror".
if (utsData.signMirror < 0) {
_ViewCoord_UV.x = 1 - _ViewCoord_UV.x;
}
else {
_ViewCoord_UV = _ViewCoord_UV;
}
float2 emissive_uv = lerp(Set_UV0, _ViewCoord_UV, _Is_ViewCoord_Scroll);
//
float4 _time_var = _Time;
float _base_Speed_var = (_time_var.g * _Base_Speed);
float _Is_PingPong_Base_var = lerp(_base_Speed_var, sin(_base_Speed_var), _Is_PingPong_Base);
float2 scrolledUV = emissive_uv + float2(_Scroll_EmissiveU, _Scroll_EmissiveV) * _Is_PingPong_Base_var;
float rotateVelocity = _Rotate_EmissiveUV * 3.141592654;
float2 _rotate_EmissiveUV_var = RotateUV(scrolledUV, rotateVelocity, float2(0.5, 0.5), _Is_PingPong_Base_var);
float4 _Emissive_Tex_var = tex2D(_Emissive_Tex, TRANSFORM_TEX(Set_UV0, _Emissive_Tex));
float emissiveMask = _Emissive_Tex_var.a;
_Emissive_Tex_var = tex2D(_Emissive_Tex, TRANSFORM_TEX(_rotate_EmissiveUV_var, _Emissive_Tex));
float _colorShift_Speed_var = 1.0 - cos(_time_var.g * _ColorShift_Speed);
float viewShift_var = smoothstep(0.0, 1.0, max(0, dot(utsData.normalDirection, utsData.viewDirection)));
float4 colorShift_Color = lerp(_Emissive_Color, lerp(_Emissive_Color, _ColorShift, _colorShift_Speed_var), _Is_ColorShift);
float4 viewShift_Color = lerp(_ViewShift, colorShift_Color, viewShift_var);
float4 emissive_Color = lerp(colorShift_Color, viewShift_Color, _Is_ViewShift);
emissive = emissive_Color.rgb * _Emissive_Tex_var.rgb * emissiveMask;
//
//v.2.0.6: GI_Intensity with Intensity Multiplier Filter
#endif
// We directly calculate custome main light during the light loop in upper code to avoid extra calculation
//customMainLight = GetCustomMainLightData(builtinData, mainPunctualLight);
#if _SDFShadow || (_RECEIVE_HAIR_SHADOW && ENABLE_UTS_HAIR_SHAOW)
float3 defaultLightDirection = normalize(UNITY_MATRIX_V[2].xyz + UNITY_MATRIX_V[1].xyz);
float3 defaultLightColor = saturate(max(float3(0.05, 0.05, 0.05) * _Unlit_Intensity, max(ShadeSH9(float4(0.0, 0.0, 0.0, 1.0)), ShadeSH9(float4(0.0, -1.0, 0.0, 1.0)).rgb) * _Unlit_Intensity));
float3 customLightDirection = normalize(mul(UNITY_MATRIX_M, float4(((float3(1.0, 0.0, 0.0) * _Offset_X_Axis_BLD * 10) + (float3(0.0, 1.0, 0.0) * _Offset_Y_Axis_BLD * 10) + (float3(0.0, 0.0, -1.0) * lerp(-1.0, 1.0, _Inverse_Z_Axis_BLD))), 0)).xyz);
float3 lightDirection = normalize(lerp(defaultLightDirection, customMainLight.lightDirection.xyz, any(customMainLight.lightDirection.xyz)));
lightDirection = lerp(lightDirection, customLightDirection, _Is_BLD);
float3 originalLightColor = customMainLight.lightColor.rgb;
originalLightColor = lerp(originalLightColor, clamp(originalLightColor, ConvertFromEV100(_ToonEvAdjustmentValueMin ), ConvertFromEV100(_ToonEvAdjustmentValueMax)), _ToonEvAdjustmentCurve) * _Light_Intensity_Multiplier;
float3 lightColor = lerp(max(defaultLightColor, originalLightColor), max(defaultLightColor, saturate(originalLightColor)), max(_Is_Filter_LightColor, _ToonLightHiCutFilter));
float4 _1st_ShadeMap_var = lerp(SAMPLE_TEXTURE2D(_1st_ShadeMap, sampler_BaseColorMap,TRANSFORM_TEX(Set_UV0, _1st_ShadeMap)), _MainTex_var, _Use_BaseAs1st);
float3 _1st_Shade_var = lerp((_1st_ShadeMap_var.rgb * _1st_ShadeColor.rgb), ((_1st_ShadeMap_var.rgb * _1st_ShadeColor.rgb) * lightColor), _Is_LightColor_1st_Shade);
float systemShadowValue = lerp(1.0f, saturate(customMainLight.shadowValue * 2.0f), _Set_SystemShadowsToBase);
#endif
#ifdef _SDFShadow
// modified by Suomi @ 20230902 - SDFResult is used to sample SDF texture on the correct side
float angle;
bool rightside;
float2 SDF_UV = TRANSFORM_TEX(Set_UV0, _BaseColorMap);
float4 sdfRes = SDFResult(rightside, angle, customMainLight.lightDirection, SDF_UV);
float sdfShadowValue = 1.0f - SDFMask(angle, sdfRes.r);
utsAggregateLighting.directDiffuse = lerp(_1st_Shade_var, bsdfData.diffuseColor * _BaseColor.rgb * lightColor, sdfShadowValue * systemShadowValue);
utsAggregateLighting.directSpecular = lerp(0, utsAggregateLighting.directSpecular, sdfShadowValue * systemShadowValue);
utsAggregateLighting.directSpecular += _SDFNoseHighlightCoef * SDFNoseHighlight(angle, sdfRes.g, rightside, SDF_UV) * lightColor;
#endif
#if _RECEIVE_HAIR_SHADOW && ENABLE_UTS_HAIR_SHAOW
// 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)));
float3 viewLightDir = TransformWorldToViewDir(customMainLight.lightDirection); // / 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 = (input.positionSS.xy + 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 depthCorrect = 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.
float hairShadow = lerp(0,hairShadowOpacity,depthCorrect);
utsAggregateLighting.directDiffuse = lerp(utsAggregateLighting.directDiffuse, _1st_Shade_var, hairShadow * systemShadowValue);
utsAggregateLighting.directSpecular = lerp(utsAggregateLighting.directSpecular, 0, hairShadow * systemShadowValue);
#endif
// Ambient
utsAggregateLighting.indirectDiffuse = EvaluateIndirectDiffuse(posInput, bsdfData, V) * _ID_Intensity;
utsAggregateLighting.indirectSpecular = EvaluateIndirectSpecular(context, posInput, preLightData, bsdfData, surfaceData, builtinData, V) * _IR_Intensity;
float3 finalColorWoEmissive = AccumulateUTSAggregateLighting(utsAggregateLighting);
finalColorWoEmissive = GetExposureAdjustedColor(finalColorWoEmissive);
finalColorWoEmissive = ApplyCompensation(finalColorWoEmissive);
finalColor = finalColorWoEmissive + emissive;
#ifdef _IS_TRANSCLIPPING_OFF
outColor = float4(finalColor, 1 * ApplyChannelAlpha(channelAlpha));
#elif _IS_TRANSCLIPPING_ON
float Set_Opacity = saturate((inverseClipping + _Tweak_transparency));
outColor = EvaluateAtmosphericScattering(posInput, V, float4(finalColor, 1));
outColor = float4(outColor.rgb, Set_Opacity * ApplyChannelAlpha(channelAlpha));
#endif
#if _MATERIAL_TYPE_FRONT_HAIR && ENABLE_UTS_HAIR_BLENDING
float2 screenUV = posInput.positionNDC * _HairBlendingRTHandleScale.xy;
float4 hairBlendingMap = SAMPLE_TEXTURE2D(_HairBlendingTex, s_trilinear_clamp_sampler, screenUV);
outColor.rgb = lerp(outColor.rgb, hairBlendingMap.rgb, hairBlendingMap.a * _HairBlendingFactor);
#endif
#if UTS_DEBUG_SHADOWMAP || UTS_DEBUG_SELFSHADOW
outColor.rgb = 1;
#ifdef UTS_DEBUG_SELFSHADOW
outColor.rgb = min(finalColor, outColor.rgb);
#endif
#ifdef UTS_DEBUG_SHADOWMAP
#ifdef UTS_DEBUG_SHADOWMAP_BINALIZATION
outColor.rgb = min(context.shadowValue < 0.9f ? clamp(context.shadowValue - 0.2, 0.0, 0.9) : 1.0f, outColor.rgb);
#else
outColor.rgb = min(context.shadowValue, outColor.rgb);
#endif
#endif // ifdef UTS_DEBUG_SHADOWMAP
#endif // defined(UTS_DEBUG_SHADOWMAP) || defined(UTS_DEBUG_SELFSHADOW)
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.deviceDepth;
#endif
#ifdef UNITY_VIRTUAL_TEXTURING
outVTFeedback = builtinData.vtPackedFeedback;
#endif
//outColor.rgb = customMainLight.shadowValue;
}

View File

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

View File

@@ -0,0 +1,314 @@
//Unity Toon Shader/HDRP
//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
#ifndef SCALARIZE_LIGHT_LOOP
// We perform scalarization only for forward rendering as for deferred loads will already be scalar since tiles will match waves and therefore all threads will read from the same tile.
// More info on scalarization: https://flashypixels.wordpress.com/2018/11/10/intro-to-gpu-scalarization-part-2-scalarize-all-the-lights/ .
// Note that it is currently disabled on gamecore platforms for issues with wave intrinsics and the new compiler, it will be soon investigated, but we disable it in the meantime.
#define SCALARIZE_LIGHT_LOOP (defined(PLATFORM_SUPPORTS_WAVE_INTRINSICS) && !defined(LIGHTLOOP_DISABLE_TILE_AND_CLUSTER) && !defined(SHADER_API_GAMECORE) && SHADERPASS == SHADERPASS_FORWARD)
#endif
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/MotionVectorVertexShaderCommon.hlsl"
PackedVaryingsType Vert(AttributesMesh inputMesh, AttributesPass inputPass)
{
VaryingsType varyingsType;
varyingsType.vmesh = VertMesh(inputMesh);
return MotionVectorVS(varyingsType, inputMesh, inputPass);
}
#else // _WRITE_TRANSPARENT_MOTION_VECTOR
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl"
PackedVaryingsType Vert(AttributesMesh inputMesh)
{
VaryingsType varyingsType;
varyingsType.vmesh = VertMesh(inputMesh);
return PackVaryingsType(varyingsType);
}
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
float ApplyChannelAlpha( float alpha)
{
return lerp(1.0, alpha, _ComposerMaskMode);
}
#ifdef UNITY_VIRTUAL_TEXTURING
#define VT_BUFFER_TARGET SV_Target1
#define EXTRA_BUFFER_TARGET SV_Target2
#else
#define EXTRA_BUFFER_TARGET SV_Target1
#endif
void Frag(PackedVaryingsToPS packedInput,
#ifdef OUTPUT_SPLIT_LIGHTING
out float4 outColor : SV_Target0, // outSpecularLighting
#ifdef UNITY_VIRTUAL_TEXTURING
out float4 outVTFeedback : VT_BUFFER_TARGET,
#endif
out float4 outDiffuseLighting : EXTRA_BUFFER_TARGET,
OUTPUT_SSSBUFFER(outSSSBuffer)
#else
out float4 outColor : SV_Target0
#ifdef UNITY_VIRTUAL_TEXTURING
,out float4 outVTFeedback : VT_BUFFER_TARGET
#endif
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
, out float4 outMotionVec : EXTRA_BUFFER_TARGET
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
#endif // OUTPUT_SPLIT_LIGHTING
#ifdef _DEPTHOFFSET_ON
, out float outputDepth : SV_Depth
#endif
)
{
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
// Init outMotionVector here to solve compiler warning (potentially unitialized variable)
// It is init to the value of forceNoMotion (with 2.0)
outMotionVec = float4(2.0, 0.0, 0.0, 0.0);
#endif
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput);
FragInputs input = UnpackVaryingsMeshToFragInputs(packedInput.vmesh);
#if defined(PLATFORM_SUPPORTS_PRIMITIVE_ID_IN_PIXEL_SHADER) && SHADER_STAGE_FRAGMENT
#if (defined(VARYINGS_NEED_PRIMITIVEID) || (SHADERPASS == SHADERPASS_FULL_SCREEN_DEBUG))
input.primitiveID = packedInput.primitiveID;
#endif
#endif
#if defined(VARYINGS_NEED_CULLFACE) && SHADER_STAGE_FRAGMENT
input.isFrontFace = IS_FRONT_VFACE(packedInput.cullFace, true, false);
#endif
float4 UV0 = input.texCoord0;
UTSData utsData;
// We need to readapt the SS position as our screen space positions are for a low res buffer, but we try to access a full res buffer.
input.positionSS.xy = _OffScreenRendering > 0 ? (input.positionSS.xy * _OffScreenDownsampleFactor) : input.positionSS.xy;
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
// input.positionSS is SV_Position
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);
#ifdef VARYINGS_NEED_POSITION_WS
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
#ifdef MATERIAL_TYPE_EYE
// Must have view Dir to work
float2 viewT = TransformObjectToTangent(V, input.tangentToWorld);
float2 parallaxOffset = viewT;
parallaxOffset.y = -parallaxOffset.y;
UV0.xy = clamp(UV0.xy -_EyeParallaxAmount * parallaxOffset, 0, 1);
#endif
#else
// Unused
float3 V = float3(1.0, 1.0, 1.0); // Avoid the division by 0
#endif
#ifdef _SURFACE_TYPE_TRANSPARENT
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_TRANSPARENT;
#else
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_OPAQUE;
#endif
SurfaceData tempSurfaceData;
BuiltinData builtinData;
GetSurfaceAndBuiltinData(input, V, posInput, tempSurfaceData, builtinData);
UTSSurfaceData surfaceData = GetUTSSurfaceData(input, V);
UtsBSDFData bsdfData = ConvertUTSSurfaceDataToUTSBSDFData(surfaceData);
#define UNITY_PROJ_COORD(a) a
#define UNITY_SAMPLE_SCREEN_SHADOW(tex, uv) tex2Dproj( tex, UNITY_PROJ_COORD(uv) ).r
float inverseClipping = 0.0;
LightLoopContext context;
context.shadowContext = InitShadowContext();
context.shadowValue = 1;
context.sampleReflection = 0.0;
#if UNITY_VERSION >= 202120 && UNITY_VERSION < 202320
context.splineVisibility = -1;
#endif
#ifdef APPLY_FOG_ON_SKY_REFLECTIONS
context.positionWS = posInput.positionWS;
#endif
// With XR single-pass and camera-relative: offset position to do lighting computations from the combined center view (original camera matrix).
// This is required because there is only one list of lights generated on the CPU. Shadows are also generated once and shared between the instanced views.
ApplyCameraRelativeXR(posInput.positionWS);
// Initialize the contactShadow and contactShadowFade fields
InitContactShadow(posInput, context);
float channelAlpha = 0.0f;
LightLoopOutput lightLoopOutput;
ZERO_INITIALIZE(LightLoopOutput, lightLoopOutput);
UtsLightLoop(input, posInput, bsdfData, builtinData, V, featureFlags, lightLoopOutput);
/*
#ifdef _EMISSIVE_SIMPLE
float4 _Emissive_Tex_var = tex2D(_Emissive_Tex, TRANSFORM_TEX(UV0, _Emissive_Tex));
float emissiveMask = _Emissive_Tex_var.a;
emissive = _Emissive_Tex_var.rgb * _Emissive_Color.rgb * emissiveMask;
#elif _EMISSIVE_ANIMATION
//v.2.0.7 Calculation View Coord UV for Scroll
float3 viewNormal_Emissive = (mul(UNITY_MATRIX_V, float4(i_normalDir, 0))).xyz;
float3 NormalBlend_Emissive_Detail = viewNormal_Emissive * float3(-1, -1, 1);
float3 NormalBlend_Emissive_Base = (mul(UNITY_MATRIX_V, float4(utsData.viewDirection, 0)).xyz * float3(-1, -1, 1)) + float3(0, 0, 1);
float3 noSknewViewNormal_Emissive = NormalBlend_Emissive_Base * dot(NormalBlend_Emissive_Base, NormalBlend_Emissive_Detail) / NormalBlend_Emissive_Base.z - NormalBlend_Emissive_Detail;
float2 _ViewNormalAsEmissiveUV = noSknewViewNormal_Emissive.xy * 0.5 + 0.5;
float2 _ViewCoord_UV = RotateUV(_ViewNormalAsEmissiveUV, -(utsData.cameraDir * utsData.cameraRoll), float2(0.5, 0.5), 1.0);
//Invert if it's "inside the mirror".
if (utsData.signMirror < 0) {
_ViewCoord_UV.x = 1 - _ViewCoord_UV.x;
}
else {
_ViewCoord_UV = _ViewCoord_UV;
}
float2 emissive_uv = lerp(UV0, _ViewCoord_UV, _Is_ViewCoord_Scroll);
//
float4 _time_var = _Time;
float _base_Speed_var = (_time_var.g * _Base_Speed);
float _Is_PingPong_Base_var = lerp(_base_Speed_var, sin(_base_Speed_var), _Is_PingPong_Base);
float2 scrolledUV = emissive_uv + float2(_Scroll_EmissiveU, _Scroll_EmissiveV) * _Is_PingPong_Base_var;
float rotateVelocity = _Rotate_EmissiveUV * 3.141592654;
float2 _rotate_EmissiveUV_var = RotateUV(scrolledUV, rotateVelocity, float2(0.5, 0.5), _Is_PingPong_Base_var);
float4 _Emissive_Tex_var = tex2D(_Emissive_Tex, TRANSFORM_TEX(UV0, _Emissive_Tex));
float emissiveMask = _Emissive_Tex_var.a;
_Emissive_Tex_var = tex2D(_Emissive_Tex, TRANSFORM_TEX(_rotate_EmissiveUV_var, _Emissive_Tex));
float _colorShift_Speed_var = 1.0 - cos(_time_var.g * _ColorShift_Speed);
float viewShift_var = smoothstep(0.0, 1.0, max(0, dot(utsData.normalDirection, utsData.viewDirection)));
float4 colorShift_Color = lerp(_Emissive_Color, lerp(_Emissive_Color, _ColorShift, _colorShift_Speed_var), _Is_ColorShift);
float4 viewShift_Color = lerp(_ViewShift, colorShift_Color, viewShift_var);
float4 emissive_Color = lerp(colorShift_Color, viewShift_Color, _Is_ViewShift);
emissive = emissive_Color.rgb * _Emissive_Tex_var.rgb * emissiveMask;
//
//v.2.0.6: GI_Intensity with Intensity Multiplier Filter
#endif
*/
// We directly calculate custome main light during the light loop in upper code to avoid extra calculation
//customMainLight = GetCustomMainLightData(builtinData, mainPunctualLight);
/*
#if _SHADOW_MODE_SDF || (_RECEIVE_HAIR_SHADOW_ON && ENABLE_UTS_HAIR_SHAOW)
float3 defaultLightDirection = normalize(UNITY_MATRIX_V[2].xyz + UNITY_MATRIX_V[1].xyz);
float3 defaultLightColor = saturate(max(float3(0.05, 0.05, 0.05) * _Unlit_Intensity, max(ShadeSH9(float4(0.0, 0.0, 0.0, 1.0)), ShadeSH9(float4(0.0, -1.0, 0.0, 1.0)).rgb) * _Unlit_Intensity));
float3 customLightDirection = normalize(mul(UNITY_MATRIX_M, float4(((float3(1.0, 0.0, 0.0) * _Offset_X_Axis_BLD * 10) + (float3(0.0, 1.0, 0.0) * _Offset_Y_Axis_BLD * 10) + (float3(0.0, 0.0, -1.0) * lerp(-1.0, 1.0, _Inverse_Z_Axis_BLD))), 0)).xyz);
float3 lightDirection = normalize(lerp(defaultLightDirection, customMainLight.lightDirection.xyz, any(customMainLight.lightDirection.xyz)));
lightDirection = lerp(lightDirection, customLightDirection, _Is_BLD);
float3 originalLightColor = customMainLight.lightColor.rgb;
originalLightColor = lerp(originalLightColor, clamp(originalLightColor, ConvertFromEV100(_ToonEvAdjustmentValueMin ), ConvertFromEV100(_ToonEvAdjustmentValueMax)), _ToonEvAdjustmentCurve) * _Light_Intensity_Multiplier;
float3 lightColor = lerp(max(defaultLightColor, originalLightColor), max(defaultLightColor, saturate(originalLightColor)), max(_Is_Filter_LightColor, _ToonLightHiCutFilter));
float4 _1st_ShadeMap_var = lerp(SAMPLE_TEXTURE2D(_1st_ShadeMap, sampler_BaseColorMap,TRANSFORM_TEX(UV0, _1st_ShadeMap)), _MainTex_var, _Use_BaseAs1st);
float3 _1st_Shade_var = lerp((_1st_ShadeMap_var.rgb * _1st_ShadeColor.rgb), ((_1st_ShadeMap_var.rgb * _1st_ShadeColor.rgb) * lightColor), _Is_LightColor_1st_Shade);
float systemShadowValue = lerp(1.0f, saturate(customMainLight.shadowValue * 2.0f), _Set_SystemShadowsToBase);
#endif
#if _SHADOW_MODE_SDF
// modified by Suomi @ 20230902 - SDFResult is used to sample SDF texture on the correct side
float angle;
bool rightside;
float2 SDF_UV = TRANSFORM_TEX(UV0, _BaseColorMap);
float4 sdfRes = SDFResult(rightside, angle, customMainLight.lightDirection, SDF_UV);
float sdfShadowValue = 1.0f - SDFMask(angle, sdfRes.r);
utsAggregateLighting.directDiffuse = lerp(_1st_Shade_var, bsdfData.diffuseColor * _BaseColor.rgb * lightColor, sdfShadowValue * systemShadowValue);
utsAggregateLighting.directSpecular = lerp(0, utsAggregateLighting.directSpecular, sdfShadowValue * systemShadowValue);
utsAggregateLighting.directSpecular += _SDFNoseHighlightCoef * SDFNoseHighlight(angle, sdfRes.g, rightside, SDF_UV) * lightColor;
#endif
#if _RECEIVE_HAIR_SHADOW_ON && ENABLE_UTS_HAIR_SHAOW
// 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)));
float3 viewLightDir = TransformWorldToViewDir(customMainLight.lightDirection); // / 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 = (input.positionSS.xy + 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 depthCorrect = 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.
float hairShadow = lerp(0,hairShadowOpacity,depthCorrect);
utsAggregateLighting.directDiffuse = lerp(utsAggregateLighting.directDiffuse, _1st_Shade_var, hairShadow * systemShadowValue);
utsAggregateLighting.directSpecular = lerp(utsAggregateLighting.directSpecular, 0, hairShadow * systemShadowValue);
#endif
*/
//outColor.rgb = lightLoopOutput.diffuseLighting + lightLoopOutput.specularLighting;
//outColor.a = 1.0;
//return;
float3 finalColor = lightLoopOutput.diffuseLighting + lightLoopOutput.specularLighting;
#ifdef _IS_TRANSCLIPPING_OFF
outColor = float4(finalColor, 1 * ApplyChannelAlpha(channelAlpha));
#elif _IS_TRANSCLIPPING_ON
float Set_Opacity = saturate((inverseClipping + _Tweak_transparency));
outColor = EvaluateAtmosphericScattering(posInput, V, float4(finalColor, 1));
outColor = float4(outColor.rgb, Set_Opacity * ApplyChannelAlpha(channelAlpha));
#endif
#if MATERIAL_TYPE_FRONT_HAIR && ENABLE_UTS_HAIR_BLENDING
float2 screenUV = posInput.positionNDC * _HairBlendingRTHandleScale.xy;
float4 hairBlendingMap = SAMPLE_TEXTURE2D(_HairBlendingTex, s_trilinear_clamp_sampler, screenUV);
outColor.rgb = lerp(outColor.rgb, hairBlendingMap.rgb, hairBlendingMap.a * _HairBlendingFactor);
#endif
#if UTS_DEBUG_SHADOWMAP || UTS_DEBUG_SELFSHADOW
outColor.rgb = 1;
#ifdef UTS_DEBUG_SELFSHADOW
outColor.rgb = min(finalColor, outColor.rgb);
#endif
#ifdef UTS_DEBUG_SHADOWMAP
#ifdef UTS_DEBUG_SHADOWMAP_BINALIZATION
outColor.rgb = min(context.shadowValue < 0.9f ? clamp(context.shadowValue - 0.2, 0.0, 0.9) : 1.0f, outColor.rgb);
#else
outColor.rgb = min(context.shadowValue, outColor.rgb);
#endif
#endif // ifdef UTS_DEBUG_SHADOWMAP
#endif // defined(UTS_DEBUG_SHADOWMAP) || defined(UTS_DEBUG_SELFSHADOW)
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.deviceDepth;
#endif
#ifdef UNITY_VIRTUAL_TEXTURING
outVTFeedback = builtinData.vtPackedFeedback;
#endif
}

View File

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