13 Commits

Author SHA1 Message Date
4507ebdccf Fixed npm dependency issue
All checks were successful
Publish to Private NPM Registry / publish (push) Successful in 12s
2025-11-07 18:32:47 +09:00
448c295cfc Update gitea workflow
Some checks failed
Publish to Private NPM Registry / publish (push) Failing after 12s
2025-11-07 18:29:33 +09:00
7f807661d4 Merge branch 'release/3.0.0'
Some checks failed
Publish to Private NPM Registry / publish (push) Failing after 1m12s
# Conflicts:
#	package.json
2025-11-07 18:24:02 +09:00
49ad3bf7ca Add gitea workflow 2025-11-07 18:21:48 +09:00
600c8f65ac Updated the shadow visual. 2025-11-06 18:13:19 +09:00
bcba75a7d6 Added dots instancing support;
Fixed the problem that shader can compile when using emission color map;
2025-09-01 01:15:57 +09:00
e35650f052 Added GT Toon map;
Changed shadow bias from fixed to slope based;
2025-08-25 10:47:26 +09:00
973f617590 Added new stocking scope to shader gui;
Added new stocking surface feature;
Added unity 6.3 support;

Fixed the issue that ssr weight does not blend ibl and ssr properly;
Fixed the issue that material recive ssr regardless of specular ambient mode;
2025-08-17 13:10:38 +09:00
aeb4da48eb Added transparent depth pre pass;
Added transparent depth post pass;
Added transparent depth write;
Added transparent back then front render;
Added transparent motion vector write;
2025-05-25 00:03:26 +09:00
1a93e81edd Added stencil setup in UTSAPI;
Changed hair shadow length from screen space to world space;
2025-05-24 00:05:50 +09:00
5b2eb17148 Added translaprent support 2025-05-22 22:28:48 +09:00
84ad8ef993 Fixed the bug that UTSRenderPassSettings using editor only api during runtime. 2025-05-21 17:08:03 +09:00
59b46bce44 Added UTSAPI 2025-05-21 17:02:07 +09:00
46 changed files with 995 additions and 418 deletions

View File

@@ -0,0 +1,26 @@
name: Publish to Private NPM Registry
on:
push:
tags:
- "v*" # Trigger on tags like v1.0.0, v2.3, etc.
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
registry-url: "https://npm.personalnas.com/"
- name: Publish to private registry
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
npm publish --registry=https://npm.personalnas.com/

View File

@@ -1649,11 +1649,11 @@ namespace UnityEditor.Rendering.Toon
m_MaterialEditor.TexturePropertySingleLine(Styles.hairBlendingTargetMapText, hairBlendingMap); m_MaterialEditor.TexturePropertySingleLine(Styles.hairBlendingTargetMapText, hairBlendingMap);
EditorGUI.indentLevel--; EditorGUI.indentLevel--;
} }
material.SetShaderPassEnabled(UtsShaderPassName.HAIR_BLENDING_TARGET_PASS_NAME, isHairBlendingTargetEnabled); material.SetShaderPassEnabled(UTSPassName.HAIR_BLENDING_TARGET_PASS_NAME, isHairBlendingTargetEnabled);
SwitchKeyword(m_materialType); SwitchKeyword(m_materialType);
material.SetFloat(ShaderPropMaterialType, (float)m_materialType); material.SetFloat(ShaderPropMaterialType, (float)m_materialType);
material.SetShaderPassEnabled(UtsShaderPassName.HAIR_SHADOW_CASTER_PASS_NAME, m_materialType == MaterialType.FrontHair); material.SetShaderPassEnabled(UTSPassName.HAIR_SHADOW_CASTER_PASS_NAME, m_materialType == MaterialType.FrontHair);
void SwitchKeyword(MaterialType target) void SwitchKeyword(MaterialType target)
{ {
@@ -2347,18 +2347,18 @@ namespace UnityEditor.Rendering.Toon
internal static void SetupOverDrawTransparentObject(Material material) internal static void SetupOverDrawTransparentObject(Material material)
{ {
var srpDefaultLightModeTag = material.GetTag("LightMode", false, UtsShaderPassName.OUTLINE_PASS_NAME); var srpDefaultLightModeTag = material.GetTag("LightMode", false, UTSPassName.OUTLINE_PASS_NAME);
if (srpDefaultLightModeTag == UtsShaderPassName.OUTLINE_PASS_NAME) if (srpDefaultLightModeTag == UTSPassName.OUTLINE_PASS_NAME)
{ {
material.SetShaderPassEnabled(UtsShaderPassName.OUTLINE_PASS_NAME, true); material.SetShaderPassEnabled(UTSPassName.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, UtsShaderPassName.OUTLINE_PASS_NAME); var srpDefaultLightModeTag = material.GetTag("LightMode", false, UTSPassName.OUTLINE_PASS_NAME);
if (srpDefaultLightModeTag == UtsShaderPassName.OUTLINE_PASS_NAME) if (srpDefaultLightModeTag == UTSPassName.OUTLINE_PASS_NAME)
{ {
MaterialSetInt(material, srpDefaultColorMask, 15); MaterialSetInt(material, srpDefaultColorMask, 15);
MaterialSetInt(material, srpDefaultCullMode, (int)CullingMode.Frontface); MaterialSetInt(material, srpDefaultCullMode, (int)CullingMode.Frontface);
@@ -2368,12 +2368,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);
var srpDefaultLightModeTag = material.GetTag("LightMode", false, UtsShaderPassName.OUTLINE_PASS_NAME); var srpDefaultLightModeTag = material.GetTag("LightMode", false, UTSPassName.OUTLINE_PASS_NAME);
var isOutlineEnabled = true; var isOutlineEnabled = true;
if (srpDefaultLightModeTag == UtsShaderPassName.OUTLINE_PASS_NAME) if (srpDefaultLightModeTag == UTSPassName.OUTLINE_PASS_NAME)
{ {
const string kOutline = "Outline"; const string kOutline = "Outline";
isOutlineEnabled = material.GetShaderPassEnabled(UtsShaderPassName.OUTLINE_PASS_NAME); isOutlineEnabled = material.GetShaderPassEnabled(UTSPassName.OUTLINE_PASS_NAME);
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
isOutlineEnabled = EditorGUILayout.Toggle(kOutline, isOutlineEnabled); isOutlineEnabled = EditorGUILayout.Toggle(kOutline, isOutlineEnabled);
@@ -2382,11 +2382,11 @@ namespace UnityEditor.Rendering.Toon
m_MaterialEditor.RegisterPropertyChangeUndo(kOutline); m_MaterialEditor.RegisterPropertyChangeUndo(kOutline);
if (isOutlineEnabled) if (isOutlineEnabled)
{ {
material.SetShaderPassEnabled(UtsShaderPassName.OUTLINE_PASS_NAME, true); material.SetShaderPassEnabled(UTSPassName.OUTLINE_PASS_NAME, true);
} }
else else
{ {
material.SetShaderPassEnabled(UtsShaderPassName.OUTLINE_PASS_NAME, false); material.SetShaderPassEnabled(UTSPassName.OUTLINE_PASS_NAME, false);
} }
} }
} }

View File

@@ -1,6 +1,6 @@
using UnityEngine; using UnityEngine;
using static Misaki.HdrpToon.UtsShaderPropertyName; using static Misaki.HdrpToon.UTSPropertyName;
namespace Misaki.HdrpToon.Editor namespace Misaki.HdrpToon.Editor
{ {
@@ -49,7 +49,7 @@ namespace Misaki.HdrpToon.Editor
public static bool IsHairBlendingTarget(this Material material) public static bool IsHairBlendingTarget(this Material material)
{ {
return material.GetShaderPassEnabled(UtsShaderPassName.HAIR_BLENDING_TARGET_PASS_NAME); return material.GetShaderPassEnabled(UTSPassName.HAIR_BLENDING_TARGET_PASS_NAME);
} }
} }
} }

View File

@@ -5,20 +5,14 @@ namespace Misaki.HdrpToon.Editor
SurfaceOptions = 1 << 0, SurfaceOptions = 1 << 0,
ShadingColor = 1 << 1, ShadingColor = 1 << 1,
Shadow = 1 << 2, Shadow = 1 << 2,
MaterialFeature = 1 << 3, SurfaceInputs = 1 << 3,
SurfaceInputs = 1 << 4, Ambient = 1 << 4,
Ambient = 1 << 5, // Surface Features
Highlight = 1 << 6, AngelRing = 1 << 5,
Rimlight = 1 << 7, Rimlight = 1 << 6,
MatCap = 1 << 8, Stocking = 1 << 7,
Stocking = 1 << 9,
AngelRing = 1 << 10, Outline = 1 << 8,
Emission = 1 << 11, Advance = 1 << 9,
Outline = 1 << 12,
TessellationHDRP = 1 << 13,
SceneLight = 1 << 14,
EnvironmentalLightEffectiveness = 1 << 15,
MetaverseSettings = 1 << 16,
Advance = 1 << 17,
} }
} }

View File

@@ -2,11 +2,11 @@ using Misaki.ShaderGUI;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using static Misaki.HdrpToon.UtsShaderPropertyName.Advance; using static Misaki.HdrpToon.UTSPropertyName.Advance;
namespace Misaki.HdrpToon.Editor namespace Misaki.HdrpToon.Editor
{ {
public class AdvanceScope : MaterialUIScope<ShaderGUIExpandable> internal class AdvanceScope : MaterialUIScope<ShaderGUIExpandable>
{ {
private static class Properties private static class Properties
{ {
@@ -20,7 +20,7 @@ namespace Misaki.HdrpToon.Editor
private static class Styles private static class Styles
{ {
public static readonly GUIContent diffuseMinText = new("Minimal diffuse contribution", "Specifies the minimum contribution of the base color to the diffuse light. Keep it 0 to make sure energy conservation."); public static readonly GUIContent diffuseMinText = new("Minimal Diffuse Contribution", "Specifies the minimum contribution of the base color to the diffuse light. Keep it 0 to make sure energy conservation.");
public static readonly GUIContent lightIntensityMultiplierText = new("Light Intensity Multiplier", "Specifies the intensity multiplier of the light."); public static readonly GUIContent lightIntensityMultiplierText = new("Light Intensity Multiplier", "Specifies the intensity multiplier of the light.");
public static readonly GUIContent clampLightColorText = new("Clamp Light Color", "Specifies whether to clamp the light color."); public static readonly GUIContent clampLightColorText = new("Clamp Light Color", "Specifies whether to clamp the light color.");
@@ -32,7 +32,7 @@ namespace Misaki.HdrpToon.Editor
protected override GUIContent Header => EditorGUIUtility.TrTextContent("Advance Settings"); protected override GUIContent Header => EditorGUIUtility.TrTextContent("Advance Settings");
public override void LoadMaterialProperties() protected override void LoadMaterialProperties()
{ {
Properties.diffuseMin = FindProperty(MINIMAL_DIFFUSE_CONTRIBUTION); Properties.diffuseMin = FindProperty(MINIMAL_DIFFUSE_CONTRIBUTION);

View File

@@ -4,7 +4,7 @@ using UnityEngine;
namespace Misaki.HdrpToon.Editor namespace Misaki.HdrpToon.Editor
{ {
public class AmbientScope : MaterialUIScope<ShaderGUIExpandable> internal class AmbientScope : MaterialUIScope<ShaderGUIExpandable>
{ {
protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.Ambient; protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.Ambient;
protected override GUIContent Header => new("Ambient Settings"); protected override GUIContent Header => new("Ambient Settings");
@@ -52,7 +52,7 @@ namespace Misaki.HdrpToon.Editor
public static readonly GUIContent ssrWeightText = new("SSR Weight", "SSR Weight"); public static readonly GUIContent ssrWeightText = new("SSR Weight", "SSR Weight");
} }
public override void LoadMaterialProperties() protected override void LoadMaterialProperties()
{ {
Properties.indirectDiffuseMode = FindProperty("_Indirect_Diffuse_Mode"); Properties.indirectDiffuseMode = FindProperty("_Indirect_Diffuse_Mode");
Properties.indirectSpecularMode = FindProperty("_Indirect_Specular_Mode"); Properties.indirectSpecularMode = FindProperty("_Indirect_Specular_Mode");
@@ -99,10 +99,8 @@ namespace Misaki.HdrpToon.Editor
private static void DrawIndirectSpecularHeader() private static void DrawIndirectSpecularHeader()
{ {
EditorGUILayout.Space(); EditorGUILayout.Space();
using (var indentLevelScope = new EditorGUI.IndentLevelScope(-1)) using var indentLevelScope = new EditorGUI.IndentLevelScope(-1);
{ EditorGUILayout.LabelField("Indirect Specular", EditorStyles.boldLabel);
EditorGUILayout.LabelField("Indirect Specular", EditorStyles.boldLabel);
}
} }
protected override void DrawContent() protected override void DrawContent()

View File

@@ -3,7 +3,7 @@ using System.Linq;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using static Misaki.HdrpToon.UtsShaderPropertyName.AngelRing; using static Misaki.HdrpToon.UTSPropertyName.AngelRing;
namespace Misaki.HdrpToon.Editor namespace Misaki.HdrpToon.Editor
{ {
@@ -32,7 +32,7 @@ namespace Misaki.HdrpToon.Editor
protected override GUIContent Header => EditorGUIUtility.TrTextContent("Angel Ring Settings"); protected override GUIContent Header => EditorGUIUtility.TrTextContent("Angel Ring Settings");
public override void LoadMaterialProperties() protected override void LoadMaterialProperties()
{ {
Properties.angelRingColor = FindProperty(ANGEL_RING_COLOR); Properties.angelRingColor = FindProperty(ANGEL_RING_COLOR);
Properties.angelRingColorMap = FindProperty(ANGEL_RING_COLOR_MAP); Properties.angelRingColorMap = FindProperty(ANGEL_RING_COLOR_MAP);

View File

@@ -1,8 +1,10 @@
using Misaki.ShaderGUI; using Misaki.ShaderGUI;
using System.Linq;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using static Misaki.HdrpToon.UtsShaderPropertyName.Outline; using static Misaki.HdrpToon.UTSPropertyName.Outline;
using static UnityEditor.EditorGUI;
namespace Misaki.HdrpToon.Editor namespace Misaki.HdrpToon.Editor
{ {
@@ -46,7 +48,7 @@ namespace Misaki.HdrpToon.Editor
protected override GUIContent Header => EditorGUIUtility.TrTextContent("Outline Settings"); protected override GUIContent Header => EditorGUIUtility.TrTextContent("Outline Settings");
public override void LoadMaterialProperties() protected override void LoadMaterialProperties()
{ {
Properties.outlineState = FindProperty(OUTLINE_STATE); Properties.outlineState = FindProperty(OUTLINE_STATE);
@@ -71,6 +73,14 @@ namespace Misaki.HdrpToon.Editor
if (Properties.outlineState.GetBooleanValue()) if (Properties.outlineState.GetBooleanValue())
{ {
var isTransparentAny = materials.Any(m => m.GetInteger(UTSPropertyName.SurfaceOptions.SURFACE_TYPE) == 1);
if (isTransparentAny)
{
EditorGUILayout.HelpBox("Outline is not supported in transparent mode.", MessageType.Warning);
}
using var settingScope = new DisabledGroupScope(isTransparentAny);
EditorGUILayout.Space(); EditorGUILayout.Space();
editor.TexturePropertySingleLine(Styles.outlineWidthText, Properties.outlineWidthMap, Properties.outlineWidth); editor.TexturePropertySingleLine(Styles.outlineWidthText, Properties.outlineWidthMap, Properties.outlineWidth);
editor.TexturePropertySingleLine(Styles.outlineColorText, Properties.outlineColorMap, Properties.outlineColor); editor.TexturePropertySingleLine(Styles.outlineColorText, Properties.outlineColorMap, Properties.outlineColor);

View File

@@ -3,11 +3,11 @@ using System.Linq;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using static Misaki.HdrpToon.UtsShaderPropertyName.RimLight; using static Misaki.HdrpToon.UTSPropertyName.RimLight;
namespace Misaki.HdrpToon.Editor namespace Misaki.HdrpToon.Editor
{ {
public class RimLightScope : MaterialUIScope<ShaderGUIExpandable> internal class RimLightScope : MaterialUIScope<ShaderGUIExpandable>
{ {
private static class Properties private static class Properties
{ {
@@ -43,7 +43,7 @@ namespace Misaki.HdrpToon.Editor
protected override GUIContent Header => EditorGUIUtility.TrTextContent("Rim Light Settings"); protected override GUIContent Header => EditorGUIUtility.TrTextContent("Rim Light Settings");
protected override bool ShowSection => materials.All(mat => mat.HasFeature(SurfaceFeature.RimLight)); protected override bool ShowSection => materials.All(mat => mat.HasFeature(SurfaceFeature.RimLight));
public override void LoadMaterialProperties() protected override void LoadMaterialProperties()
{ {
Properties.rimLightColor = FindProperty(RIM_LIGHT_COLOR); Properties.rimLightColor = FindProperty(RIM_LIGHT_COLOR);
Properties.rimLightIntensity = FindProperty(RIM_LIGHT_INTENSITY); Properties.rimLightIntensity = FindProperty(RIM_LIGHT_INTENSITY);

View File

@@ -5,7 +5,7 @@ using UnityEngine;
namespace Misaki.HdrpToon.Editor namespace Misaki.HdrpToon.Editor
{ {
public class ShadingColorScope : MaterialUIScope<ShaderGUIExpandable> internal class ShadingColorScope : MaterialUIScope<ShaderGUIExpandable>
{ {
private static class Properties private static class Properties
{ {
@@ -85,7 +85,7 @@ namespace Misaki.HdrpToon.Editor
} }
} }
public override void LoadMaterialProperties() protected override void LoadMaterialProperties()
{ {
Properties.shadingRampMapState = FindProperty("_Use_Shading_Ramp_Map"); Properties.shadingRampMapState = FindProperty("_Use_Shading_Ramp_Map");

View File

@@ -30,7 +30,7 @@ namespace Misaki.HdrpToon.Editor
protected override GUIContent Header => EditorGUIUtility.TrTextContent("Shadow Settings"); protected override GUIContent Header => EditorGUIUtility.TrTextContent("Shadow Settings");
public override void LoadMaterialProperties() protected override void LoadMaterialProperties()
{ {
Properties.receiveLightShadow = FindProperty("_Receive_Light_Shadow"); Properties.receiveLightShadow = FindProperty("_Receive_Light_Shadow");
Properties.receiveScreenSpaceShadow = FindProperty("_Receive_Screen_Space_Shadow"); Properties.receiveScreenSpaceShadow = FindProperty("_Receive_Screen_Space_Shadow");

View File

@@ -1,22 +1,52 @@
using Misaki.ShaderGUI; using Misaki.ShaderGUI;
using System.Linq;
using UnityEditor;
using UnityEngine; using UnityEngine;
using static Misaki.HdrpToon.UTSPropertyName.Stocking;
namespace Misaki.HdrpToon.Editor namespace Misaki.HdrpToon.Editor
{ {
public class StockingScope : MaterialUIScope<ShaderGUIExpandable> internal class StockingScope : MaterialUIScope<ShaderGUIExpandable>
{ {
protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.Stocking; private static class Properties
protected override GUIContent Header => throw new System.NotImplementedException();
public override void LoadMaterialProperties()
{ {
throw new System.NotImplementedException(); public static MaterialProperty stockingFresnelWidth;
public static MaterialProperty stockingSparkleSpacing;
public static MaterialProperty stockingSparkleAmount;
public static MaterialProperty stockingSparkleSize;
public static MaterialProperty stockingSparkleIntensity;
}
private static class Styles
{
public static readonly GUIContent stockingFresnelWidthText = new("Fresnel Width", "Set the width of the fresnel effect for the stocking.");
public static readonly GUIContent stockingSparkleSpacingText = new("Sparkle Spacing", "Set the spacing between sparkles on the stocking.");
public static readonly GUIContent stockingSparkleAmountText = new("Sparkle Amount", "Set the amount of sparkles on the stocking.");
public static readonly GUIContent stockingSparkleSizeText = new("Sparkle Size", "Set the size of the sparkles on the stocking.");
public static readonly GUIContent stockingSparkleIntensityText = new("Sparkle Intensity", "Set the intensity of the sparkle effect for the stocking.");
}
protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.Stocking;
protected override GUIContent Header => EditorGUIUtility.TrTextContent("Stocking Settings");
protected override bool ShowSection => materials.All(mat => mat.HasFeature(SurfaceFeature.Stocking));
protected override void LoadMaterialProperties()
{
Properties.stockingFresnelWidth = FindProperty(STOCKING_FRESNEL_WIDTH);
Properties.stockingSparkleSpacing = FindProperty(STOCKING_SPARKLE_SPACING);
Properties.stockingSparkleAmount = FindProperty(STOCKING_SPARKLE_AMOUNT);
Properties.stockingSparkleSize = FindProperty(STOCKING_SPARKLE_SIZE);
Properties.stockingSparkleIntensity = FindProperty(STOCKING_SPARKLE_INTENSITY);
} }
protected override void DrawContent() protected override void DrawContent()
{ {
throw new System.NotImplementedException(); editor.ShaderProperty(Properties.stockingFresnelWidth, Styles.stockingFresnelWidthText);
editor.ShaderProperty(Properties.stockingSparkleSpacing, Styles.stockingSparkleSpacingText);
editor.ShaderProperty(Properties.stockingSparkleAmount, Styles.stockingSparkleAmountText);
editor.ShaderProperty(Properties.stockingSparkleSize, Styles.stockingSparkleSizeText);
editor.ShaderProperty(Properties.stockingSparkleIntensity, Styles.stockingSparkleIntensityText);
} }
} }
} }

View File

@@ -4,11 +4,11 @@ using UnityEditor;
using UnityEditor.Rendering; using UnityEditor.Rendering;
using UnityEngine; using UnityEngine;
using static Misaki.HdrpToon.UtsShaderPropertyName.SurfaceInputs; using static Misaki.HdrpToon.UTSPropertyName.SurfaceInputs;
namespace Misaki.HdrpToon.Editor namespace Misaki.HdrpToon.Editor
{ {
public class SurfaceInputsScope : MaterialUIScope<ShaderGUIExpandable> internal class SurfaceInputsScope : MaterialUIScope<ShaderGUIExpandable>
{ {
private static class Properties private static class Properties
{ {
@@ -75,7 +75,7 @@ namespace Misaki.HdrpToon.Editor
protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.SurfaceInputs; protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.SurfaceInputs;
protected override GUIContent Header => new("Surface Inputs"); protected override GUIContent Header => new("Surface Inputs");
public override void LoadMaterialProperties() protected override void LoadMaterialProperties()
{ {
Properties.normalMap = FindProperty("_NormalMap"); Properties.normalMap = FindProperty("_NormalMap");
Properties.normalMapScale = FindProperty("_NormalScale"); Properties.normalMapScale = FindProperty("_NormalScale");

View File

@@ -2,18 +2,29 @@ using Misaki.ShaderGUI;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using static Misaki.HdrpToon.UTSPropertyName.SurfaceOptions;
namespace Misaki.HdrpToon.Editor namespace Misaki.HdrpToon.Editor
{ {
internal class SurfaceOptionsScope : MaterialUIScope<ShaderGUIExpandable> internal class SurfaceOptionsScope : MaterialUIScope<ShaderGUIExpandable>
{ {
private static class Properties private static class Properties
{ {
public static MaterialProperty transparentMode; public static MaterialProperty surfaceType;
public static MaterialProperty fogOnTransparent;
public static MaterialProperty transparentDepthPrepassEnable;
public static MaterialProperty transparentDepthPostpassEnable;
public static MaterialProperty transparentBackfaceEnable;
public static MaterialProperty transparentZWrite;
public static MaterialProperty receivesSSRTransparent;
public static MaterialProperty transparentWritingMotionVec;
public static MaterialProperty alphaClipEnable; public static MaterialProperty alphaClipEnable;
public static MaterialProperty alphaClip; public static MaterialProperty alphaClip;
public static MaterialProperty cullMode; public static MaterialProperty cullMode;
public static MaterialProperty doubleSidedNormalMode;
public static MaterialProperty shadingMode; public static MaterialProperty shadingMode;
public static MaterialProperty materialType; public static MaterialProperty materialType;
public static MaterialProperty pbrMode; public static MaterialProperty pbrMode;
@@ -24,12 +35,20 @@ namespace Misaki.HdrpToon.Editor
private static class Styles private static class Styles
{ {
public static readonly GUIContent transparentModeText = new("Transparent Mode", "Enable different modes that allow the simulation of a variety of transparent objects."); public static readonly GUIContent transparentModeText = new("Surface Type", "Controls the surface type of the material.");
public static readonly GUIContent fogOnTransparentText = new("Fog On Transparent", "Enable to apply fog effect on transparent objects.");
public static readonly GUIContent transparentDepthPrepassEnableText = new("Depth Prepass", "Enable to perform a depth prepass for transparent objects.");
public static readonly GUIContent transparentDepthPostpassEnableText = new("Depth Postpass", "Enable to perform a depth postpass for transparent objects.");
public static readonly GUIContent transparentBackfaceEnableText = new("Back Then Front Rendering", "Enable to render the back faces of transparent objects first, then the front faces.");
public static readonly GUIContent transparentZWriteText = new("Depth Write", "Enable to write depth for transparent objects. This is useful for correct depth testing with other transparent objects.");
public static readonly GUIContent receivesSSRTransparentText = new("Receives SSR", "Enable to allow transparent objects to receive Screen Space Reflections (SSR).");
public static readonly GUIContent transparentWritingMotionVec = new("Motion Vectors Write", "Enable to write motion vectors for transparent objects.");
public static readonly GUIContent alphaClipEnableText = new("Alpha Clipping", "Enable alpha clipping."); public static readonly GUIContent alphaClipEnableText = new("Alpha Clipping", "Enable alpha clipping.");
public static readonly GUIContent alphaClipText = new("Alpha Clipping Threshold", "Threshold for alpha clipping."); public static readonly GUIContent alphaClipText = new("Alpha Clipping Threshold", "Threshold for alpha clipping.");
public static readonly GUIContent cullingModeText = new("Culling Mode", "Controls the sides of polygons that should not be drawn (culled)."); public static readonly GUIContent cullingModeText = new("Culling Mode", "Controls the sides of polygons that should not be drawn (culled).");
public static readonly GUIContent doubleSidedNormalModeText = new("Double Sided Mode", "Controls the normal mode for double-sided rendering.");
public static readonly GUIContent shadingModeText = new("Shading Color Mode", "Specifies the shading grade mode."); public static readonly GUIContent shadingModeText = new("Shading Color Mode", "Specifies the shading grade mode.");
public static readonly GUIContent materialTypeText = new("Material Type", "Specifies the material type."); public static readonly GUIContent materialTypeText = new("Material Type", "Specifies the material type.");
public static readonly GUIContent pbrModeText = new("PBR Mode", "Specifies PBR model mode."); public static readonly GUIContent pbrModeText = new("PBR Mode", "Specifies PBR model mode.");
@@ -42,58 +61,68 @@ namespace Misaki.HdrpToon.Editor
protected override GUIContent Header => EditorGUIUtility.TrTextContent("Surface Options"); protected override GUIContent Header => EditorGUIUtility.TrTextContent("Surface Options");
public override void LoadMaterialProperties() protected override void LoadMaterialProperties()
{ {
Properties.transparentMode = FindProperty("_TransparentEnabled"); Properties.surfaceType = FindProperty(SURFACE_TYPE);
Properties.alphaClipEnable = FindProperty("_AlphaCutoffEnable"); Properties.fogOnTransparent = FindProperty(FOG_ON_TRANSPARENT);
Properties.alphaClip = FindProperty("_AlphaCutoff"); Properties.transparentDepthPrepassEnable = FindProperty(TRANSPARENT_DEPTH_PREPASS_ENABLE);
Properties.transparentDepthPostpassEnable = FindProperty(TRANSPARENT_DEPTH_POSTPASS_ENABLE);
Properties.transparentBackfaceEnable = FindProperty(TRANSPARENT_BACKFACE_ENABLE);
Properties.transparentZWrite = FindProperty(TRANSPARENT_Z_WRITE);
Properties.receivesSSRTransparent = FindProperty(RECEIVES_SSR_TRANSPARENT);
Properties.transparentWritingMotionVec = FindProperty(TRANSPARENT_WRITING_MOTION_VEC);
Properties.cullMode = FindProperty("_CullMode"); Properties.alphaClipEnable = FindProperty(ALPHA_CLIP_ENABLE);
Properties.shadingMode = FindProperty("_Shading_Mode"); Properties.alphaClip = FindProperty(ALPHA_CUTOFF);
Properties.materialType = FindProperty("_Material_Type"); Properties.cullMode = FindProperty(CULL_MODE);
Properties.pbrMode = FindProperty("_PBR_Mode"); Properties.doubleSidedNormalMode = FindProperty(DOUBLE_SIDED_NORMAL_MODE);
Properties.hairBlendingTarget = FindProperty("_HairBlendingTarget"); Properties.shadingMode = FindProperty(SHADING_MODE);
Properties.surfaceFeatures = FindProperty("_SurfaceFeatures"); Properties.materialType = FindProperty(MATERIAL_TYPE);
Properties.pbrMode = FindProperty(PBR_MODE);
Properties.hairBlendingTarget = FindProperty(HAIR_BLENDING_TARGET);
Properties.surfaceFeatures = FindProperty(SURFACE_FEATURE);
} }
protected override void DrawContent() protected override void DrawContent()
{ {
editor.ShaderProperty(Properties.transparentMode, Styles.transparentModeText); editor.ShaderProperty(Properties.surfaceType, Styles.transparentModeText);
using (new EditorGUI.IndentLevelScope())
{
if (Properties.surfaceType.GetBooleanValue())
{
editor.ShaderProperty(Properties.fogOnTransparent, Styles.fogOnTransparentText);
editor.ShaderProperty(Properties.transparentDepthPrepassEnable, Styles.transparentDepthPrepassEnableText);
editor.ShaderProperty(Properties.transparentDepthPostpassEnable, Styles.transparentDepthPostpassEnableText);
editor.ShaderProperty(Properties.transparentBackfaceEnable, Styles.transparentBackfaceEnableText);
editor.ShaderProperty(Properties.transparentZWrite, Styles.transparentZWriteText);
editor.ShaderProperty(Properties.receivesSSRTransparent, Styles.receivesSSRTransparentText);
editor.ShaderProperty(Properties.transparentWritingMotionVec, Styles.transparentWritingMotionVec);
}
editor.ShaderProperty(Properties.cullMode, Styles.cullingModeText);
if (Properties.cullMode.intValue == 0)
{
using (new EditorGUI.IndentLevelScope())
{
editor.ShaderProperty(Properties.doubleSidedNormalMode, Styles.doubleSidedNormalModeText);
}
}
}
editor.ShaderProperty(Properties.alphaClipEnable, Styles.alphaClipEnableText); editor.ShaderProperty(Properties.alphaClipEnable, Styles.alphaClipEnableText);
if (Properties.alphaClipEnable.GetBooleanValue()) if (Properties.alphaClipEnable.GetBooleanValue())
{ {
EditorGUI.indentLevel++; using var s = new EditorGUI.IndentLevelScope();
editor.ShaderProperty(Properties.alphaClip, Styles.alphaClipText); editor.ShaderProperty(Properties.alphaClip, Styles.alphaClipText);
EditorGUI.indentLevel--;
} }
editor.ShaderProperty(Properties.cullMode, Styles.cullingModeText);
editor.ShaderProperty(Properties.shadingMode, Styles.shadingModeText); editor.ShaderProperty(Properties.shadingMode, Styles.shadingModeText);
EditorGUI.BeginChangeCheck();
editor.ShaderProperty(Properties.materialType, Styles.materialTypeText); editor.ShaderProperty(Properties.materialType, Styles.materialTypeText);
if (EditorGUI.EndChangeCheck())
{
foreach (var material in materials)
{
material.SetShaderPassEnabled(UtsShaderPassName.HAIR_SHADOW_CASTER_PASS_NAME, Properties.materialType.GetEnumValue<MaterialType>() == MaterialType.FrontHair);
}
}
editor.ShaderProperty(Properties.pbrMode, Styles.pbrModeText); editor.ShaderProperty(Properties.pbrMode, Styles.pbrModeText);
EditorGUI.BeginChangeCheck();
editor.ShaderProperty(Properties.hairBlendingTarget, Styles.hairBlendingTargetText); editor.ShaderProperty(Properties.hairBlendingTarget, Styles.hairBlendingTargetText);
if (EditorGUI.EndChangeCheck())
{
foreach (var material in materials)
{
material.SetShaderPassEnabled(UtsShaderPassName.HAIR_BLENDING_TARGET_PASS_NAME, Properties.hairBlendingTarget.GetBooleanValue());
}
}
editor.ShaderProperty(Properties.surfaceFeatures, Styles.surfaceFeaturesText); editor.ShaderProperty(Properties.surfaceFeatures, Styles.surfaceFeaturesText);
} }
} }

View File

@@ -1,7 +1,6 @@
using Misaki.ShaderGUI; using Misaki.ShaderGUI;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using UnityEngine.Rendering;
namespace Misaki.HdrpToon.Editor namespace Misaki.HdrpToon.Editor
{ {
@@ -11,24 +10,9 @@ namespace Misaki.HdrpToon.Editor
public override void ValidateMaterial(Material material) public override void ValidateMaterial(Material material)
{ {
material.SetShaderPassEnabled(UtsShaderPassName.HAIR_SHADOW_CASTER_PASS_NAME, (MaterialType)material.GetInteger("_Material_Type") == MaterialType.FrontHair); UTSAPI.SetupPass(material);
material.SetShaderPassEnabled(UtsShaderPassName.HAIR_BLENDING_TARGET_PASS_NAME, material.GetInteger("_HairBlendingTarget") == 1); UTSAPI.SetupKeywords(material);
UTSAPI.SetupProperties(material);
if (material.GetInteger("_AlphaCutoffEnable") > 0.0f)
{
material.SetInt("_ZTestGBuffer", (int)CompareFunction.Equal);
}
else
{
material.SetInt("_ZTestGBuffer", (int)CompareFunction.LessEqual);
}
//if (surfaceType == SurfaceType.Opaque)
//{
material.SetInt("_ZTestDepthEqualForOpaque", (int)CompareFunction.Equal);
//}
//else
// material.SetInt(kZTestDepthEqualForOpaque, (int)material.GetTransparentZTest());
} }
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties) public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
@@ -47,15 +31,19 @@ namespace Misaki.HdrpToon.Editor
private void OnInitialize(MaterialEditor materialEditor, MaterialProperty[] properties) private void OnInitialize(MaterialEditor materialEditor, MaterialProperty[] properties)
{ {
AddUIScope(new SurfaceOptionsScope()); AddUIScope<SurfaceOptionsScope>();
AddUIScope(new ShadingColorScope()); AddUIScope<ShadingColorScope>();
AddUIScope(new ShadowScope()); AddUIScope<ShadowScope>();
AddUIScope(new SurfaceInputsScope()); AddUIScope<SurfaceInputsScope>();
AddUIScope(new AmbientScope()); AddUIScope<AmbientScope>();
AddUIScope(new RimLightScope());
AddUIScope(new AngelRingScope()); // Surface Features
AddUIScope(new OutlineScope()); AddUIScope<AngelRingScope>();
AddUIScope(new AdvanceScope()); AddUIScope<RimLightScope>();
AddUIScope<StockingScope>();
AddUIScope<OutlineScope>();
AddUIScope<AdvanceScope>();
Initialize(materialEditor, properties); Initialize(materialEditor, properties);

View File

@@ -2,7 +2,7 @@
namespace Misaki.HdrpToon namespace Misaki.HdrpToon
{ {
public static class UtsShaderPassName public static class UTSPassName
{ {
public const string OUTLINE_PASS_NAME = "Outline"; public const string OUTLINE_PASS_NAME = "Outline";
public const string HAIR_SHADOW_CASTER_PASS_NAME = "HairShadowCaster"; public const string HAIR_SHADOW_CASTER_PASS_NAME = "HairShadowCaster";

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 9522e8a96ee83bb4c9bc6445747d6f45

View File

@@ -1,13 +1,67 @@
namespace Misaki.HdrpToon namespace Misaki.HdrpToon
{ {
internal static class UtsShaderPropertyName internal static class UTSPropertyName
{ {
public static class InternalProperties
{
public const string SURFACE_TYPE = "_SurfaceType";
public const string DOUBLE_SIDED_CONSTANTS = "_DoubleSidedConstants";
public const string TRANSPARENT_DEPTH_PREPASS_ENABLE = "_TransparentDepthPrepassEnable";
public const string TRANSPARENT_BACKFACE_ENABLE = "_TransparentBackfaceEnable";
public const string TRANSPARENT_DEPTH_POSTPASS_ENABLE = "_TransparentDepthPostpassEnable";
public const string TRANSPARENT_CULL_MODE = "_TransparentCullMode";
public const string OPAQUE_CULL_MODE = "_OpaqueCullMode";
public const string SRC_BLEND = "_SrcBlend";
public const string DEST_BLEND = "_DstBlend";
public const string DEST_BLEND2 = "_DstBlend2";
public const string ALPHA_SRC_BLEND = "_AlphaSrcBlend";
public const string ALPHA_DEST_BLEND = "_AlphaDstBlend";
public const string CULL_MODE_FORWARD = "_CullModeForward";
public const string ZTEST_GBUFFER = "_ZTestGBuffer";
public const string ZTEST_DEPTH_EQUAL_FOR_OPAQUE = "_ZTestDepthEqualForOpaque";
public const string ZTEST_TRANSPARENT = "_ZTestTransparent";
public const string ZWRITE = "_ZWrite";
public const string STENCIL_REF = "_StencilRef";
public const string STENCIL_WRITE_MASK = "_StencilWriteMask";
public const string STENCIL_REF_DEPTH = "_StencilRefDepth";
public const string STENCIL_WRITE_MASK_DEPTH = "_StencilWriteMaskDepth";
public const string STENCIL_REF_G_BUFFER = "_StencilRefGBuffer";
public const string STENCIL_WRITE_MASK_G_BUFFER = "_StencilWriteMaskGBuffer";
public const string STENCIL_REF_MV = "_StencilRefMV";
public const string STENCIL_WRITE_MASK_MV = "_StencilWriteMaskMV";
public const string STENCIL_REF_DISTORTION_VEC = "_StencilRefDistortionVec";
public const string STENCIL_WRITE_MASK_DISTORTION_VEC = "_StencilWriteMaskDistortionVec";
}
public static class SurfaceOptions public static class SurfaceOptions
{ {
public const string SURFACE_TYPE = "_SurfaceType";
public const string FOG_ON_TRANSPARENT = "_FogOnTransparent";
public const string TRANSPARENT_DEPTH_PREPASS_ENABLE = "_TransparentDepthPrepassEnable";
public const string TRANSPARENT_BACKFACE_ENABLE = "_TransparentBackfaceEnable";
public const string TRANSPARENT_DEPTH_POSTPASS_ENABLE = "_TransparentDepthPostpassEnable";
public const string TRANSPARENT_Z_WRITE = "_TransparentZWrite";
public const string RECEIVES_SSR_TRANSPARENT = "_ReceivesSSRTransparent";
public const string TRANSPARENT_WRITING_MOTION_VEC = "_TransparentWritingMotionVec";
public const string ALPHA_CLIP_ENABLE = "_AlphaCutoffEnable";
public const string ALPHA_CUTOFF = "_AlphaCutoff";
public const string CULL_MODE = "_CullMode";
public const string DOUBLE_SIDED_NORMAL_MODE = "_DoubleSidedNormalMode";
public const string SHADING_MODE = "_Shading_Mode"; public const string SHADING_MODE = "_Shading_Mode";
public const string PBR_MODE = "_PBR_Mode";
public const string SURFACE_FEATURE = "_SurfaceFeatures";
public const string MATERIAL_TYPE = "_Material_Type"; public const string MATERIAL_TYPE = "_Material_Type";
public const string PBR_MODE = "_PBR_Mode";
public const string HAIR_BLENDING_TARGET = "_HairBlendingTarget";
public const string SURFACE_FEATURE = "_SurfaceFeatures";
} }
public static class SurfaceInputs public static class SurfaceInputs
@@ -22,6 +76,15 @@ namespace Misaki.HdrpToon
public const string EMISSIVE_EXPOSURE_WEIGHT = "_EmissiveExposureWeight"; public const string EMISSIVE_EXPOSURE_WEIGHT = "_EmissiveExposureWeight";
} }
public static class AngelRing
{
public const string ANGEL_RING_COLOR = "_AngelRingColor";
public const string ANGEL_RING_COLOR_MAP = "_AngelRingColorMap";
public const string ANGEL_RING_INTENSITY = "_AngelRingIntensity";
public const string ANGEL_RING_OFFSET_U = "_AngelRingOffsetU";
public const string ANGEL_RING_OFFSET_V = "_AngelRingOffsetV";
}
public static class RimLight public static class RimLight
{ {
public const string RIM_LIGHT_COLOR = "_RimLightColor"; public const string RIM_LIGHT_COLOR = "_RimLightColor";
@@ -46,13 +109,13 @@ namespace Misaki.HdrpToon
public const string RIM_LIGHT_MASK_LEVEL = "_Tweak_RimLightMaskLevel"; public const string RIM_LIGHT_MASK_LEVEL = "_Tweak_RimLightMaskLevel";
} }
public static class AngelRing public static class Stocking
{ {
public const string ANGEL_RING_COLOR = "_AngelRingColor"; public const string STOCKING_FRESNEL_WIDTH = "_StockingFresnelWidth";
public const string ANGEL_RING_COLOR_MAP = "_AngelRingColorMap"; public const string STOCKING_SPARKLE_SPACING = "_StockingSparkleSpacing";
public const string ANGEL_RING_INTENSITY = "_AngelRingIntensity"; public const string STOCKING_SPARKLE_AMOUNT = "_StockingSparkleAmount";
public const string ANGEL_RING_OFFSET_U = "_AngelRingOffsetU"; public const string STOCKING_SPARKLE_SIZE = "_StockingSparkleSize";
public const string ANGEL_RING_OFFSET_V = "_AngelRingOffsetV"; public const string STOCKING_SPARKLE_INTENSITY = "_StockingSparkleIntensity";
} }
public static class Outline public static class Outline

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 67328b7e131292649a97d548dd87f389

View File

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

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 723370b3a1613cb43b85b765ebcebee3

View File

@@ -1,9 +1,22 @@
namespace Misaki.HdrpToon namespace Misaki.HdrpToon
{ {
internal enum SurfaceType
{
Opaque,
Transparent
}
internal enum DoubleSidedMode
{
None,
Mirror,
Flip
}
internal enum ShadingMode internal enum ShadingMode
{ {
Standard, Standard,
SDF, SDF
} }
internal enum MaterialType internal enum MaterialType

View File

@@ -8,8 +8,8 @@ namespace Misaki.HdrpToon
public enum SurfaceFeature public enum SurfaceFeature
{ {
None = 0, None = 0,
Stocking = 1 << 0, AngelRing = 1 << 0,
RimLight = 1 << 1, RimLight = 1 << 1,
AngelRing = 1 << 2 Stocking = 1 << 2,
} }
} }

View File

@@ -8,9 +8,9 @@
// Misaki.HdrpToon.SurfaceFeature: static fields // Misaki.HdrpToon.SurfaceFeature: static fields
// //
#define SURFACEFEATURE_NONE (0) #define SURFACEFEATURE_NONE (0)
#define SURFACEFEATURE_STOCKING (1) #define SURFACEFEATURE_ANGEL_RING (1)
#define SURFACEFEATURE_RIM_LIGHT (2) #define SURFACEFEATURE_RIM_LIGHT (2)
#define SURFACEFEATURE_ANGEL_RING (4) #define SURFACEFEATURE_STOCKING (4)
#endif #endif

View File

@@ -79,9 +79,11 @@ namespace Misaki.HdrpToon
#endif #endif
} }
#if UNITY_EDITOR
public static SerializedObject GetSerializedSettings() public static SerializedObject GetSerializedSettings()
{ {
return new(GetOrCreateSettings()); return new(GetOrCreateSettings());
} }
#endif
} }
} }

View File

@@ -2,64 +2,52 @@ Shader "HDRP/Toon"
{ {
Properties Properties
{ {
//TODO: Use custom rendering data. //TODO: Write HDRP properties to UTS properties
[ToggleUI] _UseShadowThreshold("_UseShadowThreshold", Float) = 0.0 [ToggleUI] _UseShadowThreshold("_UseShadowThreshold", Integer) = 0
_AlphaCutoffShadow("_AlphaCutoffShadow", Range(0.0, 1.0)) = 0.5 _AlphaCutoffShadow("_AlphaCutoffShadow", Range(0.0, 1.0)) = 0.5
_AlphaCutoffPrepass("_AlphaCutoffPrepass", Range(0.0, 1.0)) = 0.5 _AlphaCutoffPrepass("_AlphaCutoffPrepass", Range(0.0, 1.0)) = 0.5
_AlphaCutoffPostpass("_AlphaCutoffPostpass", Range(0.0, 1.0)) = 0.5 _AlphaCutoffPostpass("_AlphaCutoffPostpass", Range(0.0, 1.0)) = 0.5
[ToggleUI] _TransparentDepthPrepassEnable("_TransparentDepthPrepassEnable", Float) = 0.0 _TransparentSortPriority("_TransparentSortPriority", Integer) = 0
[ToggleUI] _TransparentBackfaceEnable("_TransparentBackfaceEnable", Float) = 0.0
[ToggleUI] _TransparentDepthPostpassEnable("_TransparentDepthPostpassEnable", Float) = 0.0
_TransparentSortPriority("_TransparentSortPriority", Float) = 0
// Transparency // Transparency
[Enum(None, 0, Box, 1, Sphere, 2, Thin, 3)]_RefractionModel("Refraction Model", Int) = 0 [Enum(None, 0, Box, 1, Sphere, 2, Thin, 3)]_RefractionModel("Refraction Model", Integer) = 0
[Enum(Proxy, 1, HiZ, 2)]_SSRefractionProjectionModel("Refraction Projection Model", Int) = 1 [Enum(Proxy, 1, HiZ, 2)]_SSRefractionProjectionModel("Refraction Projection Model", Integer) = 1
_Ior("Index Of Refraction", Range(1.0, 2.5)) = 1.0 _Ior("Index Of Refraction", Range(1.0, 2.5)) = 1.0
_ThicknessMultiplier("Thickness Multiplier", Float) = 1.0 _ThicknessMultiplier("Thickness Multiplier", Float) = 1.0
_TransmittanceColor("Transmittance Color", Color) = (1.0, 1.0, 1.0) _TransmittanceColor("Transmittance Color", Color) = (1.0, 1.0, 1.0)
_TransmittanceColorMap("TransmittanceColorMap", 2D) = "white" {} _TransmittanceColorMap("TransmittanceColorMap", 2D) = "white" {}
_ATDistance("Transmittance Absorption Distance", Float) = 1.0 _ATDistance("Transmittance Absorption Distance", Float) = 1.0
[ToggleUI] _TransparentWritingMotionVec("_TransparentWritingMotionVec", Float) = 0.0
// Forward // Forward
[HideInInspector] _StencilRef("_StencilRef", Int) = 2 // StencilLightingUsage.RegularLighting [HideInInspector] _StencilRef("_StencilRef", Integer) = 0 // StencilUsage.Clear
[HideInInspector] _StencilWriteMask("_StencilWriteMask", Int) = 3 // StencilMask.Lighting [HideInInspector] _StencilWriteMask("_StencilWriteMask", Integer) = 3 // StencilUsage.RequiresDeferredLighting | StencilUsage.SubsurfaceScattering
// GBuffer // GBuffer
[HideInInspector] _StencilRefGBuffer("_StencilRefGBuffer", Int) = 2 // StencilLightingUsage.RegularLighting [HideInInspector] _StencilRefGBuffer("_StencilRefGBuffer", Integer) = 2 // StencilUsage.RequiresDeferredLighting
[HideInInspector] _StencilWriteMaskGBuffer("_StencilWriteMaskGBuffer", Int) = 3 // StencilMask.Lighting [HideInInspector] _StencilWriteMaskGBuffer("_StencilWriteMaskGBuffer", Integer) = 3 // StencilUsage.RequiresDeferredLighting | StencilUsage.SubsurfaceScattering
// Depth prepass // Depth prepass
[HideInInspector] _StencilRefDepth("_StencilRefDepth", Int) = 0 // Nothing [HideInInspector] _StencilRefDepth("_StencilRefDepth", Integer) = 0 // Nothing
[HideInInspector] _StencilWriteMaskDepth("_StencilWriteMaskDepth", Int) = 32 // DoesntReceiveSSR [HideInInspector] _StencilWriteMaskDepth("_StencilWriteMaskDepth", Integer) = 8 // StencilUsage.TraceReflectionRay
// Motion vector pass // Motion vector pass
[HideInInspector] _StencilRefMV("_StencilRefMV", Int) = 128 // StencilBitMask.ObjectMotionVectors [HideInInspector] _StencilRefMV("_StencilRefMV", Integer) = 32 // StencilBitMask.ObjectMotionVectors
[HideInInspector] _StencilWriteMaskMV("_StencilWriteMaskMV", Int) = 128 // StencilBitMask.ObjectMotionVectors [HideInInspector] _StencilWriteMaskMV("_StencilWriteMaskMV", Integer) = 32 // StencilBitMask.ObjectMotionVectors
// Distortion vector pass // Distortion vector pass
[HideInInspector] _StencilRefDistortionVec("_StencilRefDistortionVec", Int) = 64 // StencilBitMask.DistortionVectors [HideInInspector] _StencilRefDistortionVec("_StencilRefDistortionVec", Integer) = 64 // StencilBitMask.DistortionVectors
[HideInInspector] _StencilWriteMaskDistortionVec("_StencilWriteMaskDistortionVec", Int) = 64 // StencilBitMask.DistortionVectors [HideInInspector] _StencilWriteMaskDistortionVec("_StencilWriteMaskDistortionVec", Integer) = 64 // StencilBitMask.DistortionVectors
// Blending state // Blending state
[HideInInspector] _SurfaceType("__surfacetype", Float) = 0.0 _BlendMode("__blendmode", Integer) = 0
[HideInInspector] _BlendMode("__blendmode", Float) = 0.0 [HideInInspector] _SrcBlend("__src", Integer) = 1
[HideInInspector] _SrcBlend("__src", Float) = 1.0 [HideInInspector] _DstBlend("__dst", Integer) = 0
[HideInInspector] _DstBlend("__dst", Float) = 0.0 [HideInInspector] _AlphaSrcBlend("__alphaSrc", Integer) = 1
[HideInInspector] _AlphaSrcBlend("__alphaSrc", Float) = 1.0 [HideInInspector] _AlphaDstBlend("__alphaDst", Integer) = 0
[HideInInspector] _AlphaDstBlend("__alphaDst", Float) = 0.0 [HideInInspector][ToggleUI] _ZWrite("__zw", Integer) = 1
[HideInInspector][ToggleUI] _ZWrite("__zw", Float) = 1.0 [HideInInspector] _CullModeForward("__cullmodeForward", Integer) = 2.0 // This mode is dedicated to Forward to correctly handle backface then front face rendering thin transparent
[HideInInspector][ToggleUI] _TransparentZWrite("_TransparentZWrite", Float) = 0.0 [HideInInspector] _ZTestDepthEqualForOpaque("_ZTestDepthEqualForOpaque", Integer) = 4 // Less equal
[HideInInspector] _CullModeForward("__cullmodeForward", Float) = 2.0 // This mode is dedicated to Forward to correctly handle backface then front face rendering thin transparent [HideInInspector] _ZTestModeDistortion("_ZTestModeDistortion", Integer) = 8
[HideInInspector] _TransparentCullMode("_TransparentCullMode", Int) = 2 // Back culling by default [HideInInspector] _ZTestGBuffer("_ZTestGBuffer", Integer) = 4
[HideInInspector] _ZTestDepthEqualForOpaque("_ZTestDepthEqualForOpaque", Int) = 4 // Less equal [HideInInspector] _ZTestMode("_ZTestMode", Integer) = 4
[HideInInspector] _ZTestModeDistortion("_ZTestModeDistortion", Int) = 8 [Enum(UnityEngine.Rendering.CompareFunction)] _ZTestTransparent("Transparent ZTest", Integer) = 4 // Less equal
[HideInInspector] _ZTestGBuffer("_ZTestGBuffer", Int) = 4
[HideInInspector] _ZTestMode("_ZTestMode", Int) = 4
[Enum(UnityEngine.Rendering.CompareFunction)] _ZTestTransparent("Transparent ZTest", Int) = 4 // Less equal
[ToggleUI] _EnableFogOnTransparent("Enable Fog", Float) = 1.0
[ToggleUI] _EnableBlendModePreserveSpecularLighting("Enable Blend Mode Preserve Specular Lighting", Float) = 1.0
[ToggleUI] _DoubleSidedEnable("Double sided enable", Float) = 0.0
[Enum(Flip, 0, Mirror, 1, None, 2)] _DoubleSidedNormalMode("Double sided normal mode", Float) = 1
[HideInInspector] _DoubleSidedConstants("_DoubleSidedConstants", Vector) = (1, 1, -1, 0) [HideInInspector] _DoubleSidedConstants("_DoubleSidedConstants", Vector) = (1, 1, -1, 0)
[HideInInspector] _UVMappingMask("_UVMappingMask", Color) = (1, 0, 0, 0) [HideInInspector] _UVMappingMask("_UVMappingMask", Color) = (1, 0, 0, 0)
@@ -81,13 +69,24 @@ Shader "HDRP/Toon"
//TODO: Move more properties here for better organization //TODO: Move more properties here for better organization
// Surface Options // Surface Options
[Popup] _TransparentEnabled("Transparent Mode", Integer) = 0 [Enum(Misaki.HdrpToon.SurfaceType)]_SurfaceType("__surfacetype", Integer) = 0
[Popup(_ALPHATEST_ON)] _AlphaCutoffEnable("Alpha Cutoff Enable", Integer) = 0.0
[Popup(_ENABLE_FOG_ON_TRANSPARENT)] _FogOnTransparent("Fog On Transparent", Integer) = 0
[ToggleUI] _TransparentDepthPrepassEnable("Transparent Depth Prepass Enable", Integer) = 0
[ToggleUI] _TransparentDepthPostpassEnable("Transparent Depth Postpass Enable", Integer) = 0
[ToggleUI] _TransparentBackfaceEnable("Transparent Backface Enable", Integer) = 0
[ToggleUI] _TransparentZWrite("_TransparentZWrite", Integer) = 0
[PopupUI] _ReceivesSSRTransparent("Receives SSR Transparent", Integer) = 0
[Popup(_TRANSPARENT_WRITES_MOTION_VEC)] _TransparentWritingMotionVec ("Transparent Writing Motion Vector", Integer) = 0
[Popup(_ALPHATEST_ON)] _AlphaCutoffEnable("Alpha Cutoff Enable", Integer) = 0
_AlphaCutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5 _AlphaCutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
[Enum(Off, 0, Front, 1, Back, 2)] _CullMode("Cull Mode", Integer) = 2 [Enum(Off, 0, Front, 1, Back, 2)] _CullMode("Cull Mode", Integer) = 2
[KeywordEnum(Standard, SDF)] _Shading_Mode("Shading mode", Integer) = 0 [Enum(Misaki.HdrpToon.DoubleSidedMode)] _DoubleSidedNormalMode("Double sided normal mode", Integer) = 1
[KeywordEnum(Standard, FrontHair, Face, Eye)] _Material_Type("Material Type", Integer) = 0
[KeywordEnum(Off, Standard, Anisotropy, Hair, Fabric, Toon)] _PBR_Mode("PBR Mode", Integer) = 0 [KeywordEnumType(Misaki.HdrpToon.ShadingMode, Misaki.HdrpToon)] _Shading_Mode("Shading mode", Integer) = 0
[KeywordEnumType(Misaki.HdrpToon.MaterialType, Misaki.HdrpToon)] _Material_Type("Material Type", Integer) = 0
[KeywordEnumType(Misaki.HdrpToon.PBRMode, Misaki.HdrpToon)] _PBR_Mode("PBR Mode", Integer) = 0
[PassPopup(HairBlendingTarget)] _HairBlendingTarget("Hair Blending Target", Integer) = 0 [PassPopup(HairBlendingTarget)] _HairBlendingTarget("Hair Blending Target", Integer) = 0
[EnumFlagsUI(Misaki.HdrpToon.SurfaceFeature, Misaki.HdrpToon)]_SurfaceFeatures("Surface Features", Integer) = 0 [EnumFlagsUI(Misaki.HdrpToon.SurfaceFeature, Misaki.HdrpToon)]_SurfaceFeatures("Surface Features", Integer) = 0
@@ -172,8 +171,8 @@ Shader "HDRP/Toon"
_EmissiveExposureWeight("Emissive Pre Exposure", Range(0.0, 1.0)) = 1.0 _EmissiveExposureWeight("Emissive Pre Exposure", Range(0.0, 1.0)) = 1.0
// Ambient // Ambient
[KeywordEnum(Off, IBL, MatCap, Ramp)]_Indirect_Diffuse_Mode("_Indirect_Diffuse_Mode", Integer) = 1 [KeywordEnumType(Misaki.HdrpToon.IndirectDiffuseMode, Misaki.HdrpToon)] _Indirect_Diffuse_Mode("_Indirect_Diffuse_Mode", Integer) = 1
[KeywordEnum(Off, IBL, MatCap)]_Indirect_Specular_Mode("_Indirect_Specular_Mode", Integer) = 1 [KeywordEnumType(Misaki.HdrpToon.IndirectSpecularMode, Misaki.HdrpToon)] _Indirect_Specular_Mode("_Indirect_Specular_Mode", Integer) = 1
_IndirectDiffuseMatCapMap("IndirectDiffuseMatCapMap", 2D) = "black" {} _IndirectDiffuseMatCapMap("IndirectDiffuseMatCapMap", 2D) = "black" {}
_IndirectDiffuseMatCapLod("IndirectDiffuseMatCapMapLOD", Range(-5, 5)) = 0.0 _IndirectDiffuseMatCapLod("IndirectDiffuseMatCapMapLOD", Range(-5, 5)) = 0.0
@@ -192,6 +191,13 @@ Shader "HDRP/Toon"
_IndirectSpecularIntensity("Indirect Specular Intensity", Range(0, 5)) = 1.0 _IndirectSpecularIntensity("Indirect Specular Intensity", Range(0, 5)) = 1.0
_SSRWeight("SSR Weight", Range(0.0, 1.0)) = 1.0 _SSRWeight("SSR Weight", Range(0.0, 1.0)) = 1.0
// Angel Rings
_AngelRingColor("Angel Ring Color", Color) = (1, 1, 1, 1)
_AngelRingColorMap("Angel Ring Color Map", 2D) = "black" {}
_AngelRingIntensity("Angel Ring Intensity", Range(0, 10)) = 1
_AngelRingOffsetU("Angel Ring Offset U", Range(0, 1)) = 0
_AngelRingOffsetV("Angel Ring Offset V", Range(0, 1)) = 0
// Rim Light // Rim Light
_RimLightColor("Rim Light Color", Color) = (1, 1, 1, 1) _RimLightColor("Rim Light Color", Color) = (1, 1, 1, 1)
_RimLightIntensity("Rim Light Intensity", Range(0, 10)) = 1 _RimLightIntensity("Rim Light Intensity", Range(0, 10)) = 1
@@ -217,12 +223,12 @@ Shader "HDRP/Toon"
_Set_RimLightMask("Set_RimLightMask", 2D) = "white" {} _Set_RimLightMask("Set_RimLightMask", 2D) = "white" {}
_Tweak_RimLightMaskLevel("Tweak_RimLightMaskLevel", Range(-1, 1)) = 0 _Tweak_RimLightMaskLevel("Tweak_RimLightMaskLevel", Range(-1, 1)) = 0
// Angel Rings // Stocking
_AngelRingColor("Angel Ring Color", Color) = (1, 1, 1, 1) _StockingFresnelWidth("Stocking Fresnel Width", Range(0, 10)) = 2.0
_AngelRingColorMap("Angel Ring Color Map", 2D) = "black" {} [PowerSlider(2.0)]_StockingSparkleSpacing("Stocking Sparking Spacing", Range(64.0, 1024.0)) = 128.0
_AngelRingIntensity("Angel Ring Intensity", Range(0, 10)) = 1 _StockingSparkleAmount("Stocking Sparking Amount", Range(0, 2)) = 1.0
_AngelRingOffsetU("Angel Ring Offset U", Range(0, 1)) = 0 _StockingSparkleSize("Stocking Sparking Intensity", Range(0, 2)) = 0.5
_AngelRingOffsetV("Angel Ring Offset V", Range(0, 1)) = 0 _StockingSparkleIntensity("Stocking Sparking Intensity", Range(0, 10)) = 1.0
// Outline // Outline
[PassPopup(Outline)] _OutlineState("Outline State", Integer) = 1 [PassPopup(Outline)] _OutlineState("Outline State", Integer) = 1
@@ -232,7 +238,7 @@ Shader "HDRP/Toon"
_OutlineColorMap("Outline Color Map", 2D) = "white" {} _OutlineColorMap("Outline Color Map", 2D) = "white" {}
[ToggleUI] _AlbedoAffectOutline("Albedo Affect Outline", Float) = 1 [ToggleUI] _AlbedoAffectOutline("Albedo Affect Outline", Float) = 1
[ToggleUI] _SkyColorAffectOutline("Sky Color Affect Outline", Float) = 1 [ToggleUI] _SkyColorAffectOutline("Sky Color Affect Outline", Float) = 1
_SkyColorIntensity("Sky Color Intensity", Range(0, 5)) = 1 _SkyColorIntensity("Sky Color Intensity", Range(0, 10)) = 1
_OutlineFadeIn("Outline Fade In", Float) = 50 _OutlineFadeIn("Outline Fade In", Float) = 50
_OutlineFadeOut("Outline Fade Out", Float) = 100 _OutlineFadeOut("Outline Fade Out", Float) = 100
@@ -256,7 +262,15 @@ Shader "HDRP/Toon"
_TexWorldScaleEmissive("Scale to apply on world coordinate", Float) = 1.0 _TexWorldScaleEmissive("Scale to apply on world coordinate", Float) = 1.0
[HideInInspector] _UVMappingMaskEmissive("_UVMappingMaskEmissive", Color) = (1, 0, 0, 0) [HideInInspector] _UVMappingMaskEmissive("_UVMappingMaskEmissive", Color) = (1, 0, 0, 0)
[HideInInspector] _DiffusionProfile("Obsolete, kept for migration purpose", Int) = 0 _SubsurfaceMask("Subsurface Radius", Range(0.0, 1.0)) = 1.0
_SubsurfaceMaskMap("Subsurface Radius Map", 2D) = "white" {}
_TransmissionMask("Transmission Mask", Range(0.0, 1.0)) = 1.0
_TransmissionMaskMap("Transmission Mask Map", 2D) = "white" {}
_Thickness("Thickness", Float) = 1.0
_ThicknessMap("Thickness Map", 2D) = "white" {}
_ThicknessRemap("Thickness Remap", Vector) = (0, 1, 0, 0)
[HideInInspector] _DiffusionProfile("Obsolete, kept for migration purpose", Integer) = 0
[HideInInspector] _DiffusionProfileAsset("Diffusion Profile Asset", Vector) = (0, 0, 0, 0) [HideInInspector] _DiffusionProfileAsset("Diffusion Profile Asset", Vector) = (0, 0, 0, 0)
[HideInInspector] _DiffusionProfileHash("Diffusion Profile Hash", Float) = 0 [HideInInspector] _DiffusionProfileHash("Diffusion Profile Hash", Float) = 0
} }
@@ -269,6 +283,8 @@ Shader "HDRP/Toon"
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Variant // Variant
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
#pragma multi_compile _ DOTS_INSTANCING_ON
#pragma shader_feature_local _DOUBLESIDED_ON #pragma shader_feature_local _DOUBLESIDED_ON
#pragma shader_feature_local _NORMALMAP_TANGENT_SPACE #pragma shader_feature_local _NORMALMAP_TANGENT_SPACE
@@ -380,7 +396,6 @@ Shader "HDRP/Toon"
#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch
#pragma instancing_options renderinglayer #pragma instancing_options renderinglayer
#pragma multi_compile _ DOTS_INSTANCING_ON
#pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ DEBUG_DISPLAY
@@ -392,10 +407,13 @@ Shader "HDRP/Toon"
#pragma multi_compile DECALS_OFF DECALS_3RT DECALS_4RT #pragma multi_compile DECALS_OFF DECALS_3RT DECALS_4RT
#pragma multi_compile _ LIGHT_LAYERS #pragma multi_compile _ LIGHT_LAYERS
#pragma shader_feature _SURFACE_TYPE_TRANSPARENT
#pragma shader_feature_local_fragment _PBR_MODE_OFF #pragma shader_feature_local_fragment _PBR_MODE_OFF
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _NORMALMAP_TANGENT_SPACE
#pragma shader_feature_local_fragment _MASKMAP #pragma shader_feature_local_fragment _MASKMAP
#pragma shader_feature_local_fragment _NORMALMAP
#pragma shader_feature_local_fragment _ANISOTROPYMAP #pragma shader_feature_local_fragment _ANISOTROPYMAP
#pragma shader_feature_local_fragment _SPECULARCOLORMAP #pragma shader_feature_local_fragment _SPECULARCOLORMAP
@@ -443,7 +461,16 @@ Shader "HDRP/Toon"
HLSLPROGRAM HLSLPROGRAM
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _NORMALMAP_TANGENT_SPACE
#pragma shader_feature_local_fragment _MASKMAP
#pragma shader_feature_local_fragment _ANISOTROPYMAP
#pragma shader_feature_local_fragment _SPECULARCOLORMAP
#pragma shader_feature_local _ALPHATEST_ON #pragma shader_feature_local _ALPHATEST_ON
#pragma shader_feature _SURFACE_TYPE_TRANSPARENT
#pragma shader_feature_local_fragment _ENABLE_FOG_ON_TRANSPARENT
// Lightmap memo // Lightmap memo
// DYNAMICLIGHTMAP_ON is used when we have an "enlighten lightmap" ie a lightmap updated at runtime by enlighten.This lightmap contain indirect lighting from realtime lights and realtime emissive material.Offline baked lighting(from baked material / light, // DYNAMICLIGHTMAP_ON is used when we have an "enlighten lightmap" ie a lightmap updated at runtime by enlighten.This lightmap contain indirect lighting from realtime lights and realtime emissive material.Offline baked lighting(from baked material / light,
// both direct and indirect lighting) will hand up in the "regular" lightmap->LIGHTMAP_ON. // both direct and indirect lighting) will hand up in the "regular" lightmap->LIGHTMAP_ON.
@@ -511,9 +538,9 @@ Shader "HDRP/Toon"
HLSLPROGRAM HLSLPROGRAM
#pragma shader_feature_local_fragment _MASKMAP
#pragma shader_feature_local _NORMALMAP #pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _NORMALMAP_TANGENT_SPACE #pragma shader_feature_local_fragment _NORMALMAP_TANGENT_SPACE
#pragma shader_feature_local_fragment _MASKMAP
#pragma shader_feature_local _ALPHATEST_ON #pragma shader_feature_local _ALPHATEST_ON
@@ -561,10 +588,12 @@ Shader "HDRP/Toon"
ZWrite On ZWrite On
HLSLPROGRAM HLSLPROGRAM
#pragma multi_compile _ WRITE_NORMAL_BUFFER #pragma multi_compile _ WRITE_NORMAL_BUFFER
#pragma multi_compile _ WRITE_MSAA_DEPTH #pragma multi_compile _ WRITE_MSAA_DEPTH
#pragma shader_feature_local _ALPHATEST_ON #pragma shader_feature_local _ALPHATEST_ON
#pragma shader_feature _SURFACE_TYPE_TRANSPARENT
#define SHADERPASS SHADERPASS_MOTION_VECTORS #define SHADERPASS SHADERPASS_MOTION_VECTORS
@@ -629,11 +658,22 @@ Shader "HDRP/Toon"
HLSLPROGRAM HLSLPROGRAM
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _NORMALMAP_TANGENT_SPACE
#pragma shader_feature_local_fragment _MASKMAP
#pragma shader_feature_local _ALPHATEST_ON #pragma shader_feature_local _ALPHATEST_ON
#pragma shader_feature _SURFACE_TYPE_TRANSPARENT
#pragma shader_feature_local _DISABLE_SSR_TRANSPARENT
#define SHADERPASS SHADERPASS_TRANSPARENT_DEPTH_PREPASS
// If the transparent surface should have reflections, then we should output normal
#if !defined(_DISABLE_SSR_TRANSPARENT)
#define WRITE_NORMAL_BUFFER
#endif
#define SHADERPASS SHADERPASS_DEPTH_ONLY
#define CUTOFF_TRANSPARENT_DEPTH_PREPASS
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl" #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/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/ShaderPass/LitDepthPass.hlsl"
@@ -660,7 +700,17 @@ Shader "HDRP/Toon"
HLSLPROGRAM HLSLPROGRAM
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _NORMALMAP_TANGENT_SPACE
#pragma shader_feature_local_fragment _MASKMAP
#pragma shader_feature_local_fragment _ANISOTROPYMAP
#pragma shader_feature_local_fragment _SPECULARCOLORMAP
#pragma shader_feature_local_fragment _EMISSIVE_COLOR_MAP
#pragma shader_feature_local _ALPHATEST_ON #pragma shader_feature_local _ALPHATEST_ON
#pragma shader_feature _SURFACE_TYPE_TRANSPARENT
#pragma shader_feature_local_fragment _ENABLE_FOG_ON_TRANSPARENT
#pragma shader_feature_local _DISABLE_SSR_TRANSPARENT
#pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ DEBUG_DISPLAY
#pragma multi_compile _ LIGHTMAP_ON #pragma multi_compile _ LIGHTMAP_ON
@@ -711,9 +761,9 @@ Shader "HDRP/Toon"
Name "ForwardOnly" Name "ForwardOnly"
Tags { "LightMode" = "ForwardOnly" } Tags { "LightMode" = "ForwardOnly" }
ZWrite [_ZWriteMode] ZWrite [_ZWrite]
ZTest [_ZTestDepthEqualForOpaque] ZTest [_ZTestDepthEqualForOpaque]
Cull [_CullMode] Cull [_CullModeForward]
Blend [_SrcBlend] [_DstBlend], [_AlphaSrcBlend] [_AlphaDstBlend] Blend [_SrcBlend] [_DstBlend], [_AlphaSrcBlend] [_AlphaDstBlend]
// ForwardOpaque | ForwardTransparent // ForwardOpaque | ForwardTransparent
@@ -724,15 +774,15 @@ Shader "HDRP/Toon"
Stencil Stencil
{ {
Ref[_StencilNo] WriteMask [_StencilWriteMask]
Ref [_StencilRef]
Comp[_StencilComp] Comp Always
Pass[_StencilOpPass] Pass Replace
Fail[_StencilOpFail]
} }
HLSLPROGRAM HLSLPROGRAM
#pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ DEBUG_DISPLAY
#pragma multi_compile _ LIGHTMAP_ON #pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DIRLIGHTMAP_COMBINED
@@ -743,18 +793,13 @@ Shader "HDRP/Toon"
#pragma multi_compile SCREEN_SPACE_SHADOWS_OFF SCREEN_SPACE_SHADOWS_ON #pragma multi_compile SCREEN_SPACE_SHADOWS_OFF SCREEN_SPACE_SHADOWS_ON
#pragma multi_compile_fragment USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST #pragma multi_compile_fragment USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST
// NOTE: We force shadow to medium for the moment.
//#pragma multi_compile_fragment PUNCTUAL_SHADOW_LOW PUNCTUAL_SHADOW_MEDIUM PUNCTUAL_SHADOW_HIGH //#pragma multi_compile_fragment PUNCTUAL_SHADOW_LOW PUNCTUAL_SHADOW_MEDIUM PUNCTUAL_SHADOW_HIGH
//#pragma multi_compile_fragment DIRECTIONAL_SHADOW_LOW DIRECTIONAL_SHADOW_MEDIUM DIRECTIONAL_SHADOW_HIGH //#pragma multi_compile_fragment DIRECTIONAL_SHADOW_LOW DIRECTIONAL_SHADOW_MEDIUM DIRECTIONAL_SHADOW_HIGH
//#pragma multi_compile_fragment AREA_SHADOW_MEDIUM AREA_SHADOW_HIGH //#pragma multi_compile_fragment AREA_SHADOW_MEDIUM AREA_SHADOW_HIGH
#pragma multi_compile PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2
#define SHADERPASS SHADERPASS_FORWARD
// In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)
// Don't do it with debug display mode as it is possible there is no depth prepass in this case
#if !defined(_SURFACE_TYPE_TRANSPARENT) && !defined(DEBUG_DISPLAY)
#define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST
#endif
#pragma shader_feature _EMISSIVE_SIMPLE _EMISSIVE_ANIMATION #pragma shader_feature _EMISSIVE_SIMPLE _EMISSIVE_ANIMATION
#pragma shader_feature ENABLE_UTS_HAIR_SHAOW #pragma shader_feature ENABLE_UTS_HAIR_SHAOW
@@ -780,16 +825,21 @@ Shader "HDRP/Toon"
#pragma shader_feature_local_fragment _SHADING_RAMP_MASK_MAP #pragma shader_feature_local_fragment _SHADING_RAMP_MASK_MAP
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _NORMALMAP_TANGENT_SPACE
#pragma shader_feature_local_fragment _MASKMAP #pragma shader_feature_local_fragment _MASKMAP
#pragma shader_feature_local_fragment _NORMALMAP
#pragma shader_feature_local_fragment _ANISOTROPYMAP #pragma shader_feature_local_fragment _ANISOTROPYMAP
#pragma shader_feature_local_fragment _SPECULARCOLORMAP #pragma shader_feature_local_fragment _SPECULARCOLORMAP
#pragma shader_feature_local_fragment _EMISSIVE_COLOR_MAP #pragma shader_feature_local_fragment _EMISSIVE_COLOR_MAP
#pragma shader_feature_local_fragment _STOCKING_SPARKING_MAP
#pragma shader_feature_local_fragment _OUTLINECOLORMAP #pragma shader_feature_local_fragment _OUTLINECOLORMAP
#pragma shader_feature_local _ALPHATEST_ON #pragma shader_feature_local _ALPHATEST_ON
#pragma shader_feature _SURFACE_TYPE_TRANSPARENT
#pragma shader_feature_local_fragment _ENABLE_FOG_ON_TRANSPARENT
#pragma shader_feature_local _DISABLE_SSR_TRANSPARENT
#define PUNCTUAL_SHADOW_MEDIUM #define PUNCTUAL_SHADOW_MEDIUM
@@ -801,6 +851,15 @@ Shader "HDRP/Toon"
#define USE_FPTL_LIGHTLIST #define USE_FPTL_LIGHTLIST
#endif #endif
#define SHADERPASS SHADERPASS_FORWARD
// In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)
// Don't do it with debug display mode as it is possible there is no depth prepass in this case
#if !defined(_SURFACE_TYPE_TRANSPARENT) && !defined(DEBUG_DISPLAY)
#define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST
#endif
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Lighting.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Lighting.hlsl"
@@ -850,6 +909,7 @@ Shader "HDRP/Toon"
HLSLPROGRAM HLSLPROGRAM
#pragma shader_feature_local _ALPHATEST_ON #pragma shader_feature_local _ALPHATEST_ON
#pragma shader_feature _SURFACE_TYPE_TRANSPARENT
#define SHADERPASS SHADERPASS_DEPTH_ONLY #define SHADERPASS SHADERPASS_DEPTH_ONLY
#define CUTOFF_TRANSPARENT_DEPTH_POSTPASS #define CUTOFF_TRANSPARENT_DEPTH_POSTPASS
@@ -898,7 +958,19 @@ Shader "HDRP/Toon"
Tags { "LightMode" = "Outline" } Tags { "LightMode" = "Outline" }
Cull Front Cull Front
Blend SrcAlpha OneMinusSrcAlpha
ZWrite On
ZTest LEqual
// // NOTE: We disable taa and tau for outline because it can't provide motion vector. This will reduce the ghosting but introduce some jittering.
// // Worth it to write motion vector for outline? It will introduce additional drawcall.
// Stencil
// {
// WriteMask 3
// Ref 0
// Comp Always
// Pass Replace
// }
HLSLPROGRAM HLSLPROGRAM
@@ -1018,11 +1090,16 @@ Shader "HDRP/Toon"
#pragma multi_compile PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2
#pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DIRLIGHTMAP_COMBINED
#define SHADERPASS SHADERPASS_RAYTRACING_INDIRECT
// multi compile that allows us to strip the recursive code // multi compile that allows us to strip the recursive code
#pragma multi_compile _ MULTI_BOUNCE_INDIRECT #pragma multi_compile _ MULTI_BOUNCE_INDIRECT
#pragma shader_feature_local_raytracing _NORMALMAP
#pragma shader_feature_local_raytracing _ALPHATEST_ON
#pragma shader_feature_raytracing _SURFACE_TYPE_TRANSPARENT
#pragma shader_feature_local _DISABLE_SSR_TRANSPARENT
#define SHADERPASS SHADERPASS_RAYTRACING_INDIRECT
// If you need to change this, be sure to read this comment. // If you need to change this, be sure to read this comment.
// For raytracing we decided to force the shadow quality to low. // For raytracing we decided to force the shadow quality to low.
// - The performance is the first reason, given that it may happen during the ray tracing stage for indirect or in a non-tiled context for deferred // - The performance is the first reason, given that it may happen during the ray tracing stage for indirect or in a non-tiled context for deferred
@@ -1070,6 +1147,11 @@ Shader "HDRP/Toon"
#pragma multi_compile PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2
#pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma shader_feature_local_raytracing _NORMALMAP
#pragma shader_feature_local_raytracing _ALPHATEST_ON
#pragma shader_feature_raytracing _SURFACE_TYPE_TRANSPARENT
#pragma shader_feature_local _DISABLE_SSR_TRANSPARENT
#define SHADERPASS SHADERPASS_RAYTRACING_FORWARD #define SHADERPASS SHADERPASS_RAYTRACING_FORWARD
// If you need to change this, be sure to read this comment. // If you need to change this, be sure to read this comment.
@@ -1120,6 +1202,11 @@ Shader "HDRP/Toon"
#pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ MINIMAL_GBUFFER #pragma multi_compile _ MINIMAL_GBUFFER
#pragma shader_feature_local_raytracing _NORMALMAP
#pragma shader_feature_local_raytracing _ALPHATEST_ON
#pragma shader_feature_raytracing _SURFACE_TYPE_TRANSPARENT
#pragma shader_feature_local _DISABLE_SSR_TRANSPARENT
#define SHADERPASS SHADERPASS_RAYTRACING_GBUFFER #define SHADERPASS SHADERPASS_RAYTRACING_GBUFFER
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingMacros.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingMacros.hlsl"
@@ -1151,6 +1238,11 @@ Shader "HDRP/Toon"
#pragma only_renderers d3d11 ps5 #pragma only_renderers d3d11 ps5
#pragma raytracing surface_shader #pragma raytracing surface_shader
#pragma shader_feature_local_raytracing _NORMALMAP
#pragma shader_feature_local_raytracing _ALPHATEST_ON
#pragma shader_feature_raytracing _SURFACE_TYPE_TRANSPARENT
#pragma shader_feature_local _DISABLE_SSR_TRANSPARENT
#define SHADERPASS SHADERPASS_RAYTRACING_VISIBILITY #define SHADERPASS SHADERPASS_RAYTRACING_VISIBILITY
#pragma multi_compile _ TRANSPARENT_COLOR_SHADOW #pragma multi_compile _ TRANSPARENT_COLOR_SHADOW
@@ -1182,6 +1274,11 @@ Shader "HDRP/Toon"
#pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ DEBUG_DISPLAY
#pragma shader_feature_local_raytracing _NORMALMAP
#pragma shader_feature_local_raytracing _ALPHATEST_ON
#pragma shader_feature_raytracing _SURFACE_TYPE_TRANSPARENT
#pragma shader_feature_local _DISABLE_SSR_TRANSPARENT
#define SHADERPASS SHADERPASS_PATH_TRACING #define SHADERPASS SHADERPASS_PATH_TRACING
// This is just because it needs to be defined, shadow maps are not used. // This is just because it needs to be defined, shadow maps are not used.

View File

@@ -55,50 +55,49 @@ float Random(float2 uv)
return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453); return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453);
} }
float unity_noise_interpolate (float a, float b, float t) inline float2 voronoi_noise_random_vector (float2 UV, float offset)
{ {
return (1.0-t)*a + (t*b); float2x2 m = float2x2(15.27, 47.63, 99.41, 89.98);
UV = frac(sin(mul(UV, m)) * 46839.32);
return float2(sin(UV.y*+offset)*0.5+0.5, cos(UV.x*offset)*0.5+0.5);
} }
float ValueNoise (float2 uv) float Voronoi(float2 UV, float AngleOffset, float CellDensity)
{ {
float2 i = floor(uv); float2 g = floor(UV * CellDensity);
float2 f = frac(uv); float2 f = frac(UV * CellDensity);
f = f * f * (3.0 - 2.0 * f); float t = 8.0;
float res = 8.0;
uv = abs(frac(uv) - 0.5); for(int y=-1; y<=1; y++)
float2 c0 = i + float2(0.0, 0.0); {
float2 c1 = i + float2(1.0, 0.0); for(int x=-1; x<=1; x++)
float2 c2 = i + float2(0.0, 1.0); {
float2 c3 = i + float2(1.0, 1.0); float2 lattice = float2(x,y);
float r0 = Random(c0); float2 offset = voronoi_noise_random_vector(lattice + g, AngleOffset);
float r1 = Random(c1); float d = distance(lattice + offset, f);
float r2 = Random(c2); if(d < res)
float r3 = Random(c3); {
res = d;
}
}
}
float bottomOfGrid = unity_noise_interpolate(r0, r1, f.x); return res;
float topOfGrid = unity_noise_interpolate(r2, r3, f.x);
float t = unity_noise_interpolate(bottomOfGrid, topOfGrid, f.y);
return t;
} }
float SimpleNoise(float2 UV, float Scale) float Dither(float In, float4 positionSS)
{ {
float t = 0.0; float2 uv = positionSS.xy;
float DITHER_THRESHOLDS[16] =
float freq = pow(2.0, float(0)); {
float amp = pow(0.5, float(3-0)); 1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0,
t += ValueNoise(float2(UV.x*Scale/freq, UV.y*Scale/freq))*amp; 13.0 / 17.0, 5.0 / 17.0, 15.0 / 17.0, 7.0 / 17.0,
4.0 / 17.0, 12.0 / 17.0, 2.0 / 17.0, 10.0 / 17.0,
freq = pow(2.0, float(1)); 16.0 / 17.0, 8.0 / 17.0, 14.0 / 17.0, 6.0 / 17.0
amp = pow(0.5, float(3-1)); };
t += ValueNoise(float2(UV.x*Scale/freq, UV.y*Scale/freq))*amp; uint index = (uint(uv.x) % 4) * 4 + uint(uv.y) % 4;
return In - DITHER_THRESHOLDS[index];
freq = pow(2.0, float(2));
amp = pow(0.5, float(3-2));
t += ValueNoise(float2(UV.x*Scale/freq, UV.y*Scale/freq))*amp;
return t;
} }
#define SampleRampSignalLine(texture, u) (SAMPLE_TEXTURE2D_LOD(texture, s_linear_clamp_sampler, float2(u, 0.5), 0)) #define SampleRampSignalLine(texture, u) (SAMPLE_TEXTURE2D_LOD(texture, s_linear_clamp_sampler, float2(u, 0.5), 0))

View File

@@ -74,6 +74,24 @@ struct UtsBSDFData
real roughnessB; real roughnessB;
}; };
bool IsNonZeroBSDF(float3 L, float3 N)
{
// Should we sample shadow in zero bsdf area when using ramp map?
#if _MATERIAL_TYPE_FACE || _USE_SHADING_RAMP_MAP_ON
return true;
//#elif _USE_SHADING_RAMP_MAP_ON
#else
float NdotL = dot(N, L);
return NdotL > 0.0;
#endif
}
bool IsNonZeroBSDF(float3 L, UtsBSDFData bsdfData)
{
return IsNonZeroBSDF(L, bsdfData.normalWS);
}
UTSSurfaceData ConvertSurfaceDataToUTSSurfaceData(SurfaceData surfaceData) UTSSurfaceData ConvertSurfaceDataToUTSSurfaceData(SurfaceData surfaceData)
{ {
UTSSurfaceData output; UTSSurfaceData output;

View File

@@ -264,7 +264,6 @@ void UtsGetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInput
#endif #endif
float3 doubleSidedConstants = GetDoubleSidedConstants(); float3 doubleSidedConstants = GetDoubleSidedConstants();
ApplyDoubleSidedFlipOrMirror(input, doubleSidedConstants); // Apply double sided flip on the vertex normal ApplyDoubleSidedFlipOrMirror(input, doubleSidedConstants); // Apply double sided flip on the vertex normal
LayerTexCoord layerTexCoord; LayerTexCoord layerTexCoord;

View File

@@ -1,20 +1,23 @@
#ifndef UTS_SURFACE_FEATURE_EVALUATION #ifndef UTS_SURFACE_FEATURE_EVALUATION
#define UTS_SURFACE_FEATURE_EVALUATION #define UTS_SURFACE_FEATURE_EVALUATION
void UtsEvaluateLighting_Stocking(FragInputs input, PositionInputs posInput, float3 normalWS, float3 V, inout AggregateLighting aggregateLighting) void UtsEvaluateLighting_Stocking(FragInputs input, PositionInputs posInput, PreLightData preLightData, float3 N, float3 V, inout AggregateLighting aggregateLighting)
{ {
float NdotV = saturate(dot(normalize(V), normalWS)); float fresnel = pow(preLightData.NdotV, _StockingFresnelWidth);
NdotV = pow(NdotV, 2.0); #if _STOCKING_SPARKING_MAP
float viewAngleFactor = saturate(1.0 - preLightData.NdotV);
float2 shiftedNDC = posInput.positionNDC.xy + viewAngleFactor * 0.05;
float spacing = (1.0 - posInput.linearDepth) * _StockingSparkleSpacing;
// TODO: Move sparkle to bsdf evaluation? // NOTE: Should we use sparkle texture instead of Voronoi?
// float sparkle = Random(posInput.positionNDC.xy); float screenSparkle = smoothstep(1.0 - (0.5 * _StockingSparkleAmount), 1, 1.0 - Voronoi(shiftedNDC * _ScreenParams.xy / spacing, 5, 5.0));
// sparkle = step(0.995, sparkle); float objectSparkle = smoothstep(1.0 - (0.5 * _StockingSparkleSize), 1, 1.0 - Voronoi(input.texCoord0, 5, 100.0));
// float noise = SimpleNoise(posInput.positionNDC.xy, 500.0); float sparkle = objectSparkle * screenSparkle * _StockingSparkleIntensity * 5;
// sparkle = noise < sparkle ? 1.0 : 0.0; aggregateLighting.direct.specular += sparkle * aggregateLighting.direct.specular;
#endif
aggregateLighting.direct.diffuse *= NdotV; aggregateLighting.direct.diffuse *= fresnel;
// aggregateLighting.direct.specular = saturate(aggregateLighting.direct.specular + sparkle * (1.0 - NdotV) * 0.5);
} }
DirectLighting UtsEvaluateLighting_RimLight(PositionInputs posInput, UtsBSDFData bsdfData, PreLightData preLightData DirectLighting UtsEvaluateLighting_RimLight(PositionInputs posInput, UtsBSDFData bsdfData, PreLightData preLightData
@@ -55,7 +58,7 @@ DirectLighting UtsEvaluateLighting_RimLight(PositionInputs posInput, UtsBSDFData
return lighting; return lighting;
} }
DirectLighting UtsEvaluateLighting_AngelRing(FragInputs input, float3 normalWS, float3 V) DirectLighting UtsEvaluateLighting_AngelRing(FragInputs input, float3 N, float3 V)
{ {
DirectLighting lighting; DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting); ZERO_INITIALIZE(DirectLighting, lighting);
@@ -71,15 +74,16 @@ DirectLighting UtsEvaluateLighting_AngelRing(FragInputs input, float3 normalWS,
float3 cameraRoll = acos(clamp(cameraRollCos, -1.0, 1.0)); float3 cameraRoll = acos(clamp(cameraRollCos, -1.0, 1.0));
float cameraDir = cameraRight.y < 0 ? -1.0 : 1.0; float cameraDir = cameraRight.y < 0 ? -1.0 : 1.0;
float2 arOffsetU = lerp(mul(UNITY_MATRIX_V, float4(normalWS, 0)).xyz, float3(0, 0, 1), _AngelRingOffsetU).xy; float2 arOffsetU = lerp(mul(UNITY_MATRIX_V, float4(N, 0)).xyz, float3(0, 0, 1), _AngelRingOffsetU).xy;
arOffsetU = arOffsetU * 0.5 + 0.5; arOffsetU = arOffsetU * 0.5 + 0.5;
float2 arvnRotate = RotateUV(arOffsetU, -(cameraDir * cameraRoll).x, 0.5, 1.0); float2 arvnRotate = RotateUV(arOffsetU, -(cameraDir * cameraRoll).x, 0.5, 1.0);
float2 arOffsetUV = float2(arvnRotate.x, lerp(input.texCoord0.y, arvnRotate.y, _AngelRingOffsetV)); float2 arOffsetUV = float2(arvnRotate.x, lerp(input.texCoord0.y, arvnRotate.y, _AngelRingOffsetV));
float4 angelRingColor = SAMPLE_TEXTURE2D(_AngelRingColorMap, sampler_AngelRingColorMap, TRANSFORM_TEX(arOffsetUV, _AngelRingColorMap)) * _AngelRingColor * _AngelRingIntensity; float4 angelRingColor = SAMPLE_TEXTURE2D(_AngelRingColorMap, sampler_AngelRingColorMap, TRANSFORM_TEX(arOffsetUV, _AngelRingColorMap)) * _AngelRingColor * _AngelRingIntensity;
float weight = saturate(dot(normalize(V), normalWS)); float weight = saturate(dot(V, N));
lighting.specular = angelRingColor.r * angelRingColor.a * weight; lighting.specular = angelRingColor * angelRingColor.a * weight;
return lighting; return lighting;
} }

View File

@@ -49,16 +49,17 @@ DirectLighting UtsEvaluateBSDF_Directional(LightLoopContext lightLoopContext, Po
float3 L = -lightData.forward; float3 L = -lightData.forward;
SHADOW_TYPE shadow = 1.0; SHADOW_TYPE shadow = 1.0;
// TODO: Should we disable the contact shadow?
#if _RECEIVE_LIGHT_SHADOW_ON #if _RECEIVE_LIGHT_SHADOW_ON
shadow = EvaluateShadow_Directional(lightLoopContext, posInput, lightData, builtinData, bsdfData.geomNormalWS); shadow = EvaluateShadow_Directional(lightLoopContext, posInput, lightData, builtinData, bsdfData.geomNormalWS);
#endif #endif
if (lightData.lightDimmer > 0.0) if (lightData.lightDimmer > 0.0)
{ {
// TODO: Colored shadow will overwrite the first and second shading diffuse color // TODO: Support ray traced transparent colored shadow
//float3 shadowColor = ComputeShadowColor(shadow, lightData.shadowTint, lightData.penumbraTint); float3 shadowColor = ComputeShadowColor(shadow, lightData.shadowTint, lightData.penumbraTint);
float4 lightColor = EvaluateLight_Directional(lightLoopContext, posInput, lightData); float4 lightColor = EvaluateLight_Directional(lightLoopContext, posInput, lightData);
lightColor.rgb = GetLimitedLightColor(lightColor.rgb * lightColor.a * _LightIntensityMultiplier); lightColor.rgb = GetLimitedLightColor(lightColor.rgb * lightColor.a * _LightIntensityMultiplier) * shadowColor;
UtsClampRoughness(preLightData, bsdfData, lightData.minRoughness); UtsClampRoughness(preLightData, bsdfData, lightData.minRoughness);
@@ -84,8 +85,8 @@ DirectLighting UtsEvaluateBSDF_Punctual(LightLoopContext lightLoopContext, Posit
if (lightData.lightDimmer > 0.0) if (lightData.lightDimmer > 0.0)
{ {
// TODO: Colored shadow will overwrite the first and second shading diffuse color // TODO: Support ray traced transparent colored shadow
//float3 shadowColor = ComputeShadowColor(shadow, lightData.shadowTint, lightData.penumbraTint); float3 shadowColor = ComputeShadowColor(shadow, lightData.shadowTint, lightData.penumbraTint);
float4 lightColor = EvaluateLight_Punctual(lightLoopContext, posInput, lightData, L, distances); float4 lightColor = EvaluateLight_Punctual(lightLoopContext, posInput, lightData, L, distances);
lightColor.rgb = GetLimitedLightColor(lightColor.rgb * lightColor.a * _LightIntensityMultiplier); lightColor.rgb = GetLimitedLightColor(lightColor.rgb * lightColor.a * _LightIntensityMultiplier);
@@ -111,7 +112,7 @@ IndirectLighting UtsEvaluateBSDF_ScreenSpaceReflection(PositionInputs posInput,
// Apply the weight on the ssr contribution (if required) // Apply the weight on the ssr contribution (if required)
ApplyScreenSpaceReflectionWeight(ssrLighting); ApplyScreenSpaceReflectionWeight(ssrLighting);
reflectionHierarchyWeight = ssrLighting.a; reflectionHierarchyWeight = ssrLighting.a * _SSRWeight;
lighting.specularReflected = lerp(lighting.specularReflected, ssrLighting.rgb * preLightData.specularFGD, _SSRWeight); lighting.specularReflected = lerp(lighting.specularReflected, ssrLighting.rgb * preLightData.specularFGD, _SSRWeight);
} }
@@ -245,9 +246,9 @@ IndirectLighting UtsEvaluateBSDF_Env(LightLoopContext lightLoopContext, Position
return lighting; return lighting;
} }
void ApplyAmbientOcclusion(AmbientOcclusionFactor aoFactor, inout BuiltinData builtinData, inout AggregateLighting lighting) void ApplyAmbientOcclusion(AmbientOcclusionFactor aoFactor, UtsBSDFData bsdfData, inout BuiltinData builtinData, inout AggregateLighting lighting)
{ {
builtinData.bakeDiffuseLighting = APPLY_WEIGHT(builtinData.bakeDiffuseLighting, aoFactor.indirectAmbientOcclusion, _SSAOWeight); builtinData.bakeDiffuseLighting = APPLY_WEIGHT(builtinData.bakeDiffuseLighting, lerp(bsdfData.diffuseColor * 0.2, 1.0, aoFactor.indirectAmbientOcclusion), _SSAOWeight);
lighting.indirect.specularReflected = APPLY_WEIGHT(lighting.indirect.specularReflected, aoFactor.indirectSpecularOcclusion, _SSAOWeight); lighting.indirect.specularReflected = APPLY_WEIGHT(lighting.indirect.specularReflected, aoFactor.indirectSpecularOcclusion, _SSAOWeight);
lighting.direct.diffuse = APPLY_WEIGHT(lighting.direct.diffuse, aoFactor.directAmbientOcclusion, _SSAOWeight); lighting.direct.diffuse = APPLY_WEIGHT(lighting.direct.diffuse, aoFactor.directAmbientOcclusion, _SSAOWeight);
lighting.direct.specular = APPLY_WEIGHT(lighting.direct.specular, aoFactor.directSpecularOcclusion, _SSAOWeight); lighting.direct.specular = APPLY_WEIGHT(lighting.direct.specular, aoFactor.directSpecularOcclusion, _SSAOWeight);
@@ -265,7 +266,7 @@ void UtsPostEvaluateBSDF(PositionInputs posInput, PreLightData preLightData, Uts
#if !defined(_INDIRECT_DIFFUSE_MODE_OFF) || !defined(_INDIRECT_SPECULAR_MODE_OFF) #if !defined(_INDIRECT_DIFFUSE_MODE_OFF) || !defined(_INDIRECT_SPECULAR_MODE_OFF)
AmbientOcclusionFactor aoFactor; AmbientOcclusionFactor aoFactor;
GetScreenSpaceAmbientOcclusionMultibounce(posInput.positionSS, preLightData.NdotV, bsdfData.perceptualRoughness, bsdfData.ambientOcclusion, bsdfData.specularOcclusion, bsdfData.diffuseColor, bsdfData.fresnel0, aoFactor); GetScreenSpaceAmbientOcclusionMultibounce(posInput.positionSS, preLightData.NdotV, bsdfData.perceptualRoughness, bsdfData.ambientOcclusion, bsdfData.specularOcclusion, bsdfData.diffuseColor, bsdfData.fresnel0, aoFactor);
ApplyAmbientOcclusion(aoFactor, builtinData, lighting); ApplyAmbientOcclusion(aoFactor, bsdfData, builtinData, lighting);
#endif #endif
AdjustIndirectLighting(preLightData, bsdfData, builtinData, lighting); AdjustIndirectLighting(preLightData, bsdfData, builtinData, lighting);
@@ -274,7 +275,6 @@ void UtsPostEvaluateBSDF(PositionInputs posInput, PreLightData preLightData, Uts
lightLoopOutput.specularLighting = lighting.direct.specular + lighting.indirect.specularReflected; lightLoopOutput.specularLighting = lighting.direct.specular + lighting.indirect.specularReflected;
// Rescale the GGX to account for the multiple scattering. // Rescale the GGX to account for the multiple scattering.
lightLoopOutput.specularLighting *= 1.0 + bsdfData.fresnel0 * preLightData.energyCompensation; lightLoopOutput.specularLighting *= 1.0 + bsdfData.fresnel0 * preLightData.energyCompensation;
ApplyExposureAdjustment(lightLoopOutput.diffuseLighting); ApplyExposureAdjustment(lightLoopOutput.diffuseLighting);
ApplyExposureAdjustment(lightLoopOutput.specularLighting); ApplyExposureAdjustment(lightLoopOutput.specularLighting);
} }

View File

@@ -19,25 +19,6 @@ int eAngelRing = 4;
int eRimLight = 5; int eRimLight = 5;
int eOutline = 6; int eOutline = 6;
int GetNextDirectionalLightIndex(BuiltinData builtinData, int currentIndex, int mainLightIndex)
{
int i = 0; // Declare once to avoid the D3D11 compiler warning.
for (i = 0; i < (int)_DirectionalLightCount; ++i)
{
if (IsMatchingLightLayer(_DirectionalLightDatas[i].lightLayers, builtinData.renderingLayers))
{
if (mainLightIndex != i)
{
if (currentIndex < i)
{
return i;
}
}
}
}
return -1; // not found
}
bool UtsUseScreenSpaceShadow(DirectionalLightData light, float3 normalWS) bool UtsUseScreenSpaceShadow(DirectionalLightData light, float3 normalWS)
{ {
#if defined(RAY_TRACED_SCREEN_SPACE_SHADOW_FLAG) #if defined(RAY_TRACED_SCREEN_SPACE_SHADOW_FLAG)
@@ -50,18 +31,7 @@ bool UtsUseScreenSpaceShadow(DirectionalLightData light, float3 normalWS)
return (validScreenSpaceShadow && ((rayTracedShadow && visibleLight) || !rayTracedShadow)); return (validScreenSpaceShadow && ((rayTracedShadow && visibleLight) || !rayTracedShadow));
#else #else
return ((light.screenSpaceShadowIndex & SCREEN_SPACE_SHADOW_INDEX_MASK) != INVALID_SCREEN_SPACE_SHADOW); return ((light.screenSpaceShadowIndex & SCREEN_SPACE_SHADOW_INDEX_MASK) != INVALID_SCREEN_SPACE_SHADOW);
#endif #endif
}
bool IsNonZeroBSDF(float3 L, UtsBSDFData bsdfData)
{
#if _MATERIAL_TYPE_FACE
return true;
#else
float NdotL = dot(bsdfData.normalWS, L);
return NdotL > 0.0;
#endif
} }
void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bsdfData, BuiltinData builtinData, void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bsdfData, BuiltinData builtinData,
@@ -99,10 +69,10 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
// Is it worth sampling the shadow map? // Is it worth sampling the shadow map?
// Should we skip it if NdotL is negative? (i.e. transmission) // Should we skip it if NdotL is negative? (i.e. transmission)
if ((light.lightDimmer > 0) && (light.shadowDimmer > 0)) if ((light.lightDimmer > 0) && (light.shadowDimmer > 0) && IsNonZeroBSDF(L, bsdfData))
{ {
context.shadowValue = GetDirectionalShadowAttenuation(context.shadowContext, context.shadowValue = GetDirectionalShadowAttenuation(context.shadowContext,
posInput.positionSS, posInput.positionWS + L * _ShadowDistanceBias, UtsGetShadowNormal(bsdfData), posInput.positionSS, posInput.positionWS + L * UtsGetShadowSlopeBias(bsdfData.normalWS, L), UtsGetShadowNormal(bsdfData),
light.shadowIndex, L); light.shadowIndex, L);
} }
} }
@@ -226,7 +196,7 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
// 3. Sky Reflection // 3. Sky Reflection
// Apply SSR. // Apply SSR.
#if (defined(_SURFACE_TYPE_TRANSPARENT) && !defined(_DISABLE_SSR_TRANSPARENT)) || (!defined(_SURFACE_TYPE_TRANSPARENT) && !defined(_DISABLE_SSR)) #if (defined(_SURFACE_TYPE_TRANSPARENT) && !defined(_DISABLE_SSR_TRANSPARENT)) || (!defined(_SURFACE_TYPE_TRANSPARENT) && !defined(_DISABLE_SSR)) && defined(_INDIRECT_SPECULAR_MODE_IBL)
{ {
IndirectLighting lighting = UtsEvaluateBSDF_ScreenSpaceReflection(posInput, preLightData, reflectionHierarchyWeight); IndirectLighting lighting = UtsEvaluateBSDF_ScreenSpaceReflection(posInput, preLightData, reflectionHierarchyWeight);
AccumulateIndirectLighting(lighting, aggregateLighting); AccumulateIndirectLighting(lighting, aggregateLighting);
@@ -357,9 +327,10 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
#endif #endif
} }
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_STOCKING)) if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_ANGEL_RING))
{ {
UtsEvaluateLighting_Stocking(fragInputs, posInput, bsdfData.normalWS, V, aggregateLighting); DirectLighting lighting = UtsEvaluateLighting_AngelRing(fragInputs, bsdfData.normalWS, V);
AccumulateDirectLighting(lighting, aggregateLighting);
} }
#ifndef _LIGHT_BASE_RIM_LIGHT_ON #ifndef _LIGHT_BASE_RIM_LIGHT_ON
@@ -370,10 +341,9 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
} }
#endif #endif
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_ANGEL_RING)) if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_STOCKING))
{ {
DirectLighting lighting = UtsEvaluateLighting_AngelRing(fragInputs, bsdfData.normalWS, V); UtsEvaluateLighting_Stocking(fragInputs, posInput, preLightData, bsdfData.normalWS, V, aggregateLighting);
AccumulateDirectLighting(lighting, aggregateLighting);
} }
UtsPostEvaluateBSDF(posInput, preLightData, bsdfData, builtinData, aggregateLighting, lightLoopOutput); UtsPostEvaluateBSDF(posInput, preLightData, bsdfData, builtinData, aggregateLighting, lightLoopOutput);

View File

@@ -53,6 +53,7 @@ float3 ComputeSpecularTerm(UtsBSDFData bsdfData, PreLightData preLightData, floa
DV = DV_SmithJointGGXAniso(TdotH, BdotH, NdotH, clampedNdotV, TdotL, BdotL, abs(NdotL), bsdfData.roughnessT, bsdfData.roughnessB, partLambdaV); DV = DV_SmithJointGGXAniso(TdotH, BdotH, NdotH, clampedNdotV, TdotL, BdotL, abs(NdotL), bsdfData.roughnessT, bsdfData.roughnessB, partLambdaV);
#elif _PBR_MODE_HAIR #elif _PBR_MODE_HAIR
// TODO: Double layer anisotropic specular.
float3 t = ShiftTangent(bsdfData.bitangentWS, N, bsdfData.anisotropy); float3 t = ShiftTangent(bsdfData.bitangentWS, N, bsdfData.anisotropy);
float specularExponent = RoughnessToBlinnPhongSpecularExponent(PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness)); float specularExponent = RoughnessToBlinnPhongSpecularExponent(PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness));
DV = D_KajiyaKay(t, H, specularExponent); DV = D_KajiyaKay(t, H, specularExponent);
@@ -108,7 +109,7 @@ half3 FitWithCurveApprox(half NdotL, half Curvature)
return lerp(curve0, curve1, mad(oneMinusCurva2, -1.0 * oneMinusCurva2, 1.0)); return lerp(curve0, curve1, mad(oneMinusCurva2, -1.0 * oneMinusCurva2, 1.0));
} }
DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, PreLightData preLightData, SHADOW_TYPE shadow, DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, PreLightData preLightData, SHADOW_TYPE shadow,
float3 lightColor, float3 V, float3 L, float2 uv, float3 lightColor, float3 V, float3 L, float2 uv,
float diffuseDimmer, float specularDimmer) float diffuseDimmer, float specularDimmer)
{ {
@@ -119,7 +120,7 @@ DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, Pr
{ {
SHADOW_TYPE sharpShadow = smoothstep(0.4, 0.6, shadow); SHADOW_TYPE sharpShadow = smoothstep(0.4, 0.6, shadow);
#if _RECEIVE_HAIR_SHADOW_ON && ENABLE_UTS_HAIR_SHAOW #if _RECEIVE_HAIR_SHADOW_ON && ENABLE_UTS_HAIR_SHAOW
sharpShadow *= GetHairShadow(posInput, L); sharpShadow *= GetHairShadow(posInput, L, bsdfData.normalWS);
#endif #endif
#if _SHADING_MODE_SDF #if _SHADING_MODE_SDF
@@ -132,6 +133,8 @@ DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, Pr
float3 diffuseTerm = 0.0; float3 diffuseTerm = 0.0;
float3 specularTerm = ComputeSpecularTerm(bsdfData, preLightData, V, L); float3 specularTerm = ComputeSpecularTerm(bsdfData, preLightData, V, L);
float NdotL = dot(bsdfData.normalWS, L);
#if _USE_SHADING_RAMP_MAP_ON #if _USE_SHADING_RAMP_MAP_ON
float rampMask = _ShadingRampMask; float rampMask = _ShadingRampMask;
@@ -140,22 +143,20 @@ DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, Pr
#endif #endif
#if _SHADING_MODE_STANDARD #if _SHADING_MODE_STANDARD
float NdotL = dot(bsdfData.normalWS, L);
float halfLambert = 0.5 * NdotL + 0.5; float halfLambert = 0.5 * NdotL + 0.5;
float3 rampColor = SAMPLE_TEXTURE2D_ARRAY(_ShadingRampMap, s_linear_clamp_sampler, float2(halfLambert * shadow.x, rampMask), _ShadingIndex).rgb; float3 rampColor = SAMPLE_TEXTURE2D_ARRAY_LOD(_ShadingRampMap, s_linear_clamp_sampler, float2(halfLambert * sharpShadow.x, rampMask), _ShadingIndex, 0).rgb;
diffuseTerm = bsdfData.diffuseColor * rampColor * INV_PI; diffuseTerm = bsdfData.diffuseColor * rampColor * INV_PI;
specularTerm *= saturate(NdotL) * sharpShadow; specularTerm *= saturate(NdotL) * sharpShadow;
#elif _SHADING_MODE_SDF #elif _SHADING_MODE_SDF
float3 rampColor = SAMPLE_TEXTURE2D_ARRAY(_ShadingRampMap, s_linear_clamp_sampler, float2(sdfShadowMask * sharpShadow.x, rampMask), _ShadingIndex).rgb; float3 rampColor = SAMPLE_TEXTURE2D_ARRAY_LOD(_ShadingRampMap, s_linear_clamp_sampler, float2(sdfShadowMask * sharpShadow.x, rampMask), _ShadingIndex, 0).rgb;
diffuseTerm = bsdfData.diffuseColor * rampColor * INV_PI; diffuseTerm = bsdfData.diffuseColor * rampColor * INV_PI;
specularTerm = (specularTerm + sdfHighlight) * sdfShadowMask * sharpShadow; specularTerm = (specularTerm + sdfHighlight) * sdfShadowMask * sharpShadow;
#endif #endif
#else #else
#if _SHADING_MODE_STANDARD #if _SHADING_MODE_STANDARD
float NdotL = dot(bsdfData.normalWS, L);
float halfLambert = 0.5 * NdotL + 0.5; float halfLambert = 0.5 * NdotL + 0.5;
// float firstColorFeatherForMask = lerp(_1stShadeColorFeather, 0.0, max(_ComposerMaskMode, _FirstShadeOverridden)); // float firstColorFeatherForMask = lerp(_1stShadeColorFeather, 0.0, max(_ComposerMaskMode, _FirstShadeOverridden));

View File

@@ -6,13 +6,21 @@ float3 UtsGetShadowNormal(UtsBSDFData bsdfData)
#if _MATERIAL_TYPE_FACE #if _MATERIAL_TYPE_FACE
return normalize(mul(UNITY_MATRIX_M, float4(0.0, 0.0, 1.0, 0.0))).xyz; return normalize(mul(UNITY_MATRIX_M, float4(0.0, 0.0, 1.0, 0.0))).xyz;
#else #else
return bsdfData.geomNormalWS * (1.0 + _ShadowNormalBias); return bsdfData.normalWS * (1.0 + _ShadowNormalBias);
#endif #endif
} }
float UtsGetShadowSlopeBias(float3 N, float3 L)
{
// The slope bias is used to avoid shadow acne.
// It is calculated based on the angle between the normal and the light direction.
// The more perpendicular the light is to the surface, the more bias we apply.
float NdotL = dot(N, L);
return (1.0 - NdotL) * _ShadowDistanceBias;
}
float3 SampleSDFTexture(float3 L, float2 uv, out float angle) float3 SampleSDFTexture(float3 L, float2 uv, out float angle)
{ {
// TODO: Move sdf sample result to UtsBSDFData to avoid sampleing in a loop
float2 right_uv = float2(1 - uv.x, uv.y); float2 right_uv = float2(1 - uv.x, uv.y);
float3 left_SDFTex = SAMPLE_TEXTURE2D(_SDFShadingMap, sampler_SDFShadingMap, uv).rgb; float3 left_SDFTex = SAMPLE_TEXTURE2D(_SDFShadingMap, sampler_SDFShadingMap, uv).rgb;
float3 right_SDFTex = SAMPLE_TEXTURE2D(_SDFShadingMap, sampler_SDFShadingMap, right_uv).rgb; float3 right_SDFTex = SAMPLE_TEXTURE2D(_SDFShadingMap, sampler_SDFShadingMap, right_uv).rgb;
@@ -27,7 +35,7 @@ float3 SampleSDFTexture(float3 L, float2 uv, out float angle)
return isRightSide ? right_SDFTex : left_SDFTex; return isRightSide ? right_SDFTex : left_SDFTex;
} }
float GetHairShadow(PositionInputs posInput, float3 L) float GetHairShadow(PositionInputs posInput, float3 L, float N)
{ {
float shadow = 1.0; float shadow = 1.0;
@@ -37,18 +45,21 @@ float GetHairShadow(PositionInputs posInput, float3 L)
if (hairShadowOpacity > 0.0) if (hairShadowOpacity > 0.0)
{ {
float3 viewLightDir = TransformWorldToViewDir(L); float3 viewLightDir = TransformWorldToViewDir(L);
float shadowLengthY = _HairShadowDistance * 5.0 * max(0.5, posInput.linearDepth * _HairShadowDistanceScaleFactor) / posInput.linearDepth; float distance = _HairShadowDistance + max(0.0, posInput.linearDepth * _HairShadowDistanceScaleFactor);
float2 shadowLength = float2(shadowLengthY * 2.0f, shadowLengthY); float3 viewOffsetPos = TransformWorldToView(posInput.positionWS) + viewLightDir * distance * 0.01;
float4 clipPos = mul(UNITY_MATRIX_P, float4(viewOffsetPos, 1.0));
float3 cameraDirOS = normalize(TransformWorldToObject(GetCameraPositionWS())); float2 samplingPointSS = clipPos.xy / clipPos.w;
float cameraDirFactor = 1.0 - smoothstep(0.1, 0.9, cameraDirOS.y); samplingPointSS = samplingPointSS * 0.5 + 0.5;
// shadowLength.y *= cameraDirFactor;
#if UNITY_UV_STARTS_AT_TOP
// TODO: sample point is still shifting when fov change. samplingPointSS.y = 1.0 - samplingPointSS.y;
float2 samplingPoint = (posInput.positionSS + shadowLength * viewLightDir.xy) * _ScreenSize.zw; // Use 1080p as the reference resolution to achieve consistent shadow lengths across various screen resolutions. #endif
float2 scaledUVs = samplingPoint * _RTHandleScale.xy; // We have to including the scaling factor for our shadow map since we are not going to allocate new texture if the rendering resolution changed. float NdotL = saturate(dot(N, L));
float hairShadow = SAMPLE_TEXTURE2D_SHADOW(_HairShadowTex, s_linear_clamp_compare_sampler, float3(scaledUVs, posInput.deviceDepth + _HairShadowDepthBias)).r; float slopeBias = (1.0 - NdotL) * _HairShadowDepthBias;
float2 scaledUVs = samplingPointSS * _RTHandleScale.xy; // We have to including the scaling factor for our shadow map since we are not going to allocate new texture if the rendering resolution changed.
float hairShadow = SAMPLE_TEXTURE2D_SHADOW(_HairShadowTex, s_linear_clamp_compare_sampler, float3(scaledUVs, posInput.deviceDepth + slopeBias)).r;
shadow = lerp(1.0 - hairShadowOpacity, 1.0, hairShadow); shadow = lerp(1.0 - hairShadowOpacity, 1.0, hairShadow);
} }
@@ -77,9 +88,9 @@ SHADOW_TYPE UtsEvaluateShadow_Punctual(LightLoopContext lightLoopContext, Positi
} }
else else
#endif #endif
if ((light.shadowIndex >= 0) && (light.shadowDimmer > 0)) if ((light.shadowIndex >= 0) && (light.shadowDimmer > 0) && IsNonZeroBSDF(L, N))
{ {
shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, posInput.positionSS, posInput.positionWS + L * _ShadowDistanceBias, N, light.shadowIndex, L, distances.x, light.lightType == GPULIGHTTYPE_POINT, light.lightType != GPULIGHTTYPE_PROJECTOR_BOX); shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, posInput.positionSS, posInput.positionWS + L * UtsGetShadowSlopeBias(N, L), N, light.shadowIndex, L, distances.x, light.lightType == GPULIGHTTYPE_POINT, light.lightType != GPULIGHTTYPE_PROJECTOR_BOX);
#ifdef SHADOWS_SHADOWMASK #ifdef SHADOWS_SHADOWMASK
// Note: Legacy Unity have two shadow mask mode. ShadowMask (ShadowMask contain static objects shadow and ShadowMap contain only dynamic objects shadow, final result is the minimun of both value) // Note: Legacy Unity have two shadow mask mode. ShadowMask (ShadowMask contain static objects shadow and ShadowMap contain only dynamic objects shadow, final result is the minimun of both value)

View File

@@ -33,6 +33,13 @@ TEXTURE2D(_SSSLutMap);
TEXTURE2D(_HairBlendingMap); TEXTURE2D(_HairBlendingMap);
SAMPLER(sampler_HairBlendingMap); SAMPLER(sampler_HairBlendingMap);
TEXTURE2D(_EmissiveColorMap);
SAMPLER(sampler_EmissiveColorMap);
// Stocking
TEXTURE2D(_StockingSparkingMap);
SAMPLER(sampler_StockingSparkingMap);
// Global // Global
TEXTURE2D(_HairShadowTex); TEXTURE2D(_HairShadowTex);
TEXTURE2D_X(_HairBlendingTex); TEXTURE2D_X(_HairBlendingTex);

View File

@@ -2,6 +2,8 @@
float _SurfaceFeatures; float _SurfaceFeatures;
half _AlphaCutoffEnable; half _AlphaCutoffEnable;
float _AlphaCutoff; float _AlphaCutoff;
half _BlendMode;
float4 _DoubleSidedConstants;
// Shading Color // Shading Color
float4 _BaseColor; float4 _BaseColor;
@@ -66,6 +68,8 @@ float _EnergyConservingSpecularColor;
float3 _EmissiveColor; float3 _EmissiveColor;
half _AlbedoAffectEmissive; half _AlbedoAffectEmissive;
half _EmissiveExposureWeight; half _EmissiveExposureWeight;
float4 _EmissiveColorMap_ST;
half _TexWorldScaleEmissive;
float _ObjectSpaceUVMappingEmissive; float _ObjectSpaceUVMappingEmissive;
@@ -84,6 +88,13 @@ float _IndirectSpecularMatCapLod;
float _IndirectSpecularIntensity; float _IndirectSpecularIntensity;
float _SSRWeight; float _SSRWeight;
// Angle Ring
float4 _AngelRingColor;
float4 _AngelRingColorMap_ST;
float _AngelRingIntensity;
float _AngelRingOffsetU;
float _AngelRingOffsetV;
//Rim Light //Rim Light
float4 _RimLightColor; float4 _RimLightColor;
float _RimLightIntensity; float _RimLightIntensity;
@@ -94,12 +105,12 @@ float _RimLightClippingLevel;
float _LightDirectionRimLightLevel; float _LightDirectionRimLightLevel;
// Angle Ring // Stocking
float4 _AngelRingColor; float _StockingFresnelWidth;
float4 _AngelRingColorMap_ST; float _StockingSparkleSpacing;
float _AngelRingIntensity; float _StockingSparkleAmount;
float _AngelRingOffsetU; float _StockingSparkleSize;
float _AngelRingOffsetV; float _StockingSparkleIntensity;
// Outline // Outline
float _OutlineWidth; float _OutlineWidth;
@@ -125,10 +136,6 @@ float _Minimal_Diffuse_Contribution;
// Light Loop // Light Loop
float3 _ObjectCenterPositionWS; float3 _ObjectCenterPositionWS;
// NOTE: Not sure what these are for
// float _FirstShadeOverridden;
// float _SecondShadeOverridden;
float _UseShadowThreshold; float _UseShadowThreshold;
float _AlphaCutoffShadow; float _AlphaCutoffShadow;
float _ComposerMaskMode; float _ComposerMaskMode;

View File

@@ -41,7 +41,6 @@ PackedVaryingsType Vert(AttributesMesh inputMesh)
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR #endif // _WRITE_TRANSPARENT_MOTION_VECTOR
#ifdef UNITY_VIRTUAL_TEXTURING #ifdef UNITY_VIRTUAL_TEXTURING
#define VT_BUFFER_TARGET SV_Target1 #define VT_BUFFER_TARGET SV_Target1
#define EXTRA_BUFFER_TARGET SV_Target2 #define EXTRA_BUFFER_TARGET SV_Target2
@@ -49,8 +48,6 @@ PackedVaryingsType Vert(AttributesMesh inputMesh)
#define EXTRA_BUFFER_TARGET SV_Target1 #define EXTRA_BUFFER_TARGET SV_Target1
#endif #endif
void Frag(PackedVaryingsToPS packedInput, void Frag(PackedVaryingsToPS packedInput,
#ifdef OUTPUT_SPLIT_LIGHTING #ifdef OUTPUT_SPLIT_LIGHTING
out float4 outColor : SV_Target0, // outSpecularLighting out float4 outColor : SV_Target0, // outSpecularLighting
@@ -87,34 +84,40 @@ void Frag(PackedVaryingsToPS packedInput,
discard; discard;
#endif #endif
float4 objPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1)); float4 objPos = mul(UNITY_MATRIX_M, float4(0, 0, 0, 1));
float4 uv0 = input.texCoord0; float4 uv0 = input.texCoord0;
float3 envLightSource_GradientEquator = ShadeSH9(float4(0, 1, 0, 0));
float3 envLightSource_SkyboxIntensity = max(
SampleBakedGI_UTS_OutLine(objPos.xyz, float3(0.0, 1.0, 0.0), input.texCoord1.xy, input.texCoord2.xy),
SampleBakedGI_UTS_OutLine(objPos.xyz, float3(0.0, -1.0, -0.0), input.texCoord1.xy, input.texCoord2.xy)
).rgb;
float3 ambientSkyColor = envLightSource_SkyboxIntensity.rgb > 0.0 ? envLightSource_SkyboxIntensity : envLightSource_GradientEquator;
ambientSkyColor *= GetCurrentExposureMultiplier() * _SkyColorIntensity;
float3 baseColor = SAMPLE_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, TRANSFORM_TEX(uv0, _BaseColorMap)).rgb;
baseColor *= _BaseColor.rgb;
float4 outlineColor = _OutlineColor; float4 outlineColor = _OutlineColor;
outlineColor.rgb = lerp(outlineColor.rgb, outlineColor.rgb + ambientSkyColor, _SkyColorAffectOutline);
#if _OUTLINECOLORMAP #if _OUTLINECOLORMAP
outlineColor *= SAMPLE_TEXTURE2D(_OutlineColorMap, sampler_OutlineColorMap, TRANSFORM_TEX(uv0, _BaseColorMap)).rgb; outlineColor *= SAMPLE_TEXTURE2D(_OutlineColorMap, sampler_OutlineColorMap, TRANSFORM_TEX(uv0, _BaseColorMap)).rgb;
#endif #endif
outlineColor.rgb = lerp(outlineColor.rgb, outlineColor.rgb * baseColor, _AlbedoAffectOutline);
float3 volColor, volOpacity;
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize(); float3 baseColor = 1.0;
if (_AlbedoAffectOutline > 0.5)
{
baseColor = SAMPLE_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, TRANSFORM_TEX(uv0, _BaseColorMap)).rgb;
baseColor *= _BaseColor.rgb;
}
outlineColor.rgb *= baseColor;
float3 ambientSkyColor = 0.0;
if (_SkyColorAffectOutline > 0.5)
{
float3 envLightSource_GradientEquator = ShadeSH9(float4(0, 1, 0, 0));
float3 envLightSource_SkyboxIntensity = max(
SampleBakedGI_UTS_OutLine(objPos.xyz, float3(0.0, 1.0, 0.0), input.texCoord1.xy, input.texCoord2.xy),
SampleBakedGI_UTS_OutLine(objPos.xyz, float3(0.0, -1.0, 0.0), input.texCoord1.xy, input.texCoord2.xy)
).rgb;
ambientSkyColor = envLightSource_SkyboxIntensity.rgb > 0.0 ? envLightSource_SkyboxIntensity : envLightSource_GradientEquator;
ambientSkyColor *= GetCurrentExposureMultiplier() * _SkyColorIntensity;
}
outlineColor.rgb += outlineColor.rgb * ambientSkyColor;
// input.positionSS is SV_Position // input.positionSS is SV_Position
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex); PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS); float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
float3 volColor, volOpacity;
EvaluateAtmosphericScattering(posInput, V, volColor, volOpacity); // Premultiplied alpha EvaluateAtmosphericScattering(posInput, V, volColor, volOpacity); // Premultiplied alpha
outlineColor.rgb = outlineColor.rgb * (1 - volOpacity) + volColor; outlineColor.rgb = outlineColor.rgb * (1 - volOpacity) + volColor;
outColor = outlineColor; outColor = outlineColor;
@@ -126,5 +129,3 @@ void Frag(PackedVaryingsToPS packedInput,
outVTFeedback = builtinData.vtPackedFeedback; outVTFeedback = builtinData.vtPackedFeedback;
#endif #endif
} }
// End of File

View File

@@ -1,9 +1,9 @@
float4 objPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1)); float4 objPos = mul(UNITY_MATRIX_M, float4(0, 0, 0, 1));
float4 _Outline_Sampler_var = SAMPLE_TEXTURE2D_LOD(_OutlineWidthMap, sampler_OutlineWidthMap, TRANSFORM_TEX(inputMesh.uv0, _BaseColorMap), 0.0); float4 _Outline_Sampler_var = SAMPLE_TEXTURE2D_LOD(_OutlineWidthMap, sampler_OutlineWidthMap, TRANSFORM_TEX(inputMesh.uv0, _BaseColorMap), 0.0);
//v.2.0.4.3 baked Normal Texture for Outline //v.2.0.4.3 baked Normal Texture for Outline
float3 normalDir = UnityObjectToWorldNormal(inputMesh.normalOS); float3 normalDir = UnityObjectToWorldNormal(inputMesh.normalOS);
float3 tangentDir = normalize(mul(unity_ObjectToWorld, float4(inputMesh.tangentOS.xyz, 0.0)).xyz); float3 tangentDir = normalize(mul(UNITY_MATRIX_M, float4(inputMesh.tangentOS.xyz, 0.0)).xyz);
float3 bitangentDir = normalize(cross(normalDir, tangentDir) * inputMesh.tangentOS.w); float3 bitangentDir = normalize(cross(normalDir, tangentDir) * inputMesh.tangentOS.w);
float3x3 tangentTransform = float3x3(tangentDir, bitangentDir, normalDir); float3x3 tangentTransform = float3x3(tangentDir, bitangentDir, normalDir);
//end //end

View File

@@ -79,22 +79,13 @@ void Frag(PackedVaryingsToPS packedInput,
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput); UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput);
FragInputs input = UnpackVaryingsMeshToFragInputs(packedInput.vmesh); FragInputs input = UnpackVaryingsToFragInputs(packedInput);
#if defined(PLATFORM_SUPPORTS_PRIMITIVE_ID_IN_PIXEL_SHADER) && SHADER_STAGE_FRAGMENT
#if (defined(VARYINGS_NEED_PRIMITIVEID) || (SHADERPASS == SHADERPASS_FULL_SCREEN_DEBUG))
input.primitiveID = packedInput.primitiveID;
#endif
#endif
#if defined(VARYINGS_NEED_CULLFACE) && SHADER_STAGE_FRAGMENT
input.isFrontFace = IS_FRONT_VFACE(packedInput.cullFace, true, false);
#endif
// We need to readapt the SS position as our screen space positions are for a low res buffer, but we try to access a full res buffer. // We need to readapt the SS position as our screen space positions are for a low res buffer, but we try to access a full res buffer.
input.positionSS.xy = _OffScreenRendering > 0 ? (input.positionSS.xy * _OffScreenDownsampleFactor) : input.positionSS.xy; input.positionSS.xy = _OffScreenRendering > 0 ? (input.positionSS.xy * _OffScreenDownsampleFactor) : input.positionSS.xy;
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize(); uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex); PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);
#ifdef VARYINGS_NEED_POSITION_WS #ifdef VARYINGS_NEED_POSITION_WS
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS); float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
@@ -119,6 +110,10 @@ void Frag(PackedVaryingsToPS packedInput,
SurfaceData tempSurfaceData; SurfaceData tempSurfaceData;
BuiltinData builtinData; BuiltinData builtinData;
UtsGetSurfaceAndBuiltinData(input, V, posInput, tempSurfaceData, builtinData); UtsGetSurfaceAndBuiltinData(input, V, posInput, tempSurfaceData, builtinData);
float3 doubleSidedConstants = GetDoubleSidedConstants();
ApplyDoubleSidedFlipOrMirror(input, doubleSidedConstants);
UTSSurfaceData surfaceData = GetUTSSurfaceData(input, V); UTSSurfaceData surfaceData = GetUTSSurfaceData(input, V);
UtsBSDFData bsdfData = ConvertUTSSurfaceDataToUTSBSDFData(surfaceData); UtsBSDFData bsdfData = ConvertUTSSurfaceDataToUTSBSDFData(surfaceData);
@@ -153,6 +148,10 @@ void Frag(PackedVaryingsToPS packedInput,
float4 hairBlendingTex = LOAD_TEXTURE2D_X(_HairBlendingTex, screenUV); float4 hairBlendingTex = LOAD_TEXTURE2D_X(_HairBlendingTex, screenUV);
outColor.rgb = lerp(outColor.rgb, hairBlendingTex.rgb, hairBlendingTex.a * _HairBlendingFactor); outColor.rgb = lerp(outColor.rgb, hairBlendingTex.rgb, hairBlendingTex.a * _HairBlendingFactor);
#endif #endif
#if _ENABLE_FOG_ON_TRANSPARENT && _SURFACE_TYPE_TRANSPARENT
outColor = EvaluateAtmosphericScattering(posInput, V, outColor);
#endif
#if UTS_DEBUG_SHADOWMAP || UTS_DEBUG_SELFSHADOW #if UTS_DEBUG_SHADOWMAP || UTS_DEBUG_SELFSHADOW
outColor.rgb = 1; outColor.rgb = 1;
@@ -176,5 +175,6 @@ void Frag(PackedVaryingsToPS packedInput,
outVTFeedback = builtinData.vtPackedFeedback; outVTFeedback = builtinData.vtPackedFeedback;
#endif #endif
} //outColor.rgb = input.isFrontFace;
}

View File

@@ -23,14 +23,18 @@ namespace Misaki.HdrpToon
Shader.SetGlobalFloat("_Outline_MaxWidth", utsRenderer.outlineMaxWidth.value * 0.01f); Shader.SetGlobalFloat("_Outline_MaxWidth", utsRenderer.outlineMaxWidth.value * 0.01f);
var renderConfig = HDUtils.GetRendererConfiguration(false, false); var renderConfig = HDUtils.GetRendererConfiguration(false, false);
var result = new UnityEngine.Rendering.RendererUtils.RendererListDesc(UtsShaderPassName.outlinePassId, ctx.cullingResults, ctx.hdCamera.camera) var result = new UnityEngine.Rendering.RendererUtils.RendererListDesc(UTSPassName.outlinePassId, ctx.cullingResults, ctx.hdCamera.camera)
{ {
rendererConfiguration = renderConfig, rendererConfiguration = renderConfig,
renderQueueRange = GetRenderQueueRange(RenderQueueType.All), renderQueueRange = GetRenderQueueRange(RenderQueueType.AllOpaque),
excludeObjectMotionVectors = false, excludeObjectMotionVectors = false,
}; };
CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result)); #if UNITY_6000_3_OR_NEWER
CoreUtils.DrawRendererList(ctx.cmd, ctx.renderContext.CreateRendererList(result));
#else
CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result, ctx.hdCamera));
#endif
} }
} }
} }

View File

@@ -127,9 +127,9 @@ namespace Misaki.HdrpToon
} }
} }
private bool ShouldReallocateHairShadowBuffer() private static bool IsRTHandleValid(RTHandle rtHandle)
{ {
return _hairShadowRTHandle == null || _hairShadowRTHandle.rt == null || !_hairShadowRTHandle.rt.IsCreated() || _needReallocateHairShadow; return rtHandle != null && rtHandle.rt != null && rtHandle.rt.IsCreated();
} }
private void ReallocateHairShadowBuffer() private void ReallocateHairShadowBuffer()
@@ -141,12 +141,11 @@ namespace Misaki.HdrpToon
} }
#endif #endif
// Use R8 or R16 directly?
var format = _hairShadowQuality switch var format = _hairShadowQuality switch
{ {
BufferQuality.Low => GraphicsFormat.D16_UNorm, BufferQuality.Low => GraphicsFormat.D16_UNorm,
BufferQuality.High => GraphicsFormat.D32_SFloat, BufferQuality.High => GraphicsFormat.D32_SFloat,
_ => GraphicsFormat.R16G16B16A16_SFloat _ => GraphicsFormat.D16_UNorm
}; };
_hairShadowRTHandle?.Release(); _hairShadowRTHandle?.Release();
@@ -156,11 +155,6 @@ namespace Misaki.HdrpToon
_needReallocateHairShadow = false; _needReallocateHairShadow = false;
} }
private bool ShouldReallocateHairBlendingBuffer()
{
return _hairBlendingRTHandle == null || _hairBlendingRTHandle.rt == null || !_hairBlendingRTHandle.rt.IsCreated() || _needReallocateHairBlending;
}
private void ReallocateHairBlendingBuffer() private void ReallocateHairBlendingBuffer()
{ {
#if UNITY_EDITOR #if UNITY_EDITOR
@@ -262,7 +256,7 @@ namespace Misaki.HdrpToon
return; return;
} }
if (ShouldReallocateHairShadowBuffer()) if (!IsRTHandleValid(_hairShadowRTHandle) || _needReallocateHairShadow)
{ {
ReallocateHairShadowBuffer(); ReallocateHairShadowBuffer();
return; return;
@@ -272,14 +266,18 @@ namespace Misaki.HdrpToon
{ {
CoreUtils.SetRenderTarget(ctx.cmd, _hairShadowRTHandle, ClearFlag.Depth); CoreUtils.SetRenderTarget(ctx.cmd, _hairShadowRTHandle, ClearFlag.Depth);
var result = new RendererListDesc(UtsShaderPassName.hairShadowCasterPassId, ctx.cullingResults, ctx.hdCamera.camera) var result = new RendererListDesc(UTSPassName.hairShadowCasterPassId, ctx.cullingResults, ctx.hdCamera.camera)
{ {
renderQueueRange = GetRenderQueueRange(RenderQueueType.AllOpaque), renderQueueRange = GetRenderQueueRange(RenderQueueType.AllOpaque),
sortingCriteria = SortingCriteria.CommonOpaque, sortingCriteria = SortingCriteria.CommonOpaque,
excludeObjectMotionVectors = false, excludeObjectMotionVectors = false,
}; };
CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result)); #if UNITY_6000_3_OR_NEWER
CoreUtils.DrawRendererList(ctx.cmd, ctx.renderContext.CreateRendererList(result));
#else
CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result, ctx.hdCamera));
#endif
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);
@@ -296,7 +294,7 @@ namespace Misaki.HdrpToon
return; return;
} }
if (ShouldReallocateHairBlendingBuffer()) if (!IsRTHandleValid(_hairBlendingRTHandle) || _needReallocateHairBlending)
{ {
ReallocateHairBlendingBuffer(); ReallocateHairBlendingBuffer();
return; return;
@@ -306,14 +304,18 @@ namespace Misaki.HdrpToon
{ {
CoreUtils.SetRenderTarget(ctx.cmd, _hairBlendingRTHandle, _hairBlendingDepthRTHandle, ClearFlag.Color | ClearFlag.Depth); CoreUtils.SetRenderTarget(ctx.cmd, _hairBlendingRTHandle, _hairBlendingDepthRTHandle, ClearFlag.Color | ClearFlag.Depth);
var result = new RendererListDesc(UtsShaderPassName.hairBlendingTargetPassId, ctx.cullingResults, ctx.hdCamera.camera) var result = new RendererListDesc(UTSPassName.hairBlendingTargetPassId, ctx.cullingResults, ctx.hdCamera.camera)
{ {
renderQueueRange = GetRenderQueueRange(RenderQueueType.AllOpaque), renderQueueRange = GetRenderQueueRange(RenderQueueType.AllOpaque),
sortingCriteria = SortingCriteria.CommonOpaque, sortingCriteria = SortingCriteria.CommonOpaque,
excludeObjectMotionVectors = false, excludeObjectMotionVectors = false,
}; };
CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result)); #if UNITY_6000_3_OR_NEWER
CoreUtils.DrawRendererList(ctx.cmd, ctx.renderContext.CreateRendererList(result));
#else
CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result, ctx.hdCamera));
#endif
} }
} }

View File

@@ -31,7 +31,7 @@ namespace Misaki.HdrpToon
targetDepthBuffer = CustomPass.TargetBuffer.None, targetDepthBuffer = CustomPass.TargetBuffer.None,
}; };
_outlinePass = new() _outlinePass = new UTSOutlinePass()
{ {
name = "UTS Outline", name = "UTS Outline",
targetColorBuffer = CustomPass.TargetBuffer.Camera, targetColorBuffer = CustomPass.TargetBuffer.Camera,
@@ -39,7 +39,7 @@ namespace Misaki.HdrpToon
}; };
CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.AfterOpaqueDepthAndNormal, _utsPass); CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.AfterOpaqueDepthAndNormal, _utsPass);
CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.BeforePostProcess, _outlinePass); CustomPassVolume.RegisterUniqueGlobalCustomPass(CustomPassInjectionPoint.BeforeTransparent, _outlinePass);
NotifyRendererSettingChanged(); NotifyRendererSettingChanged();
} }

View File

@@ -44,8 +44,36 @@ Shader "Hidden/Shader/UTSTonemapping"
inline float3 UTSToonmap(float3 x) inline float3 UTSToonmap(float3 x)
{ {
// See https://www.desmos.com/calculator/j4tpqazyfw #if 1
// GT Tonemap, see https://www.desmos.com/calculator/gslcdxvipg
float p = 1.0;
float a = 1.0;
float m = 0.22;
float l = 0.4;
float c = 1.33;
float b = 0.0;
float l0 = (l * (p - m)) / a;
float L0 = m - m / a;
float L1 = m + (1 - m) / a;
float3 Lx = m + a * (x - m);
float3 Tx = m * pow(x / m, c) + b;
float S0 = m + l0;
float S1 = m + a * l0;
float C2 = (a * p) / (p - S1);
float3 Sx = p - (p - S1) * exp(-(C2 * (x - S0)) / p);
float3 w0 = 1.0 - smoothstep( 0.0, m, x);
float3 w2 = smoothstep(m + l0, m + l0, x);
float3 w1 = 1.0 - w0 - w2;
return Tx * w0 + Lx * w1 + Sx * w2;
#else
// Modified ACES, see https://www.desmos.com/calculator/j4tpqazyfw
return (x * (2.63 * x + 0.03)) / (x * (2.11 * x + 0.72) + 0.31); return (x * (2.63 * x + 0.03)) / (x * (2.11 * x + 0.72) + 0.31);
#endif
} }
float4 CustomPostProcess(Varyings input) : SV_Target float4 CustomPostProcess(Varyings input) : SV_Target
@@ -55,9 +83,13 @@ Shader "Hidden/Shader/UTSTonemapping"
// Note that if HDUtils.DrawFullScreen is not used to render the post process, you don't need to call ClampAndScaleUVForBilinearPostProcessTexture. // Note that if HDUtils.DrawFullScreen is not used to render the post process, you don't need to call ClampAndScaleUVForBilinearPostProcessTexture.
float3 sourceColor = SAMPLE_TEXTURE2D_X(_MainTex, s_linear_clamp_sampler, ClampAndScaleUVForBilinearPostProcessTexture(input.texcoord.xy)).rgb; float3 sourceColor = SAMPLE_TEXTURE2D_X(_MainTex, s_linear_clamp_sampler, ClampAndScaleUVForBilinearPostProcessTexture(input.texcoord.xy)).rgb;
#if 1
float3 color = UTSToonmap(sourceColor);
#else
float whiteScale = 1.0 / UTSToonmap(5.3); float whiteScale = 1.0 / UTSToonmap(5.3);
float3 color = UTSToonmap(sourceColor * whiteScale); float3 color = UTSToonmap(sourceColor * whiteScale);
color *= whiteScale; color *= whiteScale;
#endif
return float4(color, 1); return float4(color, 1);
} }

270
Runtime/UTSAPI.cs Normal file
View File

@@ -0,0 +1,270 @@
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using static Misaki.HdrpToon.UTSPropertyName;
namespace Misaki.HdrpToon
{
internal enum RenderPriority
{
Opaque = RenderQueue.Geometry,
OpaqueDecal = RenderQueue.Geometry + 225, // Opaque Decal mean Opaque that can receive decal
OpaqueAlphaTest = RenderQueue.AlphaTest,
OpaqueDecalAlphaTest = RenderQueue.AlphaTest + 25,
// Warning: we must not change Geometry last value to stay compatible with occlusion
OpaqueLast = RenderQueue.GeometryLast,
AfterPostprocessOpaque = RenderQueue.GeometryLast + 1,
AfterPostprocessOpaqueAlphaTest = RenderQueue.GeometryLast + 10,
TransparentFirst = RenderQueue.Transparent - 100,
Transparent = RenderQueue.Transparent,
TransparentLast = RenderQueue.Transparent + 100,
}
internal enum StencilUsage
{
Clear = 0,
// Note: first bit is free and can still be used by both phases.
// --- Following bits are used before transparent rendering ---
IsUnlit = (1 << 0), // Unlit materials (shader and shader graph) except for the shadow matte
RequiresDeferredLighting = (1 << 1),
SubsurfaceScattering = (1 << 2), // SSS, Split Lighting
TraceReflectionRay = (1 << 3), // SSR or RTR - slot is reuse in transparent
Decals = (1 << 4), // Use to tag when an Opaque Decal is render into DBuffer
ObjectMotionVector = (1 << 5), // Animated object (for motion blur, SSR, SSAO, TAA)
// --- Stencil is cleared after opaque rendering has finished ---
// --- Following bits are used exclusively for what happens after opaque ---
WaterExclusion = (1 << 0), // Prevents water surface from being rendered.
ExcludeFromTUAndAA = (1 << 1), // Disable Temporal Upscaling and Antialiasing for certain objects
DistortionVectors = (1 << 2), // Distortion pass - reset after distortion pass, shared with SMAA
SMAA = (1 << 2), // Subpixel Morphological Antialiasing
// Reserved TraceReflectionRay = (1 << 3) for transparent SSR or RTR
Refractive = (1 << 4), // Indicates there's a refractive object
WaterSurface = (1 << 5), // Reserved for water surface usage (If update the value of 'STENCILUSAGE_WATER_SURFACE' in LensFlareCommon.hlsl)
// --- Following are user bits, we don't touch them inside HDRP and is up to the user to handle them ---
UserBit0 = (1 << 6),
UserBit1 = (1 << 7),
HDRPReservedBits = 255 & ~(UserBit0 | UserBit1),
}
internal class UTSAPI
{
public static void SetupPass(Material material)
{
var surfaceType = (SurfaceType)material.GetInteger(SurfaceOptions.SURFACE_TYPE);
var isTransparent = surfaceType == SurfaceType.Transparent;
material.SetShaderPassEnabled(UTSPassName.HAIR_SHADOW_CASTER_PASS_NAME, (MaterialType)material.GetInteger(SurfaceOptions.MATERIAL_TYPE) == MaterialType.FrontHair);
material.SetShaderPassEnabled(UTSPassName.HAIR_BLENDING_TARGET_PASS_NAME, material.GetInteger(SurfaceOptions.HAIR_BLENDING_TARGET) == 1);
var depthWriteEnable = material.GetInteger(InternalProperties.TRANSPARENT_DEPTH_PREPASS_ENABLE) == 1;
var ssrTransparent = material.GetInteger(SurfaceOptions.RECEIVES_SSR_TRANSPARENT) == 1;
var backFaceEnable = material.GetInteger(SurfaceOptions.TRANSPARENT_BACKFACE_ENABLE) == 1;
material.SetShaderPassEnabled(HDShaderPassNames.s_TransparentDepthPrepassStr, isTransparent && (depthWriteEnable || ssrTransparent));
material.SetShaderPassEnabled(HDShaderPassNames.s_TransparentDepthPostpassStr, material.GetInteger(InternalProperties.TRANSPARENT_DEPTH_POSTPASS_ENABLE) == 1 && isTransparent);
material.SetShaderPassEnabled(HDShaderPassNames.s_TransparentBackfaceStr, backFaceEnable && isTransparent);
}
public static void SetupKeywords(Material material)
{
var surfaceType = (SurfaceType)material.GetInteger(SurfaceOptions.SURFACE_TYPE);
var cullMode = (CullMode)material.GetInteger(SurfaceOptions.CULL_MODE);
var doubleSidedEnable = cullMode == CullMode.Off;
CoreUtils.SetKeyword(material, "_SURFACE_TYPE_TRANSPARENT", surfaceType == SurfaceType.Transparent);
CoreUtils.SetKeyword(material, "_DOUBLESIDED_ON", doubleSidedEnable);
CoreUtils.SetKeyword(material, "_DISABLE_SSR_TRANSPARENT", material.GetInteger(SurfaceOptions.RECEIVES_SSR_TRANSPARENT) == 0);
}
static public void ComputeStencilProperties(bool receivesLighting, bool forwardOnly, bool receivesSSR, bool useSplitLighting, bool hasRefraction, bool excludeFromTUAndAA,
out int stencilRef, out int stencilWriteMask, out int stencilRefDepth, out int stencilWriteMaskDepth, out int stencilRefGBuffer, out int stencilWriteMaskGBuffer, out int stencilRefMV, out int stencilWriteMaskMV)
{
// Stencil usage rules:
// TraceReflectionRay need to be tagged during depth prepass
// RequiresDeferredLighting need to be tagged during GBuffer
// SubsurfaceScattering need to be tagged during either GBuffer or Forward pass
// ObjectMotionVectors need to be tagged in velocity pass.
// As motion vectors pass can be use as a replacement of depth prepass it also need to have TraceReflectionRay
// As GBuffer pass can have no depth prepass, it also need to have TraceReflectionRay
// Object motion vectors is always render after a full depth buffer (if there is no depth prepass for GBuffer all object motion vectors are render after GBuffer)
// so we have a guarantee than when we write object motion vectors no other object will be draw on top (and so would have require to overwrite motion vectors).
// Final combination is:
// Prepass: TraceReflectionRay
// Motion vectors: TraceReflectionRay, ObjectVelocity
// GBuffer: LightingMask, ObjectVelocity
// Forward: LightingMask
stencilRef = (int)StencilUsage.Clear; // Forward case
stencilWriteMask = (int)StencilUsage.RequiresDeferredLighting | (int)StencilUsage.SubsurfaceScattering;
stencilRefDepth = 0;
stencilWriteMaskDepth = 0;
stencilRefGBuffer = (int)StencilUsage.RequiresDeferredLighting;
stencilWriteMaskGBuffer = (int)StencilUsage.RequiresDeferredLighting | (int)StencilUsage.SubsurfaceScattering;
stencilRefMV = (int)StencilUsage.ObjectMotionVector;
stencilWriteMaskMV = (int)StencilUsage.ObjectMotionVector;
// ForwardOnly materials with motion vectors are rendered after GBuffer, so we need to clear the deferred bit in the stencil
if (forwardOnly)
stencilWriteMaskMV |= (int)StencilUsage.RequiresDeferredLighting;
if (useSplitLighting)
{
stencilRefGBuffer |= (int)StencilUsage.SubsurfaceScattering;
stencilRef |= (int)StencilUsage.SubsurfaceScattering;
}
if (receivesSSR)
{
stencilRefDepth |= (int)StencilUsage.TraceReflectionRay;
stencilRefGBuffer |= (int)StencilUsage.TraceReflectionRay;
stencilRefMV |= (int)StencilUsage.TraceReflectionRay;
}
stencilWriteMaskDepth |= (int)StencilUsage.TraceReflectionRay;
stencilWriteMaskGBuffer |= (int)StencilUsage.TraceReflectionRay;
stencilWriteMaskMV |= (int)StencilUsage.TraceReflectionRay;
if (hasRefraction)
{
stencilRefDepth |= (int)StencilUsage.Refractive;
stencilWriteMaskDepth |= (int)StencilUsage.Refractive;
}
if (!receivesLighting)
{
stencilRefDepth |= (int)StencilUsage.IsUnlit;
stencilWriteMaskDepth |= (int)StencilUsage.IsUnlit;
stencilRefMV |= (int)StencilUsage.IsUnlit;
}
if (excludeFromTUAndAA)
{
stencilRefDepth |= (int)StencilUsage.ExcludeFromTUAndAA;
stencilRef |= (int)StencilUsage.ExcludeFromTUAndAA;
stencilWriteMask |= (int)StencilUsage.ExcludeFromTUAndAA;
stencilWriteMaskDepth |= (int)StencilUsage.ExcludeFromTUAndAA;
}
stencilWriteMaskDepth |= (int)StencilUsage.IsUnlit;
stencilWriteMaskGBuffer |= (int)StencilUsage.IsUnlit;
stencilWriteMaskMV |= (int)StencilUsage.IsUnlit;
}
public static void SetupProperties(Material material)
{
var surfaceType = (SurfaceType)material.GetInteger(SurfaceOptions.SURFACE_TYPE);
var cullMode = (CullMode)material.GetInteger(SurfaceOptions.CULL_MODE);
// Surface type
var isTransparent = surfaceType == SurfaceType.Transparent;
var isAlphaClip = material.GetInteger(SurfaceOptions.ALPHA_CLIP_ENABLE) == 1;
var renderQueue = isTransparent ? RenderPriority.Transparent : (isAlphaClip ? RenderPriority.OpaqueAlphaTest : RenderPriority.Opaque);
material.SetInteger(InternalProperties.SURFACE_TYPE, isTransparent ? 1 : 0);
material.renderQueue = (int)renderQueue;
// We only do clip for alpha clip in depth pre-pass once. Z test for GBuffer and forward pass need to set to equal to make sure alpha clip works correctly.
if (isAlphaClip)
{
material.SetInteger(InternalProperties.ZTEST_GBUFFER, (int)CompareFunction.Equal);
}
else
{
material.SetInteger(InternalProperties.ZTEST_GBUFFER, (int)CompareFunction.LessEqual);
}
if (isTransparent)
{
material.SetInteger(InternalProperties.ZTEST_DEPTH_EQUAL_FOR_OPAQUE, material.GetInteger(InternalProperties.ZTEST_TRANSPARENT));
material.SetOverrideTag("RenderType", "Transparent");
// TODO: Z write for transparent.
material.SetInteger(InternalProperties.ZWRITE, material.GetInteger(SurfaceOptions.TRANSPARENT_Z_WRITE));
material.SetInteger(InternalProperties.DEST_BLEND2, (int)BlendMode.OneMinusSrcAlpha);
//TODO: Implement additive and pre-multiply mode.
material.SetInteger(InternalProperties.SRC_BLEND, (int)BlendMode.One);
material.SetInteger(InternalProperties.DEST_BLEND, (int)BlendMode.OneMinusSrcAlpha);
material.SetInteger(InternalProperties.ALPHA_SRC_BLEND, (int)BlendMode.One);
material.SetInteger(InternalProperties.ALPHA_DEST_BLEND, (int)BlendMode.OneMinusSrcAlpha);
}
else
{
material.SetInteger(InternalProperties.ZTEST_DEPTH_EQUAL_FOR_OPAQUE, (int)CompareFunction.Equal);
material.SetOverrideTag("RenderType", isAlphaClip ? "TransparentCutout" : "");
material.SetInteger(InternalProperties.SRC_BLEND, (int)BlendMode.One);
material.SetInteger(InternalProperties.DEST_BLEND, (int)BlendMode.Zero);
material.SetInteger(InternalProperties.DEST_BLEND2, (int)BlendMode.Zero);
// Caution: we need to setup One for src and Zero for Dst for all element as users could switch from transparent to Opaque and keep remaining value.
// Unity will disable Blending based on these default value.
// Note that for after postprocess we setup 0 in opacity inside the shaders, so we correctly end with 0 in opacity for the compositing pass
material.SetInteger(InternalProperties.ALPHA_SRC_BLEND, (int)BlendMode.One);
material.SetInteger(InternalProperties.ALPHA_DEST_BLEND, (int)BlendMode.Zero);
material.SetInteger(InternalProperties.ZWRITE, 1);
}
// Double sided
var isBackFaceEnable = material.GetInteger(InternalProperties.TRANSPARENT_BACKFACE_ENABLE) == 1 && surfaceType == SurfaceType.Transparent;
var doubleSidedEnable = cullMode == CullMode.Off;
if (doubleSidedEnable)
{
var doubleSidedNormalMode = (DoubleSidedMode)material.GetInteger(SurfaceOptions.DOUBLE_SIDED_NORMAL_MODE);
switch (doubleSidedNormalMode)
{
case DoubleSidedMode.None:
material.SetVector(InternalProperties.DOUBLE_SIDED_CONSTANTS, new Vector4(1.0f, 1.0f, 1.0f, 0.0f));
break;
case DoubleSidedMode.Mirror:
material.SetVector(InternalProperties.DOUBLE_SIDED_CONSTANTS, new Vector4(1.0f, 1.0f, -1.0f, 0.0f));
break;
case DoubleSidedMode.Flip:
material.SetVector(InternalProperties.DOUBLE_SIDED_CONSTANTS, new Vector4(-1.0f, -1.0f, -1.0f, 0.0f));
break;
}
}
if (isBackFaceEnable)
{
material.SetInteger(InternalProperties.CULL_MODE_FORWARD, (int)CullMode.Back);
}
else
{
material.SetInteger(InternalProperties.CULL_MODE_FORWARD, (int)(doubleSidedEnable ? CullMode.Off : cullMode));
}
// Stencil
ComputeStencilProperties(true, true, true, false, false, false,
out var stencilRef, out var stencilWriteMask, out var stencilRefDepth, out var stencilWriteMaskDepth,
out var stencilRefGBuffer, out var stencilWriteMaskGBuffer, out var stencilRefMV, out var stencilWriteMaskMV);
material.SetInteger(InternalProperties.STENCIL_REF, stencilRef);
material.SetInteger(InternalProperties.STENCIL_WRITE_MASK, stencilWriteMask);
material.SetInteger(InternalProperties.STENCIL_REF_DEPTH, stencilRefDepth);
material.SetInteger(InternalProperties.STENCIL_WRITE_MASK_DEPTH, stencilWriteMaskDepth);
material.SetInteger(InternalProperties.STENCIL_REF_G_BUFFER, stencilRefGBuffer);
material.SetInteger(InternalProperties.STENCIL_WRITE_MASK_G_BUFFER, stencilWriteMaskGBuffer);
material.SetInteger(InternalProperties.STENCIL_REF_DISTORTION_VEC, (int)StencilUsage.DistortionVectors);
material.SetInteger(InternalProperties.STENCIL_WRITE_MASK_DISTORTION_VEC, (int)StencilUsage.DistortionVectors);
material.SetInteger(InternalProperties.STENCIL_REF_MV, stencilRefMV);
material.SetInteger(InternalProperties.STENCIL_WRITE_MASK_MV, stencilWriteMaskMV);
}
}
}

2
Runtime/UTSAPI.cs.meta Normal file
View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 83d6adf7383074c4594ff9eb19d44286

View File

@@ -1,6 +1,6 @@
{ {
"name": "com.misaki.hdrp-toon", "name": "com.misaki.hdrp-toon",
"version": "3.0.1-pre", "version": "3.0.2",
"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", "changelogUrl": "https://git.personalnas.com/Misaki/hdrp-toon/src/branch/develop/CHANGELOG.md",
@@ -21,6 +21,6 @@
}, },
"dependencies": { "dependencies": {
"com.unity.render-pipelines.high-definition": "17.0.0", "com.unity.render-pipelines.high-definition": "17.0.0",
"com.misaki.shader-gui": "1.1.4" "com.misaki.shader-gui": "1.1.5"
} }
} }