13 Commits

Author SHA1 Message Date
Misaki
9f86d53804 Update the version to 2.0.5 2025-01-08 23:12:47 +09:00
Misaki
968b83870f Removed the dependency of layer mask of hair shadow caster;
Added HairShadowCaster pass;
2025-01-08 23:09:55 +09:00
Misaki
a7a9ad16b5 Updated namespace;
Added UTSPass;
Chnaged the RTHanlde _HairShadowMap to not reallocate when screen resolution decreased;
2025-01-08 22:19:04 +09:00
Misaki
23862b4380 Merge branch 'main' of https://git.personalnas.com/Misaki/com.misaki.hdrp-toon 2024-12-26 16:17:27 +09:00
Misaki
1d2a815803 Merge branch 'main' of https://git.personalnas.com/Misaki/com.misaki.hdrp-toon 2024-12-26 16:17:22 +09:00
Misaki
e91a602add Merge branch 'main' of https://git.personalnas.com/Misaki/com.misaki.hdrp-toon 2024-12-26 16:14:49 +09:00
Misaki
eda516fdab Fixed README assets missing; 2024-12-26 16:14:36 +09:00
Misaki
d33d3f2bb7 Fixed README assets missing; 2024-12-26 16:13:19 +09:00
Misaki
48bbf1fa20 Update README and CHANGELOG; 2024-12-26 16:10:14 +09:00
Misaki
60631f558f Removed the dependency of RenderingLayerMask in UTSOutlinePass; 2024-11-20 17:01:24 +09:00
Misaki
52469649de Fixed the bug from shader gui drawer : [Worker0] Failed to create MaterialEnum, enum UnityEditor.Rendering.HighDefinition.TransparentCullMode not found;
Fixed the bug that outline does not rendering when material type is set to transparent;
Fixed the bug that hair shadow buffer does not rendering the object that material type is set to transparent;
2024-11-19 00:26:28 +09:00
Misaki
1b47306585 Changed the defualt UTS rendering settings location; 2024-11-18 23:53:13 +09:00
Misaki
bd7804395d Updated changed log 2024-11-18 23:16:18 +09:00
44 changed files with 774 additions and 947 deletions

54
CHANGELOG.md Normal file
View File

@@ -0,0 +1,54 @@
# Changelog
All notable changes to this project will be documented in this file.
## [2.0.5] - 08-Jan-2025
### Added
- Added UTSPass custom pass;
- Added HairShadowCaster shader pass;
### Changed
- Chnaged the RTHanlde _HairShadowMap to not reallocate when screen resolution decreased;
- Changed namespace;
- Removed the dependency of layer mask of hair shadow caster;
## [2.0.2] - 26-Dec-2024
### Changed
- Changed the defualt UTS rendering settings location;
- Removed the dependency of RenderingLayerMask in UTSOutlinePass;
### Fixed
- Fixed the bug from shader gui drawer : [Worker0] Failed to create MaterialEnum, enum UnityEditor.Rendering.HighDefinition.TransparentCullMode not found;
- Fixed the bug that outline does not rendering when material type is set to transparent;
- Fixed the bug that hair shadow buffer does not rendering the object that material type is set to transparent;
---
## [2.0.1] - 11-Nov-2024
### Added
- Added custom editor for BoxLightAdjustment;
### Changed
- Changed the outline layer and hair shadow caster layer from LayerMask to RenderingLayerMask;
- Changed the RenderingLayerMask update from every frame to when property changed;
- Chnaged the light following calculation from Update to LateUpdate;
---
## [2.0.0] - 23-Oct-2024
### Added
- Added the support of HDRP 17;
### Changed
- Changed GameObject custom pass to global custom pass;
### Fixed
- Fixed dependency problem in package.json file;
### Removed
- Removed HairShaodwPassDrawer;
- Removed UTSOutLinePassDrawer;

View File

@@ -1,8 +1,7 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 37f2c2f5a413a874b9ec560b74248a71 guid: f6d3b51789082774690f2051bbca2438
NativeFormatImporter: TextScriptImporter:
externalObjects: {} externalObjects: {}
mainObjectFileID: 11400000
userData: userData:
assetBundleName: assetBundleName:
assetBundleVariant: assetBundleVariant:

View File

@@ -1,13 +1,10 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor; using UnityEditor;
using Unity.Rendering.Toon;
namespace UnityEditor.Rendering.Toon namespace Misaki.HdrpToon.Editor
{ {
[CustomEditor(typeof(DebugShadowmap))] [CustomEditor(typeof(DebugShadowmap))]
internal class DebugShadowmapInspector : Editor internal class DebugShadowmapInspector : UnityEditor.Editor
{ {
public override void OnInspectorGUI() public override void OnInspectorGUI()
@@ -19,14 +16,14 @@ namespace UnityEditor.Rendering.Toon
bool isChanged = false; var isChanged = false;
var obj = target as DebugShadowmap; var obj = target as DebugShadowmap;
// hi cut filter // hi cut filter
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
bool showShadow = EditorGUILayout.Toggle(labelDebugShadowmap, obj.m_enableShadowmapDebugging); var showShadow = EditorGUILayout.Toggle(labelDebugShadowmap, obj.m_enableShadowmapDebugging);
if (EditorGUI.EndChangeCheck()) if (EditorGUI.EndChangeCheck())
{ {
Undo.RecordObject(target, "Changed Shadowmap debbuging flag"); Undo.RecordObject(target, "Changed Shadowmap debbuging flag");
@@ -41,7 +38,7 @@ namespace UnityEditor.Rendering.Toon
EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
bool binalization = EditorGUILayout.Toggle(labelBinalization, obj.m_enableBinalization); var binalization = EditorGUILayout.Toggle(labelBinalization, obj.m_enableBinalization);
if (EditorGUI.EndChangeCheck()) if (EditorGUI.EndChangeCheck())
{ {
@@ -59,7 +56,7 @@ namespace UnityEditor.Rendering.Toon
EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
bool showSlefShadow = EditorGUILayout.Toggle(labelDebugSelfShadow, obj.m_enableSelfShadowDebugging); var showSlefShadow = EditorGUILayout.Toggle(labelDebugSelfShadow, obj.m_enableSelfShadowDebugging);
if (EditorGUI.EndChangeCheck()) if (EditorGUI.EndChangeCheck())
{ {
@@ -72,7 +69,7 @@ namespace UnityEditor.Rendering.Toon
EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
bool showOutline = EditorGUILayout.Toggle(labelNoOutline, obj.m_enableOutlineDebugging); var showOutline = EditorGUILayout.Toggle(labelNoOutline, obj.m_enableOutlineDebugging);
if (EditorGUI.EndChangeCheck()) if (EditorGUI.EndChangeCheck())
{ {

View File

@@ -3,7 +3,7 @@ using UnityEditor;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements; using UnityEngine.UIElements;
namespace Unity.Toonshader.Editor namespace Misaki.HdrpToon.Editor
{ {
public class ConverterInitializer public class ConverterInitializer
{ {

View File

@@ -1,6 +1,6 @@
using UnityEngine; using UnityEngine;
namespace Unity.Toonshader.Editor namespace Misaki.HdrpToon.Editor
{ {
public struct QuaternionToVector3Converter public struct QuaternionToVector3Converter
{ {

View File

@@ -1,13 +1,11 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor; using UnityEditor;
using Unity.Rendering.Toon; using UnityEngine;
namespace UnityEditor.Rendering.Toon
namespace Misaki.HdrpToon.Editor
{ {
[CustomEditor(typeof(ModelToonEvAdjustment))] [CustomEditor(typeof(ModelToonEvAdjustment))]
internal class ModelToonEvAdjustmentInspector : Editor internal class ModelToonEvAdjustmentInspector : UnityEditor.Editor
{ {
SerializedObject m_SerializedObject; SerializedObject m_SerializedObject;
@@ -20,14 +18,14 @@ namespace UnityEditor.Rendering.Toon
const string labeIgnoreVolumeExposure = "Ignore Volume Exposure"; const string labeIgnoreVolumeExposure = "Ignore Volume Exposure";
const string labelCompensation = "Compensation"; const string labelCompensation = "Compensation";
bool isChanged = false; var isChanged = false;
var obj = target as ModelToonEvAdjustment; var obj = target as ModelToonEvAdjustment;
// hi cut filter // hi cut filter
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
bool egnoreExposure = EditorGUILayout.Toggle(labeIgnoreVolumeExposure, obj.m_IgnorVolumeExposure); var egnoreExposure = EditorGUILayout.Toggle(labeIgnoreVolumeExposure, obj.m_IgnorVolumeExposure);
if (EditorGUI.EndChangeCheck()) if (EditorGUI.EndChangeCheck())
{ {
Undo.RecordObject(target, "Changed Ignore Volume Exposure"); Undo.RecordObject(target, "Changed Ignore Volume Exposure");
@@ -38,7 +36,7 @@ namespace UnityEditor.Rendering.Toon
// hi cut filter // hi cut filter
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
bool lightFilterr = EditorGUILayout.Toggle(labelLightHighCutFilter, obj.m_ToonLightHiCutFilter); var lightFilterr = EditorGUILayout.Toggle(labelLightHighCutFilter, obj.m_ToonLightHiCutFilter);
if (EditorGUI.EndChangeCheck()) if (EditorGUI.EndChangeCheck())
{ {
Undo.RecordObject(target, "Changed Light Hi Cut Filter"); Undo.RecordObject(target, "Changed Light Hi Cut Filter");
@@ -50,7 +48,7 @@ namespace UnityEditor.Rendering.Toon
// Compensation // Compensation
EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
float compensation = EditorGUILayout.FloatField(labelCompensation, obj.m_Compensation); var compensation = EditorGUILayout.FloatField(labelCompensation, obj.m_Compensation);
if (EditorGUI.EndChangeCheck()) if (EditorGUI.EndChangeCheck())
{ {
Undo.RecordObject(target, "Changed Compensation"); Undo.RecordObject(target, "Changed Compensation");
@@ -62,7 +60,7 @@ namespace UnityEditor.Rendering.Toon
// curve // curve
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
bool exposureAdjustment = EditorGUILayout.Toggle(labelLightAdjustment, obj.m_ExposureAdjustmnt); var exposureAdjustment = EditorGUILayout.Toggle(labelLightAdjustment, obj.m_ExposureAdjustmnt);
if (EditorGUI.EndChangeCheck()) if (EditorGUI.EndChangeCheck())
{ {
Undo.RecordObject(target, "Changed Expsure Adjustment"); Undo.RecordObject(target, "Changed Expsure Adjustment");
@@ -82,7 +80,7 @@ namespace UnityEditor.Rendering.Toon
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
// var ranges = new Rect(-10, -10, 20, 20); // var ranges = new Rect(-10, -10, 20, 20);
// var curve = EditorGUILayout.CurveField(labelExposureCurave, obj.m_AnimationCurve, Color.green,ranges); // var curve = EditorGUILayout.CurveField(labelExposureCurave, obj.m_AnimationCurve, Color.green,ranges);
AnimationCurve curve = EditorGUILayout.CurveField(labelLightAdjustmentCurve, obj.m_AnimationCurve); var curve = EditorGUILayout.CurveField(labelLightAdjustmentCurve, obj.m_AnimationCurve);
if (EditorGUI.EndChangeCheck()) if (EditorGUI.EndChangeCheck())
{ {
@@ -91,7 +89,7 @@ namespace UnityEditor.Rendering.Toon
isChanged = true; isChanged = true;
} }
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
bool buttonIsPressed = GUILayout.Button("Reset", GUILayout.Width(50)); var buttonIsPressed = GUILayout.Button("Reset", GUILayout.Width(50));
var curve2 = obj.m_AnimationCurve; var curve2 = obj.m_AnimationCurve;
if (buttonIsPressed) if (buttonIsPressed)
{ {
@@ -134,7 +132,7 @@ namespace UnityEditor.Rendering.Toon
float ConvertFromEV100(float EV100) float ConvertFromEV100(float EV100)
{ {
float val = Mathf.Pow(2, EV100) * 2.5f; var val = Mathf.Pow(2, EV100) * 2.5f;
return val; return val;
} }

View File

@@ -1,9 +1,8 @@
using Unity.Rendering.HighDefinition.Toon;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements; using UnityEngine.UIElements;
namespace Unity.Toonshader.Editor namespace Misaki.HdrpToon.Editor
{ {
[CustomEditor(typeof(BoxLightAdjustment))] [CustomEditor(typeof(BoxLightAdjustment))]
public class BoxLightAdjustmentView : UnityEditor.Editor public class BoxLightAdjustmentView : UnityEditor.Editor
@@ -18,8 +17,6 @@ namespace Unity.Toonshader.Editor
return base.CreateInspectorGUI(); return base.CreateInspectorGUI();
} }
var boxLightAdjustment = (BoxLightAdjustment)target;
var root = new VisualElement var root = new VisualElement
{ {
dataSource = target dataSource = target

View File

@@ -1,6 +1,7 @@
//#define USE_SIMPLE_UI //#define USE_SIMPLE_UI
using Misaki.HdrpToon;
using System; using System;
using UnityEngine; using UnityEngine;
using UnityEngine.Rendering; using UnityEngine.Rendering;
@@ -51,24 +52,6 @@ namespace UnityEditor.Rendering.Toon
} }
} }
internal static string OutlineLightingModeName
{
get
{
const string legacyDefaultLightModeName = "Always";
const string OutlineLightingModeName = "Outline";
if (currentRenderPipeline == RenderPipeline.Legacy)
{
return legacyDefaultLightModeName; // default.
}
return OutlineLightingModeName;
}
}
internal void RenderingPerChennelsSetting(Material material) internal void RenderingPerChennelsSetting(Material material)
{ {
if (currentRenderPipeline == RenderPipeline.HDRP) if (currentRenderPipeline == RenderPipeline.HDRP)
@@ -121,6 +104,12 @@ namespace UnityEditor.Rendering.Toon
internal const string ShaderProp_OutlineTex = "_OutlineTex"; internal const string ShaderProp_OutlineTex = "_OutlineTex";
internal const string ShaderProp_Outline_Sampler = "_Outline_Sampler"; internal const string ShaderProp_Outline_Sampler = "_Outline_Sampler";
internal const string ShaderPropCastHairShadow = "_Is_CastHairShadow";
internal const string ShaderPropReceiveHairShadow = "_Is_ReceiveHairShadow";
internal const string ShaderPropEyeParallax = "_Is_EyeParallax";
internal const string ShaderPropEyebrowSeethrough = "_Is_EyebrowSeethrough";
internal const string ShaderPropSimpleUI = "_simpleUI"; internal const string ShaderPropSimpleUI = "_simpleUI";
internal const string ShaderPropAutoRenderQueue = "_AutoRenderQueue"; internal const string ShaderPropAutoRenderQueue = "_AutoRenderQueue";
internal const string ShaderPropStencilMode = "_StencilMode"; internal const string ShaderPropStencilMode = "_StencilMode";
@@ -216,17 +205,13 @@ namespace UnityEditor.Rendering.Toon
internal const string ShaderDefineIS_CLIPPING_MATTE = "_IS_CLIPPING_MATTE"; internal const string ShaderDefineIS_CLIPPING_MATTE = "_IS_CLIPPING_MATTE";
internal const string ShaderPropReceiveHairShadow = "_Is_ReceiveHairShadow";
internal const string ShaderPropEyeParallax = "_Is_EyeParallax";
internal const string ShaderPropEyebrowSeethrough = "_Is_EyebrowSeethrough";
protected readonly string[] UtsModeNames = { "Standard", "PBR" }; protected readonly string[] UtsModeNames = { "Standard", "PBR" };
protected readonly string[] EmissiveScrollMode = { "UV Coordinate Scroll", "View Coordinate Scroll" }; protected readonly string[] EmissiveScrollMode = { "UV Coordinate Scroll", "View Coordinate Scroll" };
protected readonly string[] ClippingModeNames = { "Off", "On", "Clip Transparency" }; protected readonly string[] ClippingModeNames = { "Off", "On", "Clip Transparency" };
protected readonly string[] StencilModeNames = { "Off", "Draw If Not Equal to", "Replace Stencil Buffer with" }; protected readonly string[] StencilModeNames = { "Off", "Draw If Not Equal to", "Replace Stencil Buffer with" };
protected readonly string[] ZTestModeNames = { "Disabled", "Never", "Less", "Equal", "LessEqual", "Greater", "NotEqual", "GreaterEqual", "Always" }; protected readonly string[] ZTestModeNames = { "Disabled", "Never", "Less", "Equal", "LessEqual", "Greater", "NotEqual", "GreaterEqual", "Always" };
protected readonly string[] PbrModeDefines = { "_PBR_Mode_OFF", "_PBR_Mode_ST", "_PBR_Mode_ANISO", "_PBR_Mode_KK", "_PBR_Mode_TOON" };
public enum UTS_ClippingMode public enum UTS_ClippingMode
{ {
@@ -699,7 +684,8 @@ namespace UnityEditor.Rendering.Toon
public static readonly GUIContent highlightOnShadowText = new GUIContent("Highlight Blending on Shadows", "Control the blending for the highlights in shadows, this also control the rim light."); public static readonly GUIContent highlightOnShadowText = new GUIContent("Highlight Blending on Shadows", "Control the blending for the highlights in shadows, this also control the rim light.");
public static readonly GUIContent lightColorEffectiveness = EditorGUIUtility.TrTextContent("Light Color Effectiveness", "light color effectiveness to each parameter."); public static readonly GUIContent lightColorEffectiveness = EditorGUIUtility.TrTextContent("Light Color Effectiveness", "light color effectiveness to each parameter.");
public static readonly GUIContent receiveHairShadowText = new GUIContent("Receive Hair Shadow", "Do you want this material to receive hair shadow"); public static readonly GUIContent hairShadowCasterText = new GUIContent("Hair Shadow Caster", "Enable to cast hair shadow");
public static readonly GUIContent receiveHairShadowText = new GUIContent("Receive Hair Shadow", "Enable to receive shadow from hair shadow caster");
public static readonly GUIContent eyeParallaxText = new GUIContent("Eye Parallax Correction", "Enables parallax correction for eye material"); public static readonly GUIContent eyeParallaxText = new GUIContent("Eye Parallax Correction", "Enables parallax correction for eye material");
public static readonly GUIContent eyebrowSeethroughText = new GUIContent("Eyebrow Seethrough", "Enable for eyebrow material to be blended with hair. Must configure HairShadowPass to work."); public static readonly GUIContent eyebrowSeethroughText = new GUIContent("Eyebrow Seethrough", "Enable for eyebrow material to be blended with hair. Must configure HairShadowPass to work.");
@@ -1012,17 +998,6 @@ namespace UnityEditor.Rendering.Toon
} }
// -------------------------------- // --------------------------------
public UTS3GUI()
{
}
public override void OnClosed(Material material)
{
base.OnClosed(material);
}
void OnOpenGUI(Material material, MaterialEditor materialEditor, MaterialProperty[] props) void OnOpenGUI(Material material, MaterialEditor materialEditor, MaterialProperty[] props)
{ {
m_MaterialScopeList.RegisterHeaderScope(Styles.shaderFoldout, Expandable.Shader, DrawShaderOptions, (uint)UTS_TransparentMode.Off, isTessellation: 0); m_MaterialScopeList.RegisterHeaderScope(Styles.shaderFoldout, Expandable.Shader, DrawShaderOptions, (uint)UTS_TransparentMode.Off, isTessellation: 0);
@@ -1199,7 +1174,7 @@ namespace UnityEditor.Rendering.Toon
EditorGUILayout.Space(10); EditorGUILayout.Space(10);
var headerStyle = new GUIStyle() { fontSize = 25, fontStyle = FontStyle.Bold, alignment = TextAnchor.MiddleCenter }; var headerStyle = new GUIStyle() { fontSize = 25, fontStyle = FontStyle.Bold, alignment = TextAnchor.MiddleCenter };
headerStyle.normal.textColor = GUI.skin.label.normal.textColor; headerStyle.normal.textColor = GUI.skin.label.normal.textColor;
EditorGUILayout.LabelField("Unity Toon Shader", headerStyle); EditorGUILayout.LabelField("HDRP Toon Shader", headerStyle);
EditorGUILayout.Space(20); EditorGUILayout.Space(20);
if (transparencyEnabled != UTS_TransparentMode.On) if (transparencyEnabled != UTS_TransparentMode.On)
@@ -1383,22 +1358,8 @@ namespace UnityEditor.Rendering.Toon
//If the value changes, write to the material. //If the value changes, write to the material.
if (_CullMode_Setting != (int)m_cullingMode) if (_CullMode_Setting != (int)m_cullingMode)
{ {
switch (m_cullingMode) MaterialSetInt(material, _CullMode, (int)m_cullingMode);
{
case CullingMode.Off:
MaterialSetInt(material, _CullMode, 0);
break;
case CullingMode.Frontface:
MaterialSetInt(material, _CullMode, 1);
break;
default:
MaterialSetInt(material, _CullMode, 2);
break;
} }
}
} }
void GUI_Tranparent(Material material) void GUI_Tranparent(Material material)
{ {
@@ -1559,17 +1520,14 @@ namespace UnityEditor.Rendering.Toon
void GUI_HairShadow(Material material) void GUI_HairShadow(Material material)
{ {
var isEnabled = GUI_Toggle(material, Styles.receiveHairShadowText, ShaderPropReceiveHairShadow, var isCastEnable = GUI_Toggle(material, Styles.hairShadowCasterText, ShaderPropCastHairShadow,
MaterialGetInt(material, ShaderPropCastHairShadow) != 0);
var isReceiveEnabled = GUI_Toggle(material, Styles.receiveHairShadowText, ShaderPropReceiveHairShadow,
MaterialGetInt(material, ShaderPropReceiveHairShadow) != 0); MaterialGetInt(material, ShaderPropReceiveHairShadow) != 0);
if (isEnabled) material.SetShaderPassEnabled(UtsShaderPassName.HAIR_SHADOW_CASTER_PASS_NAME, isCastEnable);
{ material.SetKeyword(new LocalKeyword(material.shader, "_RECEIVE_HAIR_SHADOW"), isReceiveEnabled);
material.EnableKeyword(new LocalKeyword(material.shader, "_RECEIVE_HAIR_SHADOW"));
}
else
{
material.DisableKeyword(new LocalKeyword(material.shader, "_RECEIVE_HAIR_SHADOW"));
}
} }
void GUI_EyeParallax(Material material) void GUI_EyeParallax(Material material)
@@ -1718,64 +1676,23 @@ namespace UnityEditor.Rendering.Toon
m_pbrMode = (PBRMode)EditorGUILayout.EnumPopup(Styles.pbrModeText, m_pbrMode); m_pbrMode = (PBRMode)EditorGUILayout.EnumPopup(Styles.pbrModeText, m_pbrMode);
EditorGUILayout.Space(); EditorGUILayout.Space();
switch (m_pbrMode) void SwitchPbrMode(string targetMode)
{ {
case PBRMode.Off: foreach (var pbrMode in PbrModeDefines)
{ {
material.SetFloat(ShaderPropPBR, (int)PBRMode.Off); if (targetMode == pbrMode)
{
material.EnableKeyword(pbrMode);
}
else
{
material.DisableKeyword(pbrMode);
}
}
}
material.EnableKeyword("_PBR_Mode_OFF"); material.SetFloat(ShaderPropPBR, (int)m_pbrMode);
material.DisableKeyword("_PBR_Mode_ST"); SwitchPbrMode(PbrModeDefines[(int)m_pbrMode]);
material.DisableKeyword("_PBR_Mode_ANISO");
material.DisableKeyword("_PBR_Mode_KK");
material.DisableKeyword("_PBR_Mode_TOON");
}
break;
case PBRMode.Standard:
{
material.SetFloat(ShaderPropPBR, (int)PBRMode.Standard);
material.DisableKeyword("_PBR_Mode_OFF");
material.EnableKeyword("_PBR_Mode_ST");
material.DisableKeyword("_PBR_Mode_ANISO");
material.DisableKeyword("_PBR_Mode_KK");
material.DisableKeyword("_PBR_Mode_TOON");
}
break;
case PBRMode.Anisotropy:
{
material.SetFloat(ShaderPropPBR, (int)PBRMode.Anisotropy);
material.DisableKeyword("_PBR_Mode_OFF");
material.DisableKeyword("_PBR_Mode_ST");
material.EnableKeyword("_PBR_Mode_ANISO");
material.DisableKeyword("_PBR_Mode_KK");
material.DisableKeyword("_PBR_Mode_TOON");
}
break;
case PBRMode.KKHair:
{
material.SetFloat(ShaderPropPBR, (int)PBRMode.KKHair);
material.DisableKeyword("_PBR_Mode_OFF");
material.DisableKeyword("_PBR_Mode_ST");
material.DisableKeyword("_PBR_Mode_ANISO");
material.EnableKeyword("_PBR_Mode_KK");
material.DisableKeyword("_PBR_Mode_TOON");
}
break;
case PBRMode.Toon:
{
material.SetFloat(ShaderPropPBR, (int)PBRMode.Toon);
material.DisableKeyword("_PBR_Mode_OFF");
material.DisableKeyword("_PBR_Mode_ST");
material.DisableKeyword("_PBR_Mode_ANISO");
material.DisableKeyword("_PBR_Mode_KK");
material.EnableKeyword("_PBR_Mode_TOON");
}
break;
}
m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, normalMap, normalScale); m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, normalMap, normalScale);
@@ -2406,18 +2323,18 @@ namespace UnityEditor.Rendering.Toon
internal static void SetupOverDrawTransparentObject(Material material) internal static void SetupOverDrawTransparentObject(Material material)
{ {
var srpDefaultLightModeTag = material.GetTag("LightMode", false, OutlineLightingModeName); var srpDefaultLightModeTag = material.GetTag("LightMode", false, UtsShaderPassName.OUTLINE_PASS_NAME);
if (srpDefaultLightModeTag == OutlineLightingModeName) if (srpDefaultLightModeTag == UtsShaderPassName.OUTLINE_PASS_NAME)
{ {
material.SetShaderPassEnabled(OutlineLightingModeName, true); material.SetShaderPassEnabled(UtsShaderPassName.OUTLINE_PASS_NAME, true);
MaterialSetInt(material, srpDefaultColorMask, 0); MaterialSetInt(material, srpDefaultColorMask, 0);
MaterialSetInt(material, srpDefaultCullMode, (int)CullingMode.Backface); MaterialSetInt(material, srpDefaultCullMode, (int)CullingMode.Backface);
} }
} }
internal static void SetupOutline(Material material) internal static void SetupOutline(Material material)
{ {
var srpDefaultLightModeTag = material.GetTag("LightMode", false, OutlineLightingModeName); var srpDefaultLightModeTag = material.GetTag("LightMode", false, UtsShaderPassName.OUTLINE_PASS_NAME);
if (srpDefaultLightModeTag == OutlineLightingModeName) if (srpDefaultLightModeTag == UtsShaderPassName.OUTLINE_PASS_NAME)
{ {
MaterialSetInt(material, srpDefaultColorMask, 15); MaterialSetInt(material, srpDefaultColorMask, 15);
MaterialSetInt(material, srpDefaultCullMode, (int)CullingMode.Frontface); MaterialSetInt(material, srpDefaultCullMode, (int)CullingMode.Frontface);
@@ -2427,15 +2344,12 @@ namespace UnityEditor.Rendering.Toon
{ {
EditorGUILayout.HelpBox("You need to add OutlinePass in custom pass to make outline work properly", MessageType.Warning); EditorGUILayout.HelpBox("You need to add OutlinePass in custom pass to make outline work properly", MessageType.Warning);
const string kDisableOutlineKeyword = "_DISABLE_OUTLINE"; var srpDefaultLightModeTag = material.GetTag("LightMode", false, UtsShaderPassName.OUTLINE_PASS_NAME);
var isLegacy = (OutlineLightingModeName == "Always");
var srpDefaultLightModeTag = material.GetTag("LightMode", false, OutlineLightingModeName);
var isOutlineEnabled = true; var isOutlineEnabled = true;
if (srpDefaultLightModeTag == OutlineLightingModeName) if (srpDefaultLightModeTag == UtsShaderPassName.OUTLINE_PASS_NAME)
{ {
const string kOutline = "Outline"; const string kOutline = "Outline";
isOutlineEnabled = material.GetShaderPassEnabled(OutlineLightingModeName); isOutlineEnabled = material.GetShaderPassEnabled(UtsShaderPassName.OUTLINE_PASS_NAME);
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
isOutlineEnabled = EditorGUILayout.Toggle(kOutline, isOutlineEnabled); isOutlineEnabled = EditorGUILayout.Toggle(kOutline, isOutlineEnabled);
@@ -2444,20 +2358,11 @@ namespace UnityEditor.Rendering.Toon
m_MaterialEditor.RegisterPropertyChangeUndo(kOutline); m_MaterialEditor.RegisterPropertyChangeUndo(kOutline);
if (isOutlineEnabled) if (isOutlineEnabled)
{ {
if (isLegacy) material.SetShaderPassEnabled(UtsShaderPassName.OUTLINE_PASS_NAME, true);
{
material.DisableKeyword(kDisableOutlineKeyword);
}
material.SetShaderPassEnabled(OutlineLightingModeName, true);
} }
else else
{ {
if (isLegacy) material.SetShaderPassEnabled(UtsShaderPassName.OUTLINE_PASS_NAME, false);
{
material.EnableKeyword(kDisableOutlineKeyword);
}
material.SetShaderPassEnabled(OutlineLightingModeName, false);
} }
} }
} }
@@ -2515,7 +2420,8 @@ namespace UnityEditor.Rendering.Toon
GUI_FloatProperty(material, Styles.nearestDistanceText); GUI_FloatProperty(material, Styles.nearestDistanceText);
EditorGUI.indentLevel--; EditorGUI.indentLevel--;
var useOutlineTexture = GUI_Toggle(material, Styles.outlineColorMapText, ShaderPropIs_OutlineTex, MaterialGetInt(material, ShaderPropIs_OutlineTex) != 0); ; var useOutlineTexture = GUI_Toggle(material, Styles.outlineColorMapText, ShaderPropIs_OutlineTex, MaterialGetInt(material, ShaderPropIs_OutlineTex) != 0);
;
EditorGUI.BeginDisabledGroup(!useOutlineTexture); EditorGUI.BeginDisabledGroup(!useOutlineTexture);
m_MaterialEditor.TexturePropertySingleLine(Styles.outlineTexText, outlineTex); m_MaterialEditor.TexturePropertySingleLine(Styles.outlineTexText, outlineTex);
EditorGUI.EndDisabledGroup(); EditorGUI.EndDisabledGroup();

View File

@@ -1,8 +1,8 @@
{ {
"name": "Unity.Toonshader.Editor", "name": "Misaki.HdrpToon.Editor",
"rootNamespace": "Unity.Toonshader.Editor", "rootNamespace": "Misaki.HdrpToon.Editor",
"references": [ "references": [
"Unity.Toonshader", "Misaki.HdrpToon",
"Unity.RenderPipelines.Core.Runtime", "Unity.RenderPipelines.Core.Runtime",
"Unity.RenderPipelines.Core.Editor", "Unity.RenderPipelines.Core.Editor",
"Unity.RenderPipelines.HighDefinition.Runtime", "Unity.RenderPipelines.HighDefinition.Runtime",

View File

@@ -6,7 +6,7 @@ using UnityEngine;
// Todo: Change this into a editor window // Todo: Change this into a editor window
namespace Unity.Toonshader.Editor namespace Misaki.HdrpToon.Editor
{ {
public class ModelOutlineJobs public class ModelOutlineJobs
{ {

View File

@@ -4,7 +4,7 @@ using UnityEditor.UIElements;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements; using UnityEngine.UIElements;
namespace Unity.Toonshader.Editor namespace Misaki.HdrpToon.Editor
{ {
public class SmoothNormalBakerWindow : EditorWindow public class SmoothNormalBakerWindow : EditorWindow
{ {

View File

@@ -3,14 +3,14 @@ using UnityEditor;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements; using UnityEngine.UIElements;
namespace Unity.Toonshader.Editor namespace Misaki.HdrpToon.Editor
{ {
public class UTSRendererSettingProvider : SettingsProvider public class UTSRendererSettingProvider : SettingsProvider
{ {
class Styles class Styles
{ {
public static GUIContent outline = new GUIContent("Outline Setting"); public static GUIContent outline = new("Outline Setting");
public static GUIContent hairShadow = new GUIContent("Hair Shadow Setting"); public static GUIContent hairShadow = new("Hair Shadow Setting");
} }
private SerializedObject _customSettings; private SerializedObject _customSettings;
@@ -30,12 +30,13 @@ namespace Unity.Toonshader.Editor
EditorGUILayout.PropertyField(_customSettings.FindProperty("outlineSetting"), Styles.outline); EditorGUILayout.PropertyField(_customSettings.FindProperty("outlineSetting"), Styles.outline);
EditorGUILayout.PropertyField(_customSettings.FindProperty("hairShadowSetting"), Styles.hairShadow); EditorGUILayout.PropertyField(_customSettings.FindProperty("hairShadowSetting"), Styles.hairShadow);
_customSettings.ApplyModifiedPropertiesWithoutUndo();
if (EditorGUI.EndChangeCheck()) if (EditorGUI.EndChangeCheck())
{ {
RegisterUTSRenderPass.NotifyRendererSettingChanged(); UTSRenderPassRegistrar.NotifyRendererSettingChanged();
} }
_customSettings.ApplyModifiedPropertiesWithoutUndo();
} }
public static bool IsSettingsAvailable() public static bool IsSettingsAvailable()

View File

@@ -1,3 +1,58 @@
# hdrp-toon # HDRP Toon Shader
A high quality toon shader for High Definition Render Pipeline(HDRP) A high-quality toon shader for the High Definition Render Pipeline (HDRP).
---
## Overview
The HDRP Toon Shader is designed to provide a high-quality toon shading effect for projects using Unity's High Definition Render Pipeline and Unity 6. This shader is ideal for creating stylized, cartoon-like visuals with smooth shading and vibrant colors.
## Docs
[Documentation Page](https://doc.personalnas.com/books/hdrp-toon-documentations)
## Features
- **High-Quality Toon Shading**: Achieve smooth and vibrant toon shading effects.
- **Customizable Parameters**: Easily adjust the shader parameters to fit your artistic needs.
- **HDRP Compatibility**: Fully compatible with Unity's High Definition Render Pipeline, including ray-tracing.
- **Performance Optimized**: Designed to be efficient and performant for real-time applications.
## Pre-Requirements
1. Unity version: 6000.0.27f1 or later
2. HDRP version: 17.0.0 or later
## Installation
1. Open your Unity project.
2. Go to `Window > Package Manager`.
3. Click on the `+` button and select `Add package from git`.
4. In the url input field, type: `https://git.personalnas.com/Misaki/com.misaki.hdrp-toon.git`.
5. Click ok to add package into your project.
## Usage
1. Create a new material in your Unity project.
2. Assign the HDRP Toon Shader to the material.
3. Apply the material to your 3D models.
4. Adjust the shader parameters in the material inspector to achieve the desired look.
## Examples
Here are some examples of the HDRP Toon Shader in action:
![preview-01.png](https://s2.loli.net/2024/12/26/zHdfSXho4csURyx.png)
## Contributing
If you would like to contribute to the development of the HDRP Toon Shader, please follow these steps:
1. Fork the repository.
2. Create a new branch for your feature or bugfix.
3. Commit your changes and push them to your fork.
4. Create a pull request with a description of your changes.
## License
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: b8d9ae1381ecb2141b4a741976d1c827 guid: 6987e5a46707b5240a0ec0d6c7374656
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@@ -0,0 +1,13 @@
using UnityEngine.Rendering;
namespace Misaki.HdrpToon
{
public static class UtsShaderPassName
{
public const string OUTLINE_PASS_NAME = "Outline";
public const string HAIR_SHADOW_CASTER_PASS_NAME = "HairShadowCaster";
public static readonly ShaderTagId outlinePassId = new(OUTLINE_PASS_NAME);
public static readonly ShaderTagId hairShadowCasterPassId = new(HAIR_SHADOW_CASTER_PASS_NAME);
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 8a2b199311606f54a9585b9b3ea31e7d

View File

@@ -2,24 +2,20 @@ using UnityEngine;
#if UNITY_EDITOR #if UNITY_EDITOR
using UnityEditor; using UnityEditor;
#endif #endif
namespace Unity.Rendering.Toon namespace Misaki.HdrpToon
{ {
[ExecuteAlways] [ExecuteAlways]
[DisallowMultipleComponent] [DisallowMultipleComponent]
[RequireComponent(typeof(Camera))] [RequireComponent(typeof(Camera))]
internal class DebugShadowmap : MonoBehaviour public class DebugShadowmap : MonoBehaviour
{ {
// flags // flags
bool m_initialized = false; bool m_initialized = false;
bool m_srpCallbackInitialized = false; bool m_srpCallbackInitialized = false;
[SerializeField] public bool m_enableShadowmapDebugging = false;
internal bool m_enableShadowmapDebugging = false; public bool m_enableSelfShadowDebugging = false;
[SerializeField] public bool m_enableBinalization = false;
internal bool m_enableSelfShadowDebugging = false; public bool m_enableOutlineDebugging = false;
[SerializeField]
internal bool m_enableBinalization = false;
[SerializeField]
internal bool m_enableOutlineDebugging = false;

View File

@@ -7,12 +7,12 @@ using UnityEditor;
using UnityEngine.Rendering.HighDefinition; using UnityEngine.Rendering.HighDefinition;
using Unity.Properties; using Unity.Properties;
namespace Unity.Rendering.HighDefinition.Toon namespace Misaki.HdrpToon
{ {
[ExecuteAlways] [ExecuteAlways]
[DisallowMultipleComponent] [DisallowMultipleComponent]
[RequireComponent(typeof(Light))] [RequireComponent(typeof(Light))]
internal class BoxLightAdjustment : MonoBehaviour public class BoxLightAdjustment : MonoBehaviour
{ {
private bool _initialized = false; private bool _initialized = false;
private bool _srpCallbackInitialized = false; private bool _srpCallbackInitialized = false;

View File

@@ -3,30 +3,32 @@ using System.IO;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
namespace Unity.Toonshader namespace Misaki.HdrpToon
{ {
[Serializable] [Serializable]
public struct UTSOutlineSetting internal struct UTSOutlineSetting
{ {
public bool enable; public bool enable;
public RenderingLayerMask renderingLayer;
} }
[Serializable] [Serializable]
public struct UtsHairShadowSetting internal struct UtsHairShadowSetting
{ {
public bool enable; public bool enable;
public RenderingLayerMask CasterRenderingLayer; public UTSHairShadowPass.ShadowQuality shadowQuality;
} }
[CreateAssetMenu(fileName = "UTSRenderSetting", menuName = "UTS/RenderSetting")] [CreateAssetMenu(fileName = "UTSRenderSetting", menuName = "UTS/RenderSetting")]
public class UTSRenderPassSettings : ScriptableObject public class UTSRenderPassSettings : ScriptableObject
{ {
public const string UTS_RENDERING_SETTINGS_NAME = "UTSRenderingSettings"; public const string UTS_RENDERING_SETTINGS_NAME = "UTSRenderingSettings";
private const string UTS_Rendering_Settings_Path = "Packages/com.misaki.hdrp-toon/Runtime/HDRP/Resources/UTSRenderSettings.asset"; public const string UTS_RENDERING_SETTINGS_PATH = "Assets/Resources/Settings/UTSRenderSettings.asset";
public const string UTS_RENDERING_SETTINGS_RESOURCES_PATH = "Settings/UTSRenderSettings";
public UTSOutlineSetting outlineSetting; [SerializeField]
public UtsHairShadowSetting hairShadowSetting; internal UTSOutlineSetting outlineSetting;
[SerializeField]
internal UtsHairShadowSetting hairShadowSetting;
internal static UTSRenderPassSettings GetOrCreateSettings() internal static UTSRenderPassSettings GetOrCreateSettings()
{ {
@@ -37,21 +39,28 @@ namespace Unity.Toonshader
} }
UTSRenderPassSettings renderingSettings = null; UTSRenderPassSettings renderingSettings = null;
if (File.Exists(UTS_Rendering_Settings_Path)) if (File.Exists(UTS_RENDERING_SETTINGS_PATH))
{ {
renderingSettings = AssetDatabase.LoadAssetAtPath<UTSRenderPassSettings>(UTS_Rendering_Settings_Path); renderingSettings = AssetDatabase.LoadAssetAtPath<UTSRenderPassSettings>(UTS_RENDERING_SETTINGS_PATH);
} }
else else
{ {
renderingSettings = CreateInstance<UTSRenderPassSettings>(); var directory = Path.GetDirectoryName(UTS_RENDERING_SETTINGS_PATH);
AssetDatabase.CreateAsset(renderingSettings, UTS_Rendering_Settings_Path); if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
} }
EditorBuildSettings.AddConfigObject(UTS_RENDERING_SETTINGS_NAME, renderingSettings, false); renderingSettings = CreateInstance<UTSRenderPassSettings>();
AssetDatabase.CreateAsset(renderingSettings, UTS_RENDERING_SETTINGS_PATH);
AssetDatabase.Refresh();
}
EditorBuildSettings.AddConfigObject(UTS_RENDERING_SETTINGS_NAME, renderingSettings, true);
return renderingSettings; return renderingSettings;
#else #else
return Resources.Load<UTSRenderPassSettings>(Path.GetFileNameWithoutExtension(UTS_Rendering_Settings_Path)); return Resources.Load<UTSRenderPassSettings>(UTS_RENDERING_SETTINGS_RESOURCES_PATH);
#endif #endif
} }

View File

@@ -1,24 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 02a9f5e1730430c4090d73e427a7f7a3, type: 3}
m_Name: UTSRenderSettings
m_EditorClassIdentifier:
outlineSetting:
enable: 1
renderingLayer:
serializedVersion: 0
m_Bits: 2
hairShadowSetting:
enable: 1
CasterRenderingLayer:
serializedVersion: 0
m_Bits: 4

View File

@@ -184,7 +184,7 @@ Shader "HDRP/Toon"
[HideInInspector][ToggleUI] _TransparentZWrite("_TransparentZWrite", Float) = 0.0 [HideInInspector][ToggleUI] _TransparentZWrite("_TransparentZWrite", Float) = 0.0
[HideInInspector] _CullMode("__cullmode", Float) = 2.0 [HideInInspector] _CullMode("__cullmode", Float) = 2.0
[HideInInspector] _CullModeForward("__cullmodeForward", Float) = 2.0 // This mode is dedicated to Forward to correctly handle backface then front face rendering thin transparent [HideInInspector] _CullModeForward("__cullmodeForward", Float) = 2.0 // This mode is dedicated to Forward to correctly handle backface then front face rendering thin transparent
[Enum(UnityEditor.Rendering.HighDefinition.TransparentCullMode)] _TransparentCullMode("_TransparentCullMode", Int) = 2 // Back culling by default [HideInInspector] _TransparentCullMode("_TransparentCullMode", Int) = 2 // Back culling by default
[HideInInspector] _ZTestDepthEqualForOpaque("_ZTestDepthEqualForOpaque", Int) = 4 // Less equal [HideInInspector] _ZTestDepthEqualForOpaque("_ZTestDepthEqualForOpaque", Int) = 4 // Less equal
[HideInInspector] _ZTestModeDistortion("_ZTestModeDistortion", Int) = 8 [HideInInspector] _ZTestModeDistortion("_ZTestModeDistortion", Int) = 8
[HideInInspector] _ZTestGBuffer("_ZTestGBuffer", Int) = 4 [HideInInspector] _ZTestGBuffer("_ZTestGBuffer", Int) = 4
@@ -317,6 +317,7 @@ Shader "HDRP/Toon"
_SDFNoseHighlightSmoothRange("SDFNoseHighlightSmoothRange", Range(0.0, 0.1)) = 0.02 _SDFNoseHighlightSmoothRange("SDFNoseHighlightSmoothRange", Range(0.0, 0.1)) = 0.02
// Hair Shadow // Hair Shadow
[Toggle(_)] _Is_CastHairShadow("Is_CastHairShadow", Float) = 0
[Toggle(_)] _Is_ReceiveHairShadow("Is_ReceiveHairShadow", Float) = 0 [Toggle(_)] _Is_ReceiveHairShadow("Is_ReceiveHairShadow", Float) = 0
_ShadowBias("ShadowBias", Range(0.0, 5.0)) = 0.0 _ShadowBias("ShadowBias", Range(0.0, 5.0)) = 0.0
@@ -1156,6 +1157,34 @@ Shader "HDRP/Toon"
ENDHLSL ENDHLSL
} }
Pass
{
Name "HairShadowCaster"
Tags{ "LightMode" = "HairShadowCaster" }
Cull[_CullMode]
ZClip [_ZClip]
ZWrite On
ZTest LEqual
ColorMask 0
HLSLPROGRAM
#define SHADERPASS SHADERPASS_SHADOWS
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitDepthPass.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitData.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassDepthOnly.hlsl"
#pragma vertex Vert
#pragma fragment Frag
ENDHLSL
}
} }
SubShader SubShader

View File

@@ -1,130 +0,0 @@
Shader "Renderers/HairShadowRenderer"
{
Properties
{
_Color("Color", Color) = (1,1,1,1)
_ColorMap("ColorMap", 2D) = "white" {}
// Transparency
_AlphaCutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
[HideInInspector]_BlendMode("_BlendMode", Range(0.0, 1.0)) = 0.5
}
HLSLINCLUDE
#pragma target 4.5
#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch
// #pragma enable_d3d11_debug_symbols
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl"
//#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl"
//enable GPU instancing support
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
ENDHLSL
SubShader
{
Tags{ "RenderPipeline" = "HDRenderPipeline" }
Pass
{
Name "HairShadow"
Tags { "LightMode" = "HairShadow" }
Blend Off
ZWrite On
ZTest LEqual
Cull Front
HLSLPROGRAM
#define _SURFACE_TYPE_OPAQUE
// Toggle the alpha test
#define _ALPHATEST_ON
// Toggle transparency
// #define _SURFACE_TYPE_TRANSPARENT
// Toggle fog on transparent
#define _ENABLE_FOG_ON_TRANSPARENT
// List all the attributes needed in your shader (will be passed to the vertex shader)
// you can see the complete list of these attributes in VaryingMesh.hlsl
#define ATTRIBUTES_NEED_TEXCOORD0
#define ATTRIBUTES_NEED_NORMAL
#define ATTRIBUTES_NEED_TANGENT
// List all the varyings needed in your fragment shader
#define VARYINGS_NEED_TEXCOORD0
#define VARYINGS_NEED_TANGENT_TO_WORLD
#define SHADERPASS SHADERPASS_FORWARD_UNLIT
int _HairShadowPassChannel;
TEXTURE2D(_ColorMap);
TEXTURE2D(_HairShadowTex);
SAMPLER(sampler_HairShadowTex);
// Declare properties in the UnityPerMaterial cbuffer to make the shader compatible with SRP Batcher.
CBUFFER_START(UnityPerMaterial)
float4 _ColorMap_ST;
float4 _Color;
float _AlphaCutoff;
float _BlendMode;
CBUFFER_END
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPassRenderersV2.hlsl"
// If you need to modify the vertex datas, you can uncomment this code
// Note: all the transformations here are done in object space
// #define HAVE_MESH_MODIFICATION
// AttributesMesh ApplyMeshModification(AttributesMesh input, float3 timeParameters)
// {
// input.positionOS += input.normalOS * 0.0001; // inflate a bit the mesh to avoid z-fight
// return input;
// }
// Put the code to render the objects in your custom pass in this function
void GetSurfaceAndBuiltinData(FragInputs fragInputs, float3 viewDirection, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
{
float cDepth = SampleCameraDepth(posInput.positionNDC);
float mDepth = posInput.deviceDepth;
float opacity = 1;
// const float3 color = float3(LinearEyeDepth(posInput.deviceDepth, _ZBufferParams), 0, 0);
// A manual depth test is needed here. Custom pass will always draw with no regard of depth.
// This test was given a quite large leeway to avoid discarding when cDepth = mDepth [Suomi, 20230915]
//float3 color = float3(cDepth < mDepth + 0.01 ? mDepth : 0, 0, 0); // Can get that in HDRP directly
float3 color = float3(0, 0, 0);
color.r = mDepth;
#ifdef _ALPHATEST_ON
DoAlphaTest(opacity, _AlphaCutoff);
#endif
// Write back the data to the output structures
ZERO_BUILTIN_INITIALIZE(builtinData); // No call to InitBuiltinData as we don't have any lighting
ZERO_INITIALIZE(SurfaceData, surfaceData);
builtinData.opacity = opacity;
builtinData.emissiveColor = float3(0, 0, 0);
surfaceData.color = color;
}
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForwardUnlit.hlsl"
#pragma vertex Vert
#pragma fragment Frag
ENDHLSL
}
}
}

View File

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

View File

@@ -194,13 +194,13 @@ void Frag(PackedVaryingsToPS packedInput,
#ifdef VARYINGS_NEED_POSITION_WS #ifdef VARYINGS_NEED_POSITION_WS
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS); float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
#ifdef _EYE_PARALLAX #ifdef _EYE_PARALLAX
// Must have view Dir to work // Must have view Dir to work
float2 viewT = TransformObjectToTangent(V, input.tangentToWorld); float2 viewT = TransformObjectToTangent(V, input.tangentToWorld);
float2 parallaxOffset = viewT; float2 parallaxOffset = viewT;
parallaxOffset.y = -parallaxOffset.y; parallaxOffset.y = -parallaxOffset.y;
Set_UV0.xy = clamp(Set_UV0.xy -_EyeParallaxAmount * parallaxOffset, 0, 1); Set_UV0.xy = clamp(Set_UV0.xy -_EyeParallaxAmount * parallaxOffset, 0, 1);
#endif #endif
#else #else
// Unused // Unused
@@ -249,11 +249,11 @@ void Frag(PackedVaryingsToPS packedInput,
#ifdef _ANISOTROPYMAP #ifdef _ANISOTROPYMAP
surfaceData.anisotropy = SAMPLE_TEXTURE2D(_AnisotropyMap, sampler_AnisotropyMap, TRANSFORM_TEX(Set_UV0, _AnisotropyMap)).r; surfaceData.anisotropy = SAMPLE_TEXTURE2D(_AnisotropyMap, sampler_AnisotropyMap, TRANSFORM_TEX(Set_UV0, _AnisotropyMap)).r;
#if _PBR_Mode_KK #if _PBR_Mode_KK
surfaceData.anisotropy += ADD_IDX(_Anisotropy) - 0.5; surfaceData.anisotropy += ADD_IDX(_Anisotropy) - 0.5;
#else #else
surfaceData.anisotropy *= ADD_IDX(_Anisotropy); surfaceData.anisotropy *= ADD_IDX(_Anisotropy);
#endif #endif
#else #else
surfaceData.anisotropy = 1.0; surfaceData.anisotropy = 1.0;
surfaceData.anisotropy *= ADD_IDX(_Anisotropy); surfaceData.anisotropy *= ADD_IDX(_Anisotropy);
@@ -267,9 +267,9 @@ void Frag(PackedVaryingsToPS packedInput,
#ifdef _PBR_Mode_TOON #ifdef _PBR_Mode_TOON
float3 _SpecTex_var = 1; float3 _SpecTex_var = 1;
#ifdef _SPECULARCOLORMAP #ifdef _SPECULARCOLORMAP
_SpecTex_var = SAMPLE_TEXTURE2D(_SpecularColorMap, sampler_SpecularColorMap, TRANSFORM_TEX(Set_UV0, _BaseColorMap)).rgb; _SpecTex_var = SAMPLE_TEXTURE2D(_SpecularColorMap, sampler_SpecularColorMap, TRANSFORM_TEX(Set_UV0, _BaseColorMap)).rgb;
#endif #endif
specularColor = _SpecTex_var * _SpecularColor; specularColor = _SpecTex_var * _SpecularColor;
#else #else
specularColor = SpecularColor(_MainTex_var.rgb * _BaseColor.rgb, metallic); specularColor = SpecularColor(_MainTex_var.rgb * _BaseColor.rgb, metallic);
@@ -351,13 +351,13 @@ void Frag(PackedVaryingsToPS packedInput,
float3 lightColor = ApplyCurrentExposureMultiplier(lightData.color); float3 lightColor = ApplyCurrentExposureMultiplier(lightData.color);
float3 lightDirection = -lightData.forward; float3 lightDirection = -lightData.forward;
#ifndef LIGHT_EVALUATION_NO_COOKIE #ifndef LIGHT_EVALUATION_NO_COOKIE
if (lightData.cookieMode != COOKIEMODE_NONE) if (lightData.cookieMode != COOKIEMODE_NONE)
{ {
float3 lightToSample = input.positionRWS - lightData.positionRWS; float3 lightToSample = input.positionRWS - lightData.positionRWS;
lightColor *= EvaluateCookie_Directional(context, lightData, lightToSample); lightColor *= EvaluateCookie_Directional(context, lightData, lightToSample);
} }
#endif #endif
UTSLightData utsLightData; UTSLightData utsLightData;
utsLightData.lightDirection = lightDirection; utsLightData.lightDirection = lightDirection;
@@ -416,33 +416,33 @@ void Frag(PackedVaryingsToPS packedInput,
light.shadowIndex, L); light.shadowIndex, L);
} }
#endif // UTS_USE_RAYTRACING_SHADOW #endif // UTS_USE_RAYTRACING_SHADOW
} }
#if defined (UTS_USE_RAYTRACING_SHADOW) #if defined (UTS_USE_RAYTRACING_SHADOW)
else else
{ {
float r = UNITY_SAMPLE_SCREEN_SHADOW(_RaytracedHardShadow, float4(posInput.positionNDC.xy, lightDirection * _ShadowBias, 1)); float r = UNITY_SAMPLE_SCREEN_SHADOW(_RaytracedHardShadow, float4(posInput.positionNDC.xy, lightDirection * _ShadowBias, 1));
context.shadowValue = r; context.shadowValue = r;
} }
#endif // UTS_USE_RAYTRACING_SHADOW #endif // UTS_USE_RAYTRACING_SHADOW
} }
context.shadowValue = lerp(1, context.shadowValue, lightData.shadowDimmer); context.shadowValue = lerp(1, context.shadowValue, lightData.shadowDimmer);
customMainLight.shadowValue = context.shadowValue; customMainLight.shadowValue = context.shadowValue;
} }
#if defined(UTS_DEBUG_SELFSHADOW) #if defined(UTS_DEBUG_SELFSHADOW)
if (_DirectionalShadowIndex >= 0) if (_DirectionalShadowIndex >= 0)
finalColor = UTS_SelfShdowMainLight(context, input, _DirectionalShadowIndex); finalColor = UTS_SelfShdowMainLight(context, input, _DirectionalShadowIndex);
#else #else
UTS_MainLight(context, input, utsLightData, surfaceData, bsdfData, inverseClipping, channelAlpha, utsData, utsAggregateLighting); UTS_MainLight(context, input, utsLightData, surfaceData, bsdfData, inverseClipping, channelAlpha, utsData, utsAggregateLighting);
#endif #endif
int i = 0; // Declare once to avoid the D3D11 compiler warning. int i = 0; // Declare once to avoid the D3D11 compiler warning.
for (i = 0; i < (int)_DirectionalLightCount; ++i) for (i = 0; i < (int) _DirectionalLightCount; ++i)
{ {
if (IsMatchingLightLayer(_DirectionalLightDatas[i].lightLayers, builtinData.renderingLayers)) if (IsMatchingLightLayer(_DirectionalLightDatas[i].lightLayers, builtinData.renderingLayers))
{ {
@@ -457,11 +457,11 @@ void Frag(PackedVaryingsToPS packedInput,
utsLightData.shadowTint = _DirectionalLightDatas[i].shadowTint; utsLightData.shadowTint = _DirectionalLightDatas[i].shadowTint;
utsLightData.penumbraTint = _DirectionalLightDatas[i].penumbraTint; utsLightData.penumbraTint = _DirectionalLightDatas[i].penumbraTint;
#if defined(UTS_DEBUG_SELFSHADOW) #if defined(UTS_DEBUG_SELFSHADOW)
#else #else
UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, 0, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting); UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, 0, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting);
#endif #endif
} }
} }
} }
@@ -476,14 +476,14 @@ void Frag(PackedVaryingsToPS packedInput,
{ {
uint lightCount, lightStart; uint lightCount, lightStart;
#ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER #ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
GetCountAndStart(posInput, LIGHTCATEGORY_PUNCTUAL, lightStart, lightCount); GetCountAndStart(posInput, LIGHTCATEGORY_PUNCTUAL, lightStart, lightCount);
#else // LIGHTLOOP_DISABLE_TILE_AND_CLUSTER #else // LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
lightCount = _PunctualLightCount; lightCount = _PunctualLightCount;
lightStart = 0; lightStart = 0;
#endif #endif
bool fastPath = false; bool fastPath = false;
#if SCALARIZE_LIGHT_LOOP #if SCALARIZE_LIGHT_LOOP
uint lightStartLane0; uint lightStartLane0;
fastPath = IsFastPath(lightStart, lightStartLane0); fastPath = IsFastPath(lightStart, lightStartLane0);
@@ -491,7 +491,7 @@ void Frag(PackedVaryingsToPS packedInput,
{ {
lightStart = lightStartLane0; lightStart = lightStartLane0;
} }
#endif #endif
@@ -508,11 +508,11 @@ void Frag(PackedVaryingsToPS packedInput,
while (v_lightListOffset < lightCount) while (v_lightListOffset < lightCount)
{ {
v_lightIdx = FetchIndex(lightStart, v_lightListOffset); v_lightIdx = FetchIndex(lightStart, v_lightListOffset);
#if SCALARIZE_LIGHT_LOOP #if SCALARIZE_LIGHT_LOOP
uint s_lightIdx = ScalarizeElementIndex(v_lightIdx, fastPath); uint s_lightIdx = ScalarizeElementIndex(v_lightIdx, fastPath);
#else #else
uint s_lightIdx = v_lightIdx; uint s_lightIdx = v_lightIdx;
#endif #endif
if (s_lightIdx == -1) if (s_lightIdx == -1)
break; break;
@@ -541,9 +541,9 @@ void Frag(PackedVaryingsToPS packedInput,
utsLightData.shadowTint = s_lightData.shadowTint; utsLightData.shadowTint = s_lightData.shadowTint;
utsLightData.penumbraTint = s_lightData.penumbraTint; utsLightData.penumbraTint = s_lightData.penumbraTint;
#if defined(UTS_DEBUG_SELFSHADOW) #if defined(UTS_DEBUG_SELFSHADOW)
#else #else
posInput.positionWS = posInput.positionWS + lightDirection * _ShadowBias; posInput.positionWS = posInput.positionWS + lightDirection * _ShadowBias;
float shadow = EvaluateShadow_Punctual(context, posInput, s_lightData, builtinData, GetNormalForShadowBias(bsdfData), lightDirection, distances); float shadow = EvaluateShadow_Punctual(context, posInput, s_lightData, builtinData, GetNormalForShadowBias(bsdfData), lightDirection, distances);
context.shadowValue = shadow; context.shadowValue = shadow;
@@ -565,7 +565,7 @@ void Frag(PackedVaryingsToPS packedInput,
} }
UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, s_lightData.lightType, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting); UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, s_lightData.lightType, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting);
#endif #endif
} }
} }
@@ -578,12 +578,12 @@ void Frag(PackedVaryingsToPS packedInput,
{ {
uint lightCount, lightStart; uint lightCount, lightStart;
#ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER #ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
GetCountAndStart(posInput, LIGHTCATEGORY_AREA, lightStart, lightCount); GetCountAndStart(posInput, LIGHTCATEGORY_AREA, lightStart, lightCount);
#else #else
lightCount = _AreaLightCount; lightCount = _AreaLightCount;
lightStart = _PunctualLightCount; lightStart = _PunctualLightCount;
#endif #endif
// COMPILER BEHAVIOR WARNING! // COMPILER BEHAVIOR WARNING!
// If rectangle lights are before line lights, the compiler will duplicate light matrices in VGPR because they are used differently between the two types of lights. // If rectangle lights are before line lights, the compiler will duplicate light matrices in VGPR because they are used differently between the two types of lights.
@@ -648,13 +648,13 @@ void Frag(PackedVaryingsToPS packedInput,
//Evaluate the shadow part //Evaluate the shadow part
float shadow; float shadow;
posInput.positionWS = posInput.positionWS + utsLightData.lightDirection * _ShadowBias; posInput.positionWS = posInput.positionWS + utsLightData.lightDirection * _ShadowBias;
#if defined(SCREEN_SPACE_SHADOWS_ON) && !defined(_SURFACE_TYPE_TRANSPARENT) #if defined(SCREEN_SPACE_SHADOWS_ON) && !defined(_SURFACE_TYPE_TRANSPARENT)
if ((s_lightData.screenSpaceShadowIndex & SCREEN_SPACE_SHADOW_INDEX_MASK) != INVALID_SCREEN_SPACE_SHADOW) if ((s_lightData.screenSpaceShadowIndex & SCREEN_SPACE_SHADOW_INDEX_MASK) != INVALID_SCREEN_SPACE_SHADOW)
{ {
shadow = GetScreenSpaceShadow(posInput, s_lightData.screenSpaceShadowIndex); shadow = GetScreenSpaceShadow(posInput, s_lightData.screenSpaceShadowIndex);
} }
else else
#endif #endif
{ {
shadow = EvaluateShadow_RectArea(context, posInput, s_lightData, builtinData, GetNormalForShadowBias(bsdfData), normalize(s_lightData.positionRWS), length(s_lightData.positionRWS)); shadow = EvaluateShadow_RectArea(context, posInput, s_lightData, builtinData, GetNormalForShadowBias(bsdfData), normalize(s_lightData.positionRWS), length(s_lightData.positionRWS));
} }
@@ -662,21 +662,21 @@ void Frag(PackedVaryingsToPS packedInput,
posInput.positionWS = posInput.positionWS - lightDirection * _ShadowBias; posInput.positionWS = posInput.positionWS - lightDirection * _ShadowBias;
} }
#if defined(UTS_DEBUG_SELFSHADOW) #if defined(UTS_DEBUG_SELFSHADOW)
#else #else
UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, s_lightData.lightType, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting); UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, s_lightData.lightType, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting);
//utsAggregateLighting.directDiffuse += ltcValue.rgb * ltcValue.a * intensity * s_lightData.diffuseDimmer; //utsAggregateLighting.directDiffuse += ltcValue.rgb * ltcValue.a * intensity * s_lightData.diffuseDimmer;
//utsAggregateLighting.directDiffuse += intensity; //utsAggregateLighting.directDiffuse += intensity;
#endif #endif
/* /*
if(s_lightData.lightType == GPULIGHTTYPE_RECTANGLE) if(s_lightData.lightType == GPULIGHTTYPE_RECTANGLE)
{ {
#if SHADEROPTIONS_BARN_DOOR #if SHADEROPTIONS_BARN_DOOR
// Apply the barn door modification to the light data // Apply the barn door modification to the light data
RectangularLightApplyBarnDoor(s_lightData, posInput.positionWS); RectangularLightApplyBarnDoor(s_lightData, posInput.positionWS);
#endif #endif
if (dot(s_lightData.forward, unL) < FLT_EPS) if (dot(s_lightData.forward, unL) < FLT_EPS)
{ {
@@ -691,15 +691,15 @@ void Frag(PackedVaryingsToPS packedInput,
float intensity; float intensity;
// Compute the light attenuation. // Compute the light attenuation.
#ifdef ELLIPSOIDAL_ATTENUATION #ifdef ELLIPSOIDAL_ATTENUATION
// The attenuation volume is an axis-aligned ellipsoid s.t. // The attenuation volume is an axis-aligned ellipsoid s.t.
// r1 = (r + w / 2), r2 = (r + h / 2), r3 = r. // r1 = (r + w / 2), r2 = (r + h / 2), r3 = r.
intensity = EllipsoidalDistanceAttenuation(unL, invHalfDim, s_lightData.rangeAttenuationScale, s_lightData.rangeAttenuationBias); intensity = EllipsoidalDistanceAttenuation(unL, invHalfDim, s_lightData.rangeAttenuationScale, s_lightData.rangeAttenuationBias);
#else #else
// The attenuation volume is an axis-aligned box s.t. // The attenuation volume is an axis-aligned box s.t.
// hX = (r + w / 2), hY = (r + h / 2), hZ = r. // hX = (r + w / 2), hY = (r + h / 2), hZ = r.
intensity = BoxDistanceAttenuation(unL, invHalfDim, s_lightData.rangeAttenuationScale, s_lightData.rangeAttenuationBias); intensity = BoxDistanceAttenuation(unL, invHalfDim, s_lightData.rangeAttenuationScale, s_lightData.rangeAttenuationBias);
#endif #endif
if(intensity != 0.0f) if(intensity != 0.0f)
{ {
@@ -727,12 +727,12 @@ void Frag(PackedVaryingsToPS packedInput,
float4x3 LD = mul(lightVerts, preLightData.ltcTransformDiffuse); float4x3 LD = mul(lightVerts, preLightData.ltcTransformDiffuse);
float3 formFactorD; float3 formFactorD;
#ifdef APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT #ifdef APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
formFactorD = PolygonFormFactor(LD, real3(0,0,1), 4); formFactorD = PolygonFormFactor(LD, real3(0,0,1), 4);
ltcValue = PolygonIrradianceFromVectorFormFactor(formFactorD); ltcValue = PolygonIrradianceFromVectorFormFactor(formFactorD);
#else #else
ltcValue = PolygonIrradiance(LD); ltcValue = PolygonIrradiance(LD);
#endif #endif
utsLightData.diffuseDimmer *= ltcValue; utsLightData.diffuseDimmer *= ltcValue;
@@ -740,36 +740,36 @@ void Frag(PackedVaryingsToPS packedInput,
// Polygon irradiance in the transformed configuration. // Polygon irradiance in the transformed configuration.
float4x3 LS = mul(lightVerts, preLightData.ltcTransformSpecular); float4x3 LS = mul(lightVerts, preLightData.ltcTransformSpecular);
float3 formFactorS; float3 formFactorS;
#ifdef APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT #ifdef APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
formFactorS = PolygonFormFactor(LS, real3(0,0,1), 4); formFactorS = PolygonFormFactor(LS, real3(0,0,1), 4);
ltcValue = PolygonIrradianceFromVectorFormFactor(formFactorS); ltcValue = PolygonIrradianceFromVectorFormFactor(formFactorS);
#else #else
ltcValue = PolygonIrradiance(LS); ltcValue = PolygonIrradiance(LS);
#endif #endif
utsLightData.specularDimmer *= ltcValue; utsLightData.specularDimmer *= ltcValue;
//Evaluate the shadow part //Evaluate the shadow part
float shadow; float shadow;
posInput.positionWS = posInput.positionWS + lightDirection * _ShadowBias; posInput.positionWS = posInput.positionWS + lightDirection * _ShadowBias;
#if defined(SCREEN_SPACE_SHADOWS_ON) && !defined(_SURFACE_TYPE_TRANSPARENT) #if defined(SCREEN_SPACE_SHADOWS_ON) && !defined(_SURFACE_TYPE_TRANSPARENT)
if ((s_lightData.screenSpaceShadowIndex & SCREEN_SPACE_SHADOW_INDEX_MASK) != INVALID_SCREEN_SPACE_SHADOW) if ((s_lightData.screenSpaceShadowIndex & SCREEN_SPACE_SHADOW_INDEX_MASK) != INVALID_SCREEN_SPACE_SHADOW)
{ {
shadow = GetScreenSpaceShadow(posInput, s_lightData.screenSpaceShadowIndex); shadow = GetScreenSpaceShadow(posInput, s_lightData.screenSpaceShadowIndex);
} }
else else
#endif #endif
{ {
shadow = EvaluateShadow_RectArea(context, posInput, s_lightData, builtinData, GetNormalForShadowBias(bsdfData), normalize(s_lightData.positionRWS), length(s_lightData.positionRWS)); shadow = EvaluateShadow_RectArea(context, posInput, s_lightData, builtinData, GetNormalForShadowBias(bsdfData), normalize(s_lightData.positionRWS), length(s_lightData.positionRWS));
} }
context.shadowValue = shadow; context.shadowValue = shadow;
posInput.positionWS = posInput.positionWS - lightDirection * _ShadowBias; posInput.positionWS = posInput.positionWS - lightDirection * _ShadowBias;
#if defined(UTS_DEBUG_SELFSHADOW) #if defined(UTS_DEBUG_SELFSHADOW)
#else #else
UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, s_lightData.lightType, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting); UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, s_lightData.lightType, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting);
#endif #endif
} }
} }
} }
@@ -818,11 +818,11 @@ void Frag(PackedVaryingsToPS packedInput,
ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcTransformSpecular); ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcTransformSpecular);
utsLightData.specularDimmer *= ltcValue; utsLightData.specularDimmer *= ltcValue;
#if defined(UTS_DEBUG_SELFSHADOW) #if defined(UTS_DEBUG_SELFSHADOW)
#else #else
UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, s_lightData.lightType, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting); UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, s_lightData.lightType, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting);
#endif #endif
} }
} }
*/ */
@@ -910,18 +910,22 @@ void Frag(PackedVaryingsToPS packedInput,
utsAggregateLighting.directSpecular += _SDFNoseHighlightCoef * SDFNoseHighlight(angle, sdfRes.g, rightside, SDF_UV) * lightColor; utsAggregateLighting.directSpecular += _SDFNoseHighlightCoef * SDFNoseHighlight(angle, sdfRes.g, rightside, SDF_UV) * lightColor;
#endif #endif
#if defined(_RECEIVE_HAIR_SHADOW) && defined(_HAIR_SHADOWS) #ifdef _RECEIVE_HAIR_SHADOW
// Push the face fragment view space position towards the light for a little bit // 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))); float hairShadowOpacity = saturate(Remap(length(posInput.positionWS), float2(_HairShadowFadeOutDistance, _HairShadowFadeInDistance), float2(0, 1)));
if(hairShadowOpacity > 0) if(hairShadowOpacity > 0)
{ {
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 viewLightDir = TransformWorldToViewDir(customMainLight.lightDirection); // / posInput.deviceDepth; when linearDepth grows large, the movement amount should be lower since we are getting further from the face.
float shadowLength = _HairShadowDistance * 5.0 * max(0.5, posInput.linearDepth * _HairShadowDistanceScaleFactor) / posInput.linearDepth; 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);
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. 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. // Then sample the hair buffer, to see if the fragment lands in shadow.
float4 hairBuffer = SAMPLE_TEXTURE2D(_HairShadowTex, s_trilinear_clamp_sampler, samplingPoint); 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 = hairBuffer.r; 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 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. // 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); float hairShadow = lerp(0,hairShadowOpacity,depthCorrect);
@@ -937,7 +941,7 @@ void Frag(PackedVaryingsToPS packedInput,
float3 finalColorWoEmissive = AccumulateAggregateLighting(utsAggregateLighting); float3 finalColorWoEmissive = AccumulateAggregateLighting(utsAggregateLighting);
finalColorWoEmissive = GetExposureAdjustedColor(finalColorWoEmissive ); finalColorWoEmissive = GetExposureAdjustedColor(finalColorWoEmissive);
finalColorWoEmissive = ApplyCompensation(finalColorWoEmissive); finalColorWoEmissive = ApplyCompensation(finalColorWoEmissive);
finalColor = finalColorWoEmissive + emissive; finalColor = finalColorWoEmissive + emissive;
@@ -967,29 +971,28 @@ void Frag(PackedVaryingsToPS packedInput,
mDepth = hairPixel > 0.1 ? max(hDepth.r, mDepth) + magic : mDepth; // Move this part of eyebrow in front of the hair mDepth = hairPixel > 0.1 ? max(hDepth.r, mDepth) + magic : mDepth; // Move this part of eyebrow in front of the hair
// Added a max here to prevent sampling of hair in the back // Added a max here to prevent sampling of hair in the back
if(cDepth - mDepth > 0.02) discard; // Manual Depth Test. if(cDepth - mDepth > 0.02) // Manual Depth Test
{
discard;
}
// _EyeBrowBlendingFactor
outColor.a = _EyeBrowBlendingFactor; outColor.a = _EyeBrowBlendingFactor;
outColor.a = hairPixel > 0.01 ? outColor.a : 1 ; outColor.a = hairPixel > 0.01 ? outColor.a : 1 ;
//outColor.rgb = float3(hDepth.rg * 5,0);
#endif #endif
#if defined(UTS_DEBUG_SHADOWMAP) || defined(UTS_DEBUG_SELFSHADOW) #if defined(UTS_DEBUG_SHADOWMAP) || defined(UTS_DEBUG_SELFSHADOW)
outColor.rgb = 1; outColor.rgb = 1;
#ifdef UTS_DEBUG_SELFSHADOW #ifdef UTS_DEBUG_SELFSHADOW
outColor.rgb = min(finalColor, outColor.rgb); outColor.rgb = min(finalColor, outColor.rgb);
#endif #endif
#ifdef UTS_DEBUG_SHADOWMAP #ifdef UTS_DEBUG_SHADOWMAP
#ifdef UTS_DEBUG_SHADOWMAP_BINALIZATION #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); outColor.rgb = min(context.shadowValue < 0.9f ? clamp(context.shadowValue - 0.2, 0.0, 0.9) : 1.0f, outColor.rgb);
#else #else
outColor.rgb = min(context.shadowValue, outColor.rgb); outColor.rgb = min(context.shadowValue, outColor.rgb);
#endif #endif
#endif // ifdef UTS_DEBUG_SHADOWMAP #endif // ifdef UTS_DEBUG_SHADOWMAP
#endif // defined(UTS_DEBUG_SHADOWMAP) || defined(UTS_DEBUG_SELFSHADOW) #endif // defined(UTS_DEBUG_SHADOWMAP) || defined(UTS_DEBUG_SELFSHADOW)
#ifdef _DEPTHOFFSET_ON #ifdef _DEPTHOFFSET_ON

View File

@@ -277,10 +277,8 @@ void UTS_MainLight(LightLoopContext lightLoopContext, FragInputs input, UTSLight
float4 _Set_RimLightMask_var = tex2D(_Set_RimLightMask, TRANSFORM_TEX(Set_UV0, _Set_RimLightMask)); 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); float3 _Is_LightColor_RimLight_var = lerp(_RimLightColor.rgb, (_RimLightColor.rgb * Set_LightColor), _Is_LightColor_RimLight);
float _RimArea_var = dot(utsData.normalDirection, utsData.viewDirection); float _RimArea_var = dot(utsData.normalDirection, utsData.viewDirection);
if(_Is_BlendAddToRimColor == 1) _RimArea_var = lerp(_RimArea_var, 1 - _RimArea_var,_Is_BlendAddToRimColor);
{
_RimArea_var = 1 - _RimArea_var;
}
float _RimLightPower_var = pow(_RimArea_var, exp2(lerp(3, 0, _RimLight_Power))); 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 _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; float _VertHalfLambert_var = 0.5 * dot(utsData.normalDirection, lightDirection) + 0.5;
@@ -296,15 +294,8 @@ void UTS_MainLight(LightLoopContext lightLoopContext, FragInputs input, UTSLight
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)); 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 *= _RimLightVisible;
Set_RimLight *= _RimLight_Strength; Set_RimLight *= _RimLight_Strength;
float3 _RimLight_var;
if(_Is_BlendAddToRimColor == 0) 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(Set_HighColor, (Set_HighColor * Set_RimLight), _RimLight);
}
else
{
_RimLight_var = lerp(Set_HighColor, (Set_HighColor + Set_RimLight), _RimLight);
}
if (any(Set_RimLight) * maskRimEnabled) if (any(Set_RimLight) * maskRimEnabled)
{ {
@@ -317,16 +308,8 @@ void UTS_MainLight(LightLoopContext lightLoopContext, FragInputs input, UTSLight
#else #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)); 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; Set_RimLight *= _RimLight_Strength;
float3 _RimLight_var;
if(_Is_BlendAddToRimColor == 0)
{
_RimLight_var = lerp(Set_HighColor, (Set_HighColor * Set_RimLight), _RimLight);
}
else
{
_RimLight_var = lerp(Set_HighColor, (Set_HighColor + Set_RimLight), _RimLight);
}
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); _RimLight_var = lerp(_RimLight_var, (_RimLight_var * ((1.0 - Set_FinalShadowMask) + (Set_FinalShadowMask * _TweakHighColorOnShadow))), _Is_UseTweakHighColorOnShadow);
#endif #endif

View File

@@ -164,10 +164,8 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
float4 _Set_RimLightMask_var = tex2D(_Set_RimLightMask, TRANSFORM_TEX(Set_UV0, _Set_RimLightMask)); 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); float3 _Is_LightColor_RimLight_var = lerp(_RimLightColor.rgb, (_RimLightColor.rgb * Set_LightColor), _Is_LightColor_RimLight);
float _RimArea_var = dot(surfaceData.normalWS, V); float _RimArea_var = dot(surfaceData.normalWS, V);
if (_Is_BlendAddToRimColor == 1) _RimArea_var = lerp(_RimArea_var, 1 - _RimArea_var, _Is_BlendAddToRimColor);
{
_RimArea_var = 1 - _RimArea_var;
}
float _RimLightPower_var = pow(_RimArea_var, exp2(lerp(3, 0, _RimLight_Power))); 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 _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; float _VertHalfLambert_var = 0.5 * dot(surfaceData.normalWS, lightDirection) + 0.5;
@@ -187,14 +185,6 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
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)); 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 *= _RimLightVisible;
Set_RimLight *= _RimLight_Strength; Set_RimLight *= _RimLight_Strength;
if(_Is_BlendAddToRimColor == 0)
{
_HighColor_var = lerp(_HighColor_var, (_HighColor_var * Set_RimLight) * 1, _RimLight);
}
else
{
_HighColor_var = lerp(_HighColor_var, (_HighColor_var + Set_RimLight) * 1, _RimLight);
}
if (any(Set_RimLight) * maskRimEnabled) if (any(Set_RimLight) * maskRimEnabled)
{ {
@@ -216,21 +206,17 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
channelOutAlpha = _HighlightVisible; channelOutAlpha = _HighlightVisible;
} }
// Rim light
diffuseTerm = lerp(lerp(diffuseTerm, (diffuseTerm * Set_RimLight), _RimLight), lerp(diffuseTerm, (diffuseTerm + Set_RimLight), _RimLight), _Is_BlendAddToRimColor);
#else #else
_HighColor_var *= _TweakHighColorMask_var; _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)); 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; Set_RimLight *= _RimLight_Strength;
if (_Is_BlendAddToRimColor == 0)
{
_HighColor_var = lerp(_HighColor_var, (_HighColor_var * Set_RimLight), _RimLight);
}
else
{
_HighColor_var = lerp(_HighColor_var, (_HighColor_var + Set_RimLight), _RimLight);
}
diffuseTerm = diffuseTerm + lerp(lerp(_HighColor_var, (_HighColor_var * ((1.0 - Set_FinalShadowMask) + (Set_FinalShadowMask * _TweakHighColorOnShadow))), _Is_UseTweakHighColorOnShadow), float3(0, 0, 0), _Is_Filter_HiCutPointLightColor); 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 #endif
// PBR---------------------------------------------------------------------------------------------------------------- // PBR----------------------------------------------------------------------------------------------------------------

View File

@@ -344,6 +344,8 @@ CBUFFER_END
float _Outline_MaxWidth; float _Outline_MaxWidth;
float4 _HairShadowRTHandleScale;
float _HairShadowDistance; float _HairShadowDistance;
float _HairShadowDistanceScaleFactor; float _HairShadowDistanceScaleFactor;
float _HairShadowDepthBias; float _HairShadowDepthBias;

View File

@@ -1,6 +1,6 @@
using UnityEngine.Rendering; using UnityEngine.Rendering;
namespace Unity.Toonshader namespace Misaki.HdrpToon
{ {
[GenerateHLSL] [GenerateHLSL]
public enum UTS_BSDFDebug public enum UTS_BSDFDebug

View File

@@ -1,7 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine.Rendering; using UnityEngine.Rendering;
namespace Unity.Toonshader namespace Misaki.HdrpToon
{ {
public static class UTSDebugPanel public static class UTSDebugPanel
{ {

View File

@@ -1,13 +1,22 @@
using Unity.Toonshader; using UnityEditor;
using UnityEngine; using UnityEngine;
using UnityEngine.Experimental.Rendering; using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering; using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition; using UnityEngine.Rendering.HighDefinition;
using UnityEngine.Rendering.RendererUtils; using UnityEngine.Rendering.RendererUtils;
[HideInInspector] namespace Misaki.HdrpToon
public class UTSHairShadowPass : DrawRenderersCustomPass
{ {
[HideInInspector]
internal class UTSHairShadowPass : DrawRenderersCustomPass
{
public enum ShadowQuality
{
Low,
High
}
private const string Hair_Shadow_RTHandle_Scale_Prop_Name = "_HairShadowRTHandleScale";
private const string Hair_Shadow_Distance_Prop_Name = "_HairShadowDistance"; private const string Hair_Shadow_Distance_Prop_Name = "_HairShadowDistance";
private const string Hair_Shadow_Distance_Scale_Prop_Name = "_HairShadowDistanceScaleFactor"; private const string Hair_Shadow_Distance_Scale_Prop_Name = "_HairShadowDistanceScaleFactor";
private const string Hair_Shadow_Depth_Bias_Prop_Name = "_HairShadowDepthBias"; private const string Hair_Shadow_Depth_Bias_Prop_Name = "_HairShadowDepthBias";
@@ -17,60 +26,99 @@ public class UTSHairShadowPass : DrawRenderersCustomPass
private const string Output_RT_Name = "_HairShadowTex"; private const string Output_RT_Name = "_HairShadowTex";
private RTHandle _outputRTHandle; private RTHandle _outputRTHandle;
private bool _isEnable = false; private bool _needReallocate;
public UnityEngine.RenderingLayerMask renderingLayerMask; private ShadowQuality _shadowQuality = ShadowQuality.High;
internal ShadowQuality CurrentShadowQuality
{
get => _shadowQuality;
set
{
if (_shadowQuality == value)
{
return;
}
_shadowQuality = value;
_needReallocate = true;
}
}
private bool ShouldReallocateBuffer()
{
return _outputRTHandle == null || _outputRTHandle.rt == null || !_outputRTHandle.rt.IsCreated() || _needReallocate;
}
private void ReallocateBuffer()
{
#if UNITY_EDITOR
if (EditorApplication.isCompiling)
{
return;
}
#endif
var scale = _shadowQuality switch
{
ShadowQuality.Low => new Vector2(0.5f, 0.5f),
ShadowQuality.High => Vector2.one,
_ => Vector2.zero
};
var format = _shadowQuality switch
{
ShadowQuality.Low => GraphicsFormat.D16_UNorm,
ShadowQuality.High => GraphicsFormat.D32_SFloat,
_ => GraphicsFormat.D16_UNorm
};
_outputRTHandle?.Release();
_outputRTHandle = RTHandles.Alloc(scale, colorFormat: format, filterMode: FilterMode.Bilinear, wrapMode: TextureWrapMode.Clamp, isShadowMap: true, name: Output_RT_Name);
Shader.SetGlobalTexture(Output_RT_Name, _outputRTHandle);
_needReallocate = false;
}
protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd) protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd)
{ {
_outputRTHandle?.Release(); ReallocateBuffer();
_outputRTHandle = RTHandles.Alloc(Screen.width, Screen.height, colorFormat: GraphicsFormat.D32_SFloat, filterMode: FilterMode.Bilinear, wrapMode: TextureWrapMode.Clamp, name: Output_RT_Name);
SetEnable(true);
} }
protected override void Execute(CustomPassContext ctx) protected override void Execute(CustomPassContext ctx)
{ {
var utsRenderer = ctx.hdCamera.volumeStack.GetComponent<UTSRenderer>(); if (ShouldReallocateBuffer())
if (utsRenderer == null || !utsRenderer.enableHairShadow.value || !utsRenderer.enable.value)
{ {
SetEnable(false); ReallocateBuffer();
return; return;
} }
if (!_isEnable)
{
return;
}
SetShadowProperty(utsRenderer);
if (_outputRTHandle != null)
{
Shader.SetGlobalTexture(Output_RT_Name, _outputRTHandle);
CoreUtils.SetRenderTarget(ctx.cmd, _outputRTHandle, ClearFlag.DepthStencil); CoreUtils.SetRenderTarget(ctx.cmd, _outputRTHandle, ClearFlag.DepthStencil);
var utsRenderer = ctx.hdCamera.volumeStack.GetComponent<UTSRenderer>();
var shouldRender = utsRenderer != null && utsRenderer.enableHairShadow.value && utsRenderer.state.value;
if (!shouldRender)
{
CoreUtils.ClearRenderTarget(ctx.cmd, ClearFlag.DepthStencil, Color.black);
return;
} }
var mask = RenderStateMask.Nothing; var mask = RenderStateMask.Nothing;
var stateBlock = new RenderStateBlock(mask) var stateBlock = new RenderStateBlock(mask)
{ {
depthState = new DepthState(depthWrite, depthCompareFunction), depthState = new DepthState(true, CompareFunction.LessEqual),
}; };
var result = new RendererListDesc(HDShaderPassNames.s_DepthForwardOnlyName, ctx.cullingResults, ctx.hdCamera.camera) var result = new RendererListDesc(UtsShaderPassName.hairShadowCasterPassId, ctx.cullingResults, ctx.hdCamera.camera)
{ {
renderQueueRange = GetRenderQueueRange(renderQueueType), renderQueueRange = GetRenderQueueRange(RenderQueueType.All),
sortingCriteria = sortingCriteria, sortingCriteria = SortingCriteria.CommonOpaque,
excludeObjectMotionVectors = false, excludeObjectMotionVectors = false,
stateBlock = stateBlock, stateBlock = stateBlock,
renderingLayerMask = renderingLayerMask,
}; };
CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result)); CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result));
}
private static void SetShadowProperty(UTSRenderer utsRenderer) Shader.SetGlobalVector(Hair_Shadow_RTHandle_Scale_Prop_Name, _outputRTHandle.rtHandleProperties.rtHandleScale);
{
Shader.SetGlobalFloat(Hair_Shadow_Distance_Prop_Name, utsRenderer.shadowDistance.value); Shader.SetGlobalFloat(Hair_Shadow_Distance_Prop_Name, utsRenderer.shadowDistance.value);
Shader.SetGlobalFloat(Hair_Shadow_Distance_Scale_Prop_Name, utsRenderer.shadowDistanceScale.value); Shader.SetGlobalFloat(Hair_Shadow_Distance_Scale_Prop_Name, utsRenderer.shadowDistanceScale.value);
Shader.SetGlobalFloat(Hair_Shadow_Depth_Bias_Prop_Name, utsRenderer.shadowDepthBias.value); Shader.SetGlobalFloat(Hair_Shadow_Depth_Bias_Prop_Name, utsRenderer.shadowDepthBias.value);
@@ -85,24 +133,13 @@ public class UTSHairShadowPass : DrawRenderersCustomPass
public void Release() public void Release()
{ {
SetEnable(false); #if UNITY_EDITOR
if (EditorApplication.isCompiling)
{
return;
}
#endif
_outputRTHandle?.Release(); _outputRTHandle?.Release();
} }
public void SetEnable(bool isEnable)
{
if (_isEnable != isEnable)
{
if (isEnable)
{
Shader.EnableKeyword("_HAIR_SHADOWS");
}
else
{
Shader.DisableKeyword("_HAIR_SHADOWS");
}
_isEnable = isEnable;
}
} }
} }

View File

@@ -1,26 +1,27 @@
using Unity.Toonshader;
using UnityEngine; using UnityEngine;
using UnityEngine.Rendering; using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition; using UnityEngine.Rendering.HighDefinition;
[HideInInspector] namespace Misaki.HdrpToon
public class UTSOutlinePass : DrawRenderersCustomPass
{ {
public UnityEngine.RenderingLayerMask renderingLayerMask; [HideInInspector]
internal class UTSOutlinePass : DrawRenderersCustomPass
{
protected override void Execute(CustomPassContext ctx) protected override void Execute(CustomPassContext ctx)
{ {
var utsRenderer = ctx.hdCamera.volumeStack.GetComponent<UTSRenderer>(); var utsRenderer = ctx.hdCamera.volumeStack.GetComponent<UTSRenderer>();
if (utsRenderer == null) if (utsRenderer == null)
{
return; return;
}
if (!utsRenderer.enableOutline.value || !utsRenderer.enable.value) if (!utsRenderer.enableOutline.value || !utsRenderer.state.value)
{
return; return;
}
Shader.SetGlobalFloat("_Outline_MaxWidth", utsRenderer.outlineMaxWidth.value * 0.01f); Shader.SetGlobalFloat("_Outline_MaxWidth", utsRenderer.outlineMaxWidth.value * 0.01f);
var outlineTag = new ShaderTagId("Outline");
var mask = RenderStateMask.Nothing; var mask = RenderStateMask.Nothing;
var stateBlock = new RenderStateBlock(mask) var stateBlock = new RenderStateBlock(mask)
{ {
@@ -30,18 +31,15 @@ public class UTSOutlinePass : DrawRenderersCustomPass
}; };
var renderConfig = HDUtils.GetRendererConfiguration(false, false); var renderConfig = HDUtils.GetRendererConfiguration(false, false);
var result = new UnityEngine.Rendering.RendererUtils.RendererListDesc(outlineTag, ctx.cullingResults, ctx.hdCamera.camera) var result = new UnityEngine.Rendering.RendererUtils.RendererListDesc(UtsShaderPassName.outlinePassId, ctx.cullingResults, ctx.hdCamera.camera)
{ {
rendererConfiguration = renderConfig, rendererConfiguration = renderConfig,
renderQueueRange = GetRenderQueueRange(renderQueueType), renderQueueRange = GetRenderQueueRange(RenderQueueType.All),
sortingCriteria = sortingCriteria,
excludeObjectMotionVectors = false, excludeObjectMotionVectors = false,
overrideMaterial = overrideMaterial,
overrideMaterialPassIndex = (overrideMaterial != null) ? overrideMaterial.FindPass(overrideMaterialPassName) : 0,
stateBlock = stateBlock, stateBlock = stateBlock,
renderingLayerMask = renderingLayerMask,
}; };
CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result)); CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result));
} }
}
} }

View File

@@ -0,0 +1,91 @@
using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
namespace Misaki.HdrpToon
{
internal class UTSPass : CustomPass
{
private const int Adjustment_Curve_Precision = 128;
private const string Compensation_Prop_Name = "_ToonEvAdjustmentCompensation";
private const string Exposure_Adjustment_Prop_Name = "_ToonEvAdjustmentCurve";
private const string Exposure_Array_Prop_Name = "_ToonEvAdjustmentValueArray";
private const string Exposure_Min_Prop_Name = "_ToonEvAdjustmentValueMin";
private const string Exposure_Max_Prop_Name = "_ToonEvAdjustmentValueMax";
private const string Toon_Light_Filter_Prop_Name = "_ToonLightHiCutFilter";
private const string Ignore_Volume_Exposure_Prop_Name = "_ToonIgnoreExposureMultiplier";
private float _max;
private float _min;
private float[] _exposureArray;
protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd)
{
_exposureArray = new float[Adjustment_Curve_Precision];
}
protected override void Execute(CustomPassContext ctx)
{
var utsRenderer = ctx.hdCamera.volumeStack.GetComponent<UTSRenderer>();
if (utsRenderer == null)
{
return;
}
var toonEVAdjustment = utsRenderer.toonEVAdjustment.value ? 1 : 0;
var lightIntensityLimiter = utsRenderer.lightIntensityLimiter.value ? 1 : 0;
var ignoreVolumeExposure = utsRenderer.ignoreVolumeExposure.value ? 1 : 0;
var compensation = utsRenderer.compensation.value;
if (!utsRenderer.state.value)
{
_min = 0;
_max = 0;
_exposureArray.AsSpan().Fill(0);
toonEVAdjustment = 0;
lightIntensityLimiter = 0;
ignoreVolumeExposure = 0;
compensation = 0;
}
else
{
// Fail safe in case the curve is deleted / has 0 point
var curve = utsRenderer.adjustmentCurve.value;
if (curve == null || curve.length == 0)
{
_min = 0f;
_max = 0f;
_exposureArray.AsSpan().Fill(0);
}
else
{
_min = curve[0].time;
_max = curve[curve.length - 1].time;
var step = (_max - _min) / (Adjustment_Curve_Precision - 1f);
for (var i = 0; i < Adjustment_Curve_Precision; i++)
{
_exposureArray[i] = curve.Evaluate(_min + step * i);
}
}
}
Shader.SetGlobalFloatArray(Exposure_Array_Prop_Name, _exposureArray);
Shader.SetGlobalFloat(Exposure_Min_Prop_Name, _min);
Shader.SetGlobalFloat(Exposure_Max_Prop_Name, _max);
Shader.SetGlobalInt(Exposure_Adjustment_Prop_Name, toonEVAdjustment);
Shader.SetGlobalInt(Toon_Light_Filter_Prop_Name, lightIntensityLimiter);
Shader.SetGlobalInt(Ignore_Volume_Exposure_Prop_Name, ignoreVolumeExposure);
Shader.SetGlobalFloat(Compensation_Prop_Name, compensation);
}
protected override void Cleanup()
{
_exposureArray = null;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: be0dbffe58fd1fc48a45d8a6e1791ac0

View File

@@ -1,67 +0,0 @@
using UnityEngine;
using UnityEngine.Rendering.HighDefinition;
namespace Unity.Toonshader
{
#if UNITY_EDITOR
[UnityEditor.InitializeOnLoad]
#endif
public static class RegisterUTSRenderPass
{
private static readonly UTSRenderPassSettings _renderSetting;
private static readonly UTSOutlinePass _outlinePass;
private static readonly UTSHairShadowPass _hairShadowPass;
static RegisterUTSRenderPass()
{
_renderSetting = UTSRenderPassSettings.GetOrCreateSettings();
if (_renderSetting == null)
{
return;
}
_outlinePass = new()
{
name = "UTS Outline",
renderingLayerMask = _renderSetting.outlineSetting.renderingLayer
};
_hairShadowPass = new()
{
name = "UTS Hair Shadow Map",
renderingLayerMask = _renderSetting.hairShadowSetting.CasterRenderingLayer,
targetColorBuffer = CustomPass.TargetBuffer.None,
targetDepthBuffer = CustomPass.TargetBuffer.None,
};
RegisterCustomPasses();
}
[RuntimeInitializeOnLoadMethod]
public static void RegisterCustomPasses()
{
CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.AfterOpaqueAndSky, _outlinePass);
CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.AfterOpaqueDepthAndNormal, _hairShadowPass);
_outlinePass.enabled = _renderSetting.outlineSetting.enable;
_hairShadowPass.SetEnable(_renderSetting.hairShadowSetting.enable);
}
public static void UnregisterGlobalCustomPass()
{
CustomPassVolume.UnregisterGlobalCustomPass(_outlinePass);
CustomPassVolume.UnregisterGlobalCustomPass(_hairShadowPass);
_hairShadowPass.Release();
}
public static void NotifyRendererSettingChanged()
{
_outlinePass.enabled = _renderSetting.outlineSetting.enable;
_outlinePass.renderingLayerMask = _renderSetting.outlineSetting.renderingLayer;
_hairShadowPass.SetEnable(_renderSetting.hairShadowSetting.enable);
_hairShadowPass.renderingLayerMask = _renderSetting.hairShadowSetting.CasterRenderingLayer;
}
}
}

View File

@@ -0,0 +1,80 @@
using UnityEngine;
using UnityEngine.Rendering.HighDefinition;
namespace Misaki.HdrpToon
{
#if UNITY_EDITOR
[UnityEditor.InitializeOnLoad]
#endif
public static class UTSRenderPassRegistrar
{
private static UTSRenderPassSettings _renderSetting;
private static UTSPass _utsPass;
private static UTSHairShadowPass _hairShadowPass;
private static UTSOutlinePass _outlinePass;
static UTSRenderPassRegistrar() => RegisterCustomPasses();
[RuntimeInitializeOnLoadMethod]
public static void RegisterCustomPasses()
{
_renderSetting = UTSRenderPassSettings.GetOrCreateSettings();
if (_renderSetting == null)
{
return;
}
_utsPass = new UTSPass()
{
name = "UTS Pass",
targetColorBuffer = CustomPass.TargetBuffer.None,
targetDepthBuffer = CustomPass.TargetBuffer.None,
};
_hairShadowPass = new()
{
name = "UTS Hair Shadow Map",
targetColorBuffer = CustomPass.TargetBuffer.None,
targetDepthBuffer = CustomPass.TargetBuffer.None,
};
_outlinePass = new()
{
name = "UTS Outline",
targetColorBuffer = CustomPass.TargetBuffer.None,
targetDepthBuffer = CustomPass.TargetBuffer.None,
};
CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.BeforeRendering, _utsPass);
CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.AfterOpaqueDepthAndNormal, _hairShadowPass);
CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.BeforePostProcess, _outlinePass);
NotifyRendererSettingChanged();
}
public static void UnregisterGlobalCustomPass()
{
CustomPassVolume.UnregisterGlobalCustomPass(_utsPass);
CustomPassVolume.UnregisterGlobalCustomPass(_hairShadowPass);
CustomPassVolume.UnregisterGlobalCustomPass(_outlinePass);
}
public static void NotifyRendererSettingChanged()
{
if (_hairShadowPass == null || _outlinePass == null)
{
return;
}
_hairShadowPass.enabled = _renderSetting.hairShadowSetting.enable;
_hairShadowPass.CurrentShadowQuality = _renderSetting.hairShadowSetting.shadowQuality;
if (!_renderSetting.hairShadowSetting.enable)
{
_hairShadowPass.Release();
}
_outlinePass.enabled = _renderSetting.outlineSetting.enable;
}
}
}

View File

@@ -1,198 +1,39 @@
using System; using System;
using UnityEditor;
using UnityEngine; using UnityEngine;
using UnityEngine.Rendering; using UnityEngine.Rendering;
namespace Unity.Toonshader namespace Misaki.HdrpToon
{ {
[Serializable, VolumeComponentMenu("Rendering/Unity Toon Shader")] [Serializable, VolumeComponentMenu("Rendering/UTS Renderer")]
public class UTSRenderer : VolumeComponent public class UTSRenderer : VolumeComponent
{ {
// flags public BoolParameter state = new(false, BoolParameter.DisplayType.EnumPopup);
bool _initialized = false;
const int kAdjustmentCurvePrecision = 128;
const string kCompensationPropName = "_ToonEvAdjustmentCompensation";
const string kExposureAdjustmentPropName = "_ToonEvAdjustmentCurve";
const string kExposureArrayPropName = "_ToonEvAdjustmentValueArray";
const string kExposureMinPropName = "_ToonEvAdjustmentValueMin";
const string kExposureMaxPropName = "_ToonEvAdjustmentValueMax";
const string kToonLightFilterPropName = "_ToonLightHiCutFilter";
const string kIgnoreVolumeExposurePropName = "_ToonIgnoreExposureMultiplier";
[SerializeField]
internal float[] _ExposureArray;
[SerializeField]
internal float _Max, _Min;
//CustomPassVolume customPassVolume = new();
//UTSOutlinePass outlinePass = new();
#if UNITY_EDITOR
#pragma warning restore CS0414
bool m_isCompiling = false;
#endif
public BoolParameter enable = new BoolParameter(false, BoolParameter.DisplayType.EnumPopup);
[Space] [Space]
[Header("Outline")] [Header("Outline")]
public BoolParameter enableOutline = new BoolParameter(false); public BoolParameter enableOutline = new(false);
public MinFloatParameter outlineMaxWidth = new MinFloatParameter(1.0f, 0.0f); public MinFloatParameter outlineMaxWidth = new(1.0f, 0.0f);
[Space] [Space]
[Header("Hair Shadow")] [Header("Hair Shadow")]
public BoolParameter enableHairShadow = new BoolParameter(false); public BoolParameter enableHairShadow = new(false);
public ClampedFloatParameter shadowDistance = new ClampedFloatParameter(5.0f, 0.0f, 20.0f); public ClampedFloatParameter shadowDistance = new(5.0f, 0.0f, 20.0f);
public ClampedFloatParameter shadowDistanceScale = new ClampedFloatParameter(0.5f, 0.0f, 1.0f); public ClampedFloatParameter shadowDistanceScale = new(0.5f, 0.0f, 1.0f);
public ClampedFloatParameter shadowDepthBias = new ClampedFloatParameter(0f, 0.0f, 0.01f); public ClampedFloatParameter shadowDepthBias = new(0f, 0.0f, 0.01f);
public FloatParameter shadowFadeIn = new FloatParameter(45f); public FloatParameter shadowFadeIn = new(45f);
public FloatParameter shadowFadeOut = new FloatParameter(50f); public FloatParameter shadowFadeOut = new(50f);
[Space] [Space]
[Header("Exposure")] [Header("Exposure")]
public BoolParameter ignoreVolumeExposure = new BoolParameter(false); public BoolParameter ignoreVolumeExposure = new(false);
public BoolParameter lightIntensityLimiter = new BoolParameter(false); public BoolParameter lightIntensityLimiter = new(false);
public MinFloatParameter compensation = new MinFloatParameter(0.0f, 0.0f); public MinFloatParameter compensation = new(0.0f, 0.0f);
public BoolParameter toonEVAdjustment = new BoolParameter(false); public BoolParameter toonEVAdjustment = new(false);
public AnimationCurveParameter adjustmentCurve = new AnimationCurveParameter(DefaultAnimationCurve()); public AnimationCurveParameter adjustmentCurve = new(DefaultAnimationCurve());
UTSRenderer() private static AnimationCurve DefaultAnimationCurve()
{
displayName = "UTS Renderer";
}
protected override void OnEnable()
{
base.OnEnable();
UTSDebugPanel.OnEnable();
Initialize();
}
protected override void OnDisable()
{
base.OnDisable();
UTSDebugPanel.OnDisable();
Release();
}
private void OnValidate()
{
if (!enable.value)
{
Release();
return;
}
Initialize();
if (!_initialized)
{
return;
}
// Fail safe in case the curve is deleted / has 0 point
var curve = adjustmentCurve.value;
if (curve == null || curve.length == 0)
{
_Min = 0f;
_Max = 0f;
for (var i = 0; i < kAdjustmentCurvePrecision; i++)
_ExposureArray[i] = 0.0f;
}
else
{
_Min = curve[0].time;
_Max = curve[curve.length - 1].time;
var step = (_Max - _Min) / (kAdjustmentCurvePrecision - 1f);
for (var i = 0; i < kAdjustmentCurvePrecision; i++)
_ExposureArray[i] = curve.Evaluate(_Min + step * i);
}
#if UNITY_EDITOR
// handle script recompile
if (EditorApplication.isCompiling && !m_isCompiling)
{
// on compile begin
m_isCompiling = true;
// Release(); no need
return; //
}
else if (!EditorApplication.isCompiling && m_isCompiling)
{
// on compile end
m_isCompiling = false;
}
#endif
Shader.SetGlobalFloatArray(kExposureArrayPropName, _ExposureArray);
Shader.SetGlobalFloat(kExposureMinPropName, _Min);
Shader.SetGlobalFloat(kExposureMaxPropName, _Max);
Shader.SetGlobalInt(kExposureAdjustmentPropName, toonEVAdjustment.value ? 1 : 0);
Shader.SetGlobalInt(kToonLightFilterPropName, lightIntensityLimiter.value ? 1 : 0);
Shader.SetGlobalInt(kIgnoreVolumeExposurePropName, ignoreVolumeExposure.value ? 1 : 0);
Shader.SetGlobalFloat(kCompensationPropName, compensation.value);
}
internal static AnimationCurve DefaultAnimationCurve()
{ {
return AnimationCurve.Linear(-10f, -10f, -1.32f, -1.32f); return AnimationCurve.Linear(-10f, -10f, -1.32f, -1.32f);
} }
void Initialize()
{
if (_initialized)
{
return;
}
#if UNITY_EDITOR
// initializing renderer can interfere GI baking. so wait until it is completed.
if (EditorApplication.isCompiling)
return;
#endif
if (_ExposureArray == null || _ExposureArray.Length != kAdjustmentCurvePrecision)
{
_ExposureArray = new float[kAdjustmentCurvePrecision];
}
_initialized = true;
}
protected override void OnDestroy()
{
base.OnDestroy();
Release();
}
new void Release()
{
if (_initialized)
{
_ExposureArray = null;
Shader.SetGlobalFloat(kExposureMinPropName, 0);
Shader.SetGlobalFloat(kExposureMaxPropName, 0);
Shader.SetGlobalInt(kExposureAdjustmentPropName, 0);
Shader.SetGlobalInt(kToonLightFilterPropName, 0);
Shader.SetGlobalInt(kIgnoreVolumeExposurePropName, 0);
Shader.SetGlobalFloat(kCompensationPropName, 0);
}
_initialized = false;
base.Release();
}
private void Reset()
{
OnDisable();
OnEnable();
DefaultAnimationCurve();
}
} }
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "Unity.Toonshader", "name": "Misaki.HdrpToon",
"rootNamespace": "Unity.Toonshader", "rootNamespace": "Misaki.HdrpToon",
"references": [ "references": [
"GUID:df380645f10b7bc4b97d4f5eb6303d95", "GUID:df380645f10b7bc4b97d4f5eb6303d95",
"GUID:3eae0364be2026648bf74846acb8a731", "GUID:3eae0364be2026648bf74846acb8a731",

View File

@@ -1,22 +1,15 @@
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
#if UNITY_EDITOR #if UNITY_EDITOR
using UnityEditor; using UnityEditor;
#endif #endif
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using UnityObject = UnityEngine.Object;
using System.Linq; using System.Linq;
namespace Unity.Rendering.Toon namespace Misaki.HdrpToon
{ {
[ExecuteAlways] [ExecuteAlways]
[DisallowMultipleComponent] [DisallowMultipleComponent]
[UTSHelpURL("ToonEVAdjustment")] public class ModelToonEvAdjustment : MonoBehaviour
internal class ModelToonEvAdjustment : MonoBehaviour
{ {
const string kCompensationPorpName = "_ToonEvAdjustmentCompensation"; const string kCompensationPorpName = "_ToonEvAdjustmentCompensation";
const string kExposureAdjustmentPropName = "_ToonEvAdjustmentCurve"; const string kExposureAdjustmentPropName = "_ToonEvAdjustmentCurve";
@@ -31,30 +24,20 @@ namespace Unity.Rendering.Toon
const int kAdjustmentCurvePrecision = 128; const int kAdjustmentCurvePrecision = 128;
public bool m_ToonLightHiCutFilter = false;
public bool m_ExposureAdjustmnt = false;
public bool m_IgnorVolumeExposure = false;
[SerializeField] public AnimationCurve m_AnimationCurve = DefaultAnimationCurve();
internal bool m_ToonLightHiCutFilter = false; public float[] m_ExposureArray;
[SerializeField] public float m_Max, m_Min;
internal bool m_ExposureAdjustmnt = false; public float m_Compensation;
[SerializeField]
internal bool m_IgnorVolumeExposure = false;
[SerializeField]
internal AnimationCurve m_AnimationCurve = DefaultAnimationCurve();
[SerializeField]
internal float[] m_ExposureArray;
[SerializeField]
internal float m_Max, m_Min;
[SerializeField]
internal float m_Compensation;
internal GameObject[] m_Objs; internal GameObject[] m_Objs;
[SerializeField] [SerializeField]
// [HideInInspector] // [HideInInspector]
Renderer[] m_Renderers; Renderer[] m_Renderers;
[SerializeField] [SerializeField]
// [HideInInspector] // [HideInInspector]
MaterialPropertyBlock[] m_MaterialPropertyBlocks; MaterialPropertyBlock[] m_MaterialPropertyBlocks;
#if UNITY_EDITOR #if UNITY_EDITOR
@@ -111,16 +94,16 @@ namespace Unity.Rendering.Toon
m_Min = 0f; m_Min = 0f;
m_Max = 0f; m_Max = 0f;
for (int i = 0; i < kAdjustmentCurvePrecision; i++) for (var i = 0; i < kAdjustmentCurvePrecision; i++)
m_ExposureArray[i] = 0.0f; m_ExposureArray[i] = 0.0f;
} }
else else
{ {
m_Min = curve[0].time; m_Min = curve[0].time;
m_Max = curve[curve.length - 1].time; m_Max = curve[curve.length - 1].time;
float step = (m_Max - m_Min) / (kAdjustmentCurvePrecision - 1f); var step = (m_Max - m_Min) / (kAdjustmentCurvePrecision - 1f);
for (int i = 0; i < kAdjustmentCurvePrecision; i++) for (var i = 0; i < kAdjustmentCurvePrecision; i++)
m_ExposureArray[i] = curve.Evaluate(m_Min + step * i); m_ExposureArray[i] = curve.Evaluate(m_Min + step * i);
} }
@@ -143,8 +126,8 @@ namespace Unity.Rendering.Toon
int length = m_Renderers.Length; var length = m_Renderers.Length;
for (int ii = 0; ii < length; ii++) for (var ii = 0; ii < length; ii++)
{ {
m_Renderers[ii].GetPropertyBlock(m_MaterialPropertyBlocks[ii]); m_Renderers[ii].GetPropertyBlock(m_MaterialPropertyBlocks[ii]);
@@ -209,13 +192,13 @@ namespace Unity.Rendering.Toon
m_Objs = new GameObject[1]; m_Objs = new GameObject[1];
m_Objs[0] = this.gameObject; m_Objs[0] = this.gameObject;
} }
int objCount = m_Objs.Length; var objCount = m_Objs.Length;
int rendererCount = 0; var rendererCount = 0;
List<Renderer> rendererList = new List<Renderer>(); var rendererList = new List<Renderer>();
for (int ii = 0; ii < objCount; ii++) for (var ii = 0; ii < objCount; ii++)
{ {
if (m_Objs[ii] == null ) if (m_Objs[ii] == null)
{ {
continue; continue;
} }
@@ -227,20 +210,20 @@ namespace Unity.Rendering.Toon
rendererCount++; rendererCount++;
rendererList.Add(renderer); rendererList.Add(renderer);
} }
GameObject[] childGameObjects = m_Objs[ii].GetComponentsInChildren<Transform>().Select(t => t.gameObject).ToArray(); var childGameObjects = m_Objs[ii].GetComponentsInChildren<Transform>().Select(t => t.gameObject).ToArray();
int childCount = childGameObjects.Length; var childCount = childGameObjects.Length;
for (int jj = 0; jj < childCount; jj++) for (var jj = 0; jj < childCount; jj++)
{ {
if (m_Objs[ii] == childGameObjects[jj]) if (m_Objs[ii] == childGameObjects[jj])
continue; continue;
var modelToonEvAdjustment = childGameObjects[jj].GetComponent<ModelToonEvAdjustment>(); var modelToonEvAdjustment = childGameObjects[jj].GetComponent<ModelToonEvAdjustment>();
if ( modelToonEvAdjustment != null ) if (modelToonEvAdjustment != null)
{ {
break; break;
} }
renderer = childGameObjects[jj].GetComponent<Renderer>(); renderer = childGameObjects[jj].GetComponent<Renderer>();
if ( renderer != null ) if (renderer != null)
{ {
rendererList.Add(renderer); rendererList.Add(renderer);
rendererCount++; rendererCount++;
@@ -254,7 +237,7 @@ namespace Unity.Rendering.Toon
m_Renderers = rendererList.ToArray(); m_Renderers = rendererList.ToArray();
for (int ii = 0; ii < rendererCount; ii++) for (var ii = 0; ii < rendererCount; ii++)
{ {
m_MaterialPropertyBlocks[ii] = new MaterialPropertyBlock(); m_MaterialPropertyBlocks[ii] = new MaterialPropertyBlock();
} }
@@ -272,10 +255,10 @@ namespace Unity.Rendering.Toon
if (m_initialized) if (m_initialized)
{ {
m_ExposureArray = null; m_ExposureArray = null;
if (m_Renderers != null ) if (m_Renderers != null)
{ {
int length = m_Renderers.Length; var length = m_Renderers.Length;
for (int ii = 0; ii < length; ii++) for (var ii = 0; ii < length; ii++)
{ {
m_Renderers[ii].SetPropertyBlock(null); m_Renderers[ii].SetPropertyBlock(null);
} }

View File

@@ -2,15 +2,14 @@ using UnityEngine;
#if UNITY_EDITOR #if UNITY_EDITOR
using UnityEditor; using UnityEditor;
#endif #endif
namespace Unity.Rendering.Toon
namespace Misaki.HdrpToon
{ {
[ExecuteAlways] [ExecuteAlways]
[DisallowMultipleComponent] [DisallowMultipleComponent]
[UTSHelpURL("ToonEVAdjustment")] [UTSHelpURL("ToonEVAdjustment")]
internal class SceneToonEvAdjustment : MonoBehaviour public class SceneToonEvAdjustment : MonoBehaviour
{ {
// flags // flags
bool m_initialized = false; bool m_initialized = false;
@@ -69,10 +68,11 @@ namespace Unity.Rendering.Toon
DefaultAnimationCurve(); DefaultAnimationCurve();
} }
internal static AnimationCurve DefaultAnimationCurve() public static AnimationCurve DefaultAnimationCurve()
{ {
return AnimationCurve.Linear(-10f, -10f, -1.32f, -1.32f); return AnimationCurve.Linear(-10f, -10f, -1.32f, -1.32f);
} }
void Update() void Update()
{ {
@@ -82,7 +82,7 @@ namespace Unity.Rendering.Toon
// Fail safe in case the curve is deleted / has 0 point // Fail safe in case the curve is deleted / has 0 point
AnimationCurve curve = m_AnimationCurve; var curve = m_AnimationCurve;
if (curve == null || curve.length == 0) if (curve == null || curve.length == 0)
@@ -90,16 +90,16 @@ namespace Unity.Rendering.Toon
m_Min = 0f; m_Min = 0f;
m_Max = 0f; m_Max = 0f;
for (int i = 0; i < kAdjustmentCurvePrecision; i++) for (var i = 0; i < kAdjustmentCurvePrecision; i++)
m_ExposureArray[i] = 0.0f; m_ExposureArray[i] = 0.0f;
} }
else else
{ {
m_Min = curve[0].time; m_Min = curve[0].time;
m_Max = curve[curve.length - 1].time; m_Max = curve[curve.length - 1].time;
float step = (m_Max - m_Min) / (kAdjustmentCurvePrecision - 1f); var step = (m_Max - m_Min) / (kAdjustmentCurvePrecision - 1f);
for (int i = 0; i < kAdjustmentCurvePrecision; i++) for (var i = 0; i < kAdjustmentCurvePrecision; i++)
m_ExposureArray[i] = curve.Evaluate(m_Min + step * i); m_ExposureArray[i] = curve.Evaluate(m_Min + step * i);
} }

View File

@@ -1,13 +1,8 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine; using UnityEngine;
#if UNITY_EDITOR #if UNITY_EDITOR
using UnityEditor;
#endif #endif
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering; namespace Misaki.HdrpToon
using UnityObject = UnityEngine.Object;
namespace Unity.Rendering.Toon
{ {
#if UNITY_2021_1_OR_NEWER #if UNITY_2021_1_OR_NEWER
internal class UTSHelpURLAttribute : HelpURLAttribute internal class UTSHelpURLAttribute : HelpURLAttribute

View File

@@ -1,8 +1,9 @@
{ {
"name": "com.misaki.hdrp-toon", "name": "com.misaki.hdrp-toon",
"version": "2.0.1", "version": "2.0.5",
"displayName": "HDRP Toon", "displayName": "HDRP Toon",
"description": "A high quality toon shader for High Definition Render Pipeline(HDRP)", "description": "A high quality toon shader for High Definition Render Pipeline(HDRP)",
"changelogUrl": "https://git.personalnas.com/Misaki/hdrp-toon/src/branch/develop/CHANGELOG.md",
"keywords": [ "keywords": [
"Toon", "Toon",
"HDRP", "HDRP",