17 Commits

Author SHA1 Message Date
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
35dc7b15a6 Added new fabirc pbr mode;
Added new stocking surface feature;

Fixed the issue that diffuse bsdf is not energy conserving.
Fixed the bug that shader can not render alpha clip properly;
2025-05-15 16:07:54 +09:00
d19322b768 Fixed the engergy conservation problem when pbr mode is toon. 2025-05-13 21:35:52 +09:00
961db806e9 Added hair blending support. 2025-05-06 23:39:49 +09:00
10331b93ff Added new ramp diffuse ambient mode. 2025-05-06 00:01:08 +09:00
abdf6196ed Fixed the bug that alpha clip does not working properly; 2025-03-24 21:41:58 +09:00
53 changed files with 1554 additions and 716 deletions

View File

@@ -0,0 +1,29 @@
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: Install dependencies
run: npm install
- 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);
EditorGUI.indentLevel--;
}
material.SetShaderPassEnabled(UtsShaderPassName.HAIR_BLENDING_TARGET_PASS_NAME, isHairBlendingTargetEnabled);
material.SetShaderPassEnabled(UTSPassName.HAIR_BLENDING_TARGET_PASS_NAME, isHairBlendingTargetEnabled);
SwitchKeyword(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)
{
@@ -2347,18 +2347,18 @@ namespace UnityEditor.Rendering.Toon
internal static void SetupOverDrawTransparentObject(Material material)
{
var srpDefaultLightModeTag = material.GetTag("LightMode", false, UtsShaderPassName.OUTLINE_PASS_NAME);
if (srpDefaultLightModeTag == UtsShaderPassName.OUTLINE_PASS_NAME)
var srpDefaultLightModeTag = material.GetTag("LightMode", false, UTSPassName.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, srpDefaultCullMode, (int)CullingMode.Backface);
}
}
internal static void SetupOutline(Material material)
{
var srpDefaultLightModeTag = material.GetTag("LightMode", false, UtsShaderPassName.OUTLINE_PASS_NAME);
if (srpDefaultLightModeTag == UtsShaderPassName.OUTLINE_PASS_NAME)
var srpDefaultLightModeTag = material.GetTag("LightMode", false, UTSPassName.OUTLINE_PASS_NAME);
if (srpDefaultLightModeTag == UTSPassName.OUTLINE_PASS_NAME)
{
MaterialSetInt(material, srpDefaultColorMask, 15);
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);
var srpDefaultLightModeTag = material.GetTag("LightMode", false, UtsShaderPassName.OUTLINE_PASS_NAME);
var srpDefaultLightModeTag = material.GetTag("LightMode", false, UTSPassName.OUTLINE_PASS_NAME);
var isOutlineEnabled = true;
if (srpDefaultLightModeTag == UtsShaderPassName.OUTLINE_PASS_NAME)
if (srpDefaultLightModeTag == UTSPassName.OUTLINE_PASS_NAME)
{
const string kOutline = "Outline";
isOutlineEnabled = material.GetShaderPassEnabled(UtsShaderPassName.OUTLINE_PASS_NAME);
isOutlineEnabled = material.GetShaderPassEnabled(UTSPassName.OUTLINE_PASS_NAME);
EditorGUI.BeginChangeCheck();
isOutlineEnabled = EditorGUILayout.Toggle(kOutline, isOutlineEnabled);
@@ -2382,11 +2382,11 @@ namespace UnityEditor.Rendering.Toon
m_MaterialEditor.RegisterPropertyChangeUndo(kOutline);
if (isOutlineEnabled)
{
material.SetShaderPassEnabled(UtsShaderPassName.OUTLINE_PASS_NAME, true);
material.SetShaderPassEnabled(UTSPassName.OUTLINE_PASS_NAME, true);
}
else
{
material.SetShaderPassEnabled(UtsShaderPassName.OUTLINE_PASS_NAME, false);
material.SetShaderPassEnabled(UTSPassName.OUTLINE_PASS_NAME, false);
}
}
}

View File

@@ -1,6 +1,6 @@
using UnityEngine;
using static Misaki.HdrpToon.UtsShaderPropertyName;
using static Misaki.HdrpToon.UTSPropertyName;
namespace Misaki.HdrpToon.Editor
{
@@ -26,6 +26,16 @@ namespace Misaki.HdrpToon.Editor
return (PBRMode)material.GetInteger(SurfaceOptions.PBR_MODE);
}
public static MaterialType GetMaterialType(this Material material)
{
if (!material.HasProperty(SurfaceOptions.MATERIAL_TYPE))
{
return MaterialType.Standard;
}
return (MaterialType)material.GetInteger(SurfaceOptions.MATERIAL_TYPE);
}
public static bool HasFeature(this Material material, SurfaceFeature feature)
{
if (!material.HasProperty(SurfaceOptions.SURFACE_FEATURE))
@@ -36,5 +46,10 @@ namespace Misaki.HdrpToon.Editor
var value = (SurfaceFeature)material.GetInteger(SurfaceOptions.SURFACE_FEATURE);
return (value & feature) != 0;
}
public static bool IsHairBlendingTarget(this Material material)
{
return material.GetShaderPassEnabled(UTSPassName.HAIR_BLENDING_TARGET_PASS_NAME);
}
}
}

View File

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

View File

@@ -2,14 +2,16 @@ using Misaki.ShaderGUI;
using UnityEditor;
using UnityEngine;
using static Misaki.HdrpToon.UtsShaderPropertyName.Advance;
using static Misaki.HdrpToon.UTSPropertyName.Advance;
namespace Misaki.HdrpToon.Editor
{
public class AdvanceScope : MaterialUIScope<ShaderGUIExpandable>
internal class AdvanceScope : MaterialUIScope<ShaderGUIExpandable>
{
private static class Properties
{
public static MaterialProperty diffuseMin;
public static MaterialProperty lightIntensityMultiplier;
public static MaterialProperty clampLightColor;
@@ -18,6 +20,8 @@ namespace Misaki.HdrpToon.Editor
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 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.");
@@ -28,8 +32,10 @@ namespace Misaki.HdrpToon.Editor
protected override GUIContent Header => EditorGUIUtility.TrTextContent("Advance Settings");
public override void LoadMaterialProperties()
protected override void LoadMaterialProperties()
{
Properties.diffuseMin = FindProperty(MINIMAL_DIFFUSE_CONTRIBUTION);
Properties.lightIntensityMultiplier = FindProperty(LIGHT_INTENSITY_MULTIPLIER);
Properties.clampLightColor = FindProperty(CLAMP_LIGHT_COLOR);
@@ -38,6 +44,8 @@ namespace Misaki.HdrpToon.Editor
protected override void DrawContent()
{
editor.ShaderProperty(Properties.diffuseMin, Styles.diffuseMinText);
editor.ShaderProperty(Properties.lightIntensityMultiplier, Styles.lightIntensityMultiplierText);
editor.ShaderProperty(Properties.clampLightColor, Styles.clampLightColorText);

View File

@@ -4,7 +4,7 @@ using UnityEngine;
namespace Misaki.HdrpToon.Editor
{
public class AmbientScope : MaterialUIScope<ShaderGUIExpandable>
internal class AmbientScope : MaterialUIScope<ShaderGUIExpandable>
{
protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.Ambient;
protected override GUIContent Header => new("Ambient Settings");
@@ -17,6 +17,10 @@ namespace Misaki.HdrpToon.Editor
public static MaterialProperty indirectDiffuseMatCapMap;
public static MaterialProperty indirectDiffuseMatCapLod;
public static MaterialProperty indirectDiffuseRampMap;
public static MaterialProperty indirectDiffuseRampIndex;
public static MaterialProperty indirectDiffuseRampPosition;
public static MaterialProperty indirectDiffuseIntensity;
public static MaterialProperty ssaoWeight;
public static MaterialProperty ssgiWeight;
@@ -35,6 +39,9 @@ namespace Misaki.HdrpToon.Editor
public static readonly GUIContent indirectDiffuseMatCapMapText = new("MatCap Map", "The material capture map for indirect diffuse evaluation, with the additional setting for controlling the LOD offset when sampling the indirect diffuse material capture map.");
public static readonly GUIContent indirectDiffuseRampMapText = new("Ramp Map", "The ramp map for indirect diffuse evaluation, with the additional setting for controlling the sampling index of the ramp map.");
public static readonly GUIContent indirectDiffuseRampPositionText = new("Ramp Position", "The ramp position for indirect diffuse evaluation.");
public static readonly GUIContent indirectDiffuseIntensityText = new("Intensity", "The indirect diffuse color is added to the material color according to the intensity value.");
public static readonly GUIContent ssaoWeightText = new("SSAO Weight", "The weight of SSAO.");
public static readonly GUIContent ssgiWeightText = new("SSGI Weight", "The weight of SSGI.");
@@ -45,7 +52,7 @@ namespace Misaki.HdrpToon.Editor
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.indirectSpecularMode = FindProperty("_Indirect_Specular_Mode");
@@ -53,6 +60,10 @@ namespace Misaki.HdrpToon.Editor
Properties.indirectDiffuseMatCapMap = FindProperty("_IndirectDiffuseMatCapMap");
Properties.indirectDiffuseMatCapLod = FindProperty("_IndirectDiffuseMatCapLod");
Properties.indirectDiffuseRampMap = FindProperty("_IndirectDiffuseRampMap");
Properties.indirectDiffuseRampIndex = FindProperty("_IndirectDiffuseRampIndex");
Properties.indirectDiffuseRampPosition = FindProperty("_IndirectDiffuseRampPosition");
Properties.indirectDiffuseIntensity = FindProperty("_IndirectDiffuseIntensity");
Properties.ssaoWeight = FindProperty("_SSAOWeight");
Properties.ssgiWeight = FindProperty("_SSGIWeight");
@@ -64,6 +75,34 @@ namespace Misaki.HdrpToon.Editor
Properties.ssrWeight = FindProperty("_SSRWeight");
}
private static void DrawIndirectDiffuseHeader()
{
EditorGUILayout.Space();
using var indentLevelScope = new EditorGUI.IndentLevelScope(-1);
EditorGUILayout.LabelField("Indirect Diffuse", EditorStyles.boldLabel);
}
private void DrawIndirectDiffuseProperties()
{
EditorGUILayout.Space();
editor.ShaderProperty(Properties.indirectDiffuseIntensity, Styles.indirectDiffuseIntensityText);
editor.ShaderProperty(Properties.ssaoWeight, Styles.ssaoWeightText);
}
private void DrawIndirectSpecularProperties()
{
EditorGUILayout.Space();
editor.ShaderProperty(Properties.indirectReflectionIntensity, Styles.indirectReflectionIntensityText);
editor.ShaderProperty(Properties.ssrWeight, Styles.ssrWeightText);
}
private static void DrawIndirectSpecularHeader()
{
EditorGUILayout.Space();
using var indentLevelScope = new EditorGUI.IndentLevelScope(-1);
EditorGUILayout.LabelField("Indirect Specular", EditorStyles.boldLabel);
}
protected override void DrawContent()
{
editor.ShaderProperty(Properties.indirectDiffuseMode, Styles.indirectDiffuseModeText);
@@ -74,41 +113,43 @@ namespace Misaki.HdrpToon.Editor
if (indirectDiffuseMode != IndirectDiffuseMode.Off)
{
EditorGUILayout.Space();
using (var indentLevelScope = new EditorGUI.IndentLevelScope(-1))
DrawIndirectDiffuseHeader();
switch (indirectDiffuseMode)
{
EditorGUILayout.LabelField("Indirect Diffuse", EditorStyles.boldLabel);
case IndirectDiffuseMode.IBL:
editor.ShaderProperty(Properties.ssgiWeight, Styles.ssgiWeightText);
break;
case IndirectDiffuseMode.Matcap:
editor.TexturePropertySingleLine(Styles.indirectDiffuseMatCapMapText, Properties.indirectDiffuseMatCapMap, Properties.indirectDiffuseMatCapLod);
break;
case IndirectDiffuseMode.Ramp:
editor.TexturePropertySingleLine(Styles.indirectDiffuseRampMapText, Properties.indirectDiffuseRampMap, Properties.indirectDiffuseRampIndex);
editor.ShaderProperty(Properties.indirectDiffuseRampPosition, Styles.indirectDiffuseRampPositionText);
break;
default:
break;
}
if (indirectDiffuseMode == IndirectDiffuseMode.Matcap)
{
editor.TexturePropertySingleLine(Styles.indirectDiffuseMatCapMapText, Properties.indirectDiffuseMatCapMap, Properties.indirectDiffuseMatCapLod);
}
editor.ShaderProperty(Properties.indirectDiffuseIntensity, Styles.indirectDiffuseIntensityText);
editor.ShaderProperty(Properties.ssaoWeight, Styles.ssaoWeightText);
if (indirectDiffuseMode == IndirectDiffuseMode.IBL)
{
editor.ShaderProperty(Properties.ssgiWeight, Styles.ssgiWeightText);
}
DrawIndirectDiffuseProperties();
}
if (indirectSpecularMode != (int)IndirectSpecularMode.Off)
if (indirectSpecularMode != IndirectSpecularMode.Off)
{
EditorGUILayout.Space();
using (var indentLevelScope = new EditorGUI.IndentLevelScope(-1))
DrawIndirectSpecularHeader();
switch (indirectSpecularMode)
{
EditorGUILayout.LabelField("Indirect Specular", EditorStyles.boldLabel);
case IndirectSpecularMode.IBL:
break;
case IndirectSpecularMode.Matcap:
editor.TexturePropertySingleLine(Styles.indirectSpecularMatCapMapText, Properties.indirectSpecularMatCapMap, Properties.indirectSpecularMatCapLod);
break;
default:
break;
}
if (indirectSpecularMode == IndirectSpecularMode.Matcap)
{
editor.TexturePropertySingleLine(Styles.indirectSpecularMatCapMapText, Properties.indirectSpecularMatCapMap, Properties.indirectSpecularMatCapLod);
}
editor.ShaderProperty(Properties.indirectReflectionIntensity, Styles.indirectReflectionIntensityText);
editor.ShaderProperty(Properties.ssrWeight, Styles.ssrWeightText);
DrawIndirectSpecularProperties();
}
}
}

View File

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

View File

@@ -1,8 +1,10 @@
using Misaki.ShaderGUI;
using System.Linq;
using UnityEditor;
using UnityEngine;
using static Misaki.HdrpToon.UtsShaderPropertyName.Outline;
using static Misaki.HdrpToon.UTSPropertyName.Outline;
using static UnityEditor.EditorGUI;
namespace Misaki.HdrpToon.Editor
{
@@ -46,7 +48,7 @@ namespace Misaki.HdrpToon.Editor
protected override GUIContent Header => EditorGUIUtility.TrTextContent("Outline Settings");
public override void LoadMaterialProperties()
protected override void LoadMaterialProperties()
{
Properties.outlineState = FindProperty(OUTLINE_STATE);
@@ -71,6 +73,14 @@ namespace Misaki.HdrpToon.Editor
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();
editor.TexturePropertySingleLine(Styles.outlineWidthText, Properties.outlineWidthMap, Properties.outlineWidth);
editor.TexturePropertySingleLine(Styles.outlineColorText, Properties.outlineColorMap, Properties.outlineColor);

View File

@@ -3,17 +3,18 @@ using System.Linq;
using UnityEditor;
using UnityEngine;
using static Misaki.HdrpToon.UtsShaderPropertyName.RimLight;
using static Misaki.HdrpToon.UTSPropertyName.RimLight;
namespace Misaki.HdrpToon.Editor
{
public class RimLightScope : MaterialUIScope<ShaderGUIExpandable>
internal class RimLightScope : MaterialUIScope<ShaderGUIExpandable>
{
private static class Properties
{
public static MaterialProperty rimLightColor;
public static MaterialProperty rimLightIntensity;
public static MaterialProperty albedoAffectRimLight;
public static MaterialProperty screenSpaceRimLight;
public static MaterialProperty rimLightLevel;
public static MaterialProperty rimLightClipping;
@@ -28,6 +29,7 @@ namespace Misaki.HdrpToon.Editor
public static readonly GUIContent rimLightColorText = new("Rim Light Color", "Specifies the color of rim light.");
public static readonly GUIContent rimLightIntensityText = new("Rim Light Strength", "Specifies Rim Light strength.");
public static readonly GUIContent albedoAffectRimLightText = new("Albedo Affect Rim Light", "Enable to let the albedo color affect the rim light color. The alpha channel of rim light color will be the blending weight.");
public static readonly GUIContent screenSpaceRimLightText = new("Screen Space Rim Light", "Enable to make the rim light width constant in screen space.");
public static readonly GUIContent rimLightLevelText = new("Rim Light Level", "Specifies Rim Light power intensity.");
public static readonly GUIContent rimLightClippingText = new("Rim Light Clipping", "Enable to Clip the rim light at specific level");
@@ -41,11 +43,12 @@ namespace Misaki.HdrpToon.Editor
protected override GUIContent Header => EditorGUIUtility.TrTextContent("Rim Light Settings");
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.rimLightIntensity = FindProperty(RIM_LIGHT_INTENSITY);
Properties.albedoAffectRimLight = FindProperty(ALBEDO_AFFECT_RIM_LIGHT);
Properties.screenSpaceRimLight = FindProperty(SCREEN_SPACE_RIM_LIGHT);
Properties.rimLightLevel = FindProperty(RIM_LIGHT_LEVEL);
Properties.rimLightClipping = FindProperty(RIM_LIGHT_CLIPPING);
@@ -60,6 +63,7 @@ namespace Misaki.HdrpToon.Editor
editor.ShaderProperty(Properties.rimLightColor, Styles.rimLightColorText);
editor.ShaderProperty(Properties.rimLightIntensity, Styles.rimLightIntensityText);
editor.ShaderProperty(Properties.albedoAffectRimLight, Styles.albedoAffectRimLightText);
editor.ShaderProperty(Properties.screenSpaceRimLight, Styles.screenSpaceRimLightText);
editor.ShaderProperty(Properties.rimLightLevel, Styles.rimLightLevelText);

View File

@@ -5,7 +5,7 @@ using UnityEngine;
namespace Misaki.HdrpToon.Editor
{
public class ShadingColorScope : MaterialUIScope<ShaderGUIExpandable>
internal class ShadingColorScope : MaterialUIScope<ShaderGUIExpandable>
{
private static class Properties
{
@@ -34,6 +34,8 @@ namespace Misaki.HdrpToon.Editor
public static MaterialProperty sdfShadowLevel;
public static MaterialProperty sdfSmoothLevel;
public static MaterialProperty sdfHighlightStrength;
public static MaterialProperty hairBlendingFactor;
}
private static class Styles
@@ -59,6 +61,8 @@ namespace Misaki.HdrpToon.Editor
public static readonly GUIContent shadingRampMaskMapText = new("Shading Ramp Mask Map", "A texture that contains the mask for the shading ramp map.");
public static readonly GUIContent sdfHighlightStrengthText = new("SDF Highlight Strength", "Control the strength of the highlight in the SDF shading map.");
public static readonly GUIContent hairBlendingFactorText = new("Hair Blending Factor", "The blending factor for hair shading.");
}
protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.ShadingColor;
@@ -81,7 +85,7 @@ namespace Misaki.HdrpToon.Editor
}
}
public override void LoadMaterialProperties()
protected override void LoadMaterialProperties()
{
Properties.shadingRampMapState = FindProperty("_Use_Shading_Ramp_Map");
@@ -108,6 +112,8 @@ namespace Misaki.HdrpToon.Editor
Properties.sdfShadowLevel = FindProperty("_SDFShadowLevel");
Properties.sdfSmoothLevel = FindProperty("_SDFShadowSmoothLevel");
Properties.sdfHighlightStrength = FindProperty("_SDFHighlightStrength");
Properties.hairBlendingFactor = FindProperty("_HairBlendingFactor");
}
protected override void DrawContent()
@@ -144,6 +150,12 @@ namespace Misaki.HdrpToon.Editor
editor.ShaderProperty(Properties.sdfHighlightStrength, Styles.sdfHighlightStrengthText);
}
if (materials.All(material => material.GetMaterialType() == MaterialType.FrontHair))
{
EditorGUILayout.Space();
editor.ShaderProperty(Properties.hairBlendingFactor, Styles.hairBlendingFactorText);
}
EditorGUILayout.Space();
editor.TextureScaleOffsetProperty(Properties.baseColorMap);
}

View File

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

View File

@@ -0,0 +1,52 @@
using Misaki.ShaderGUI;
using System.Linq;
using UnityEditor;
using UnityEngine;
using static Misaki.HdrpToon.UTSPropertyName.Stocking;
namespace Misaki.HdrpToon.Editor
{
internal class StockingScope : MaterialUIScope<ShaderGUIExpandable>
{
private static class Properties
{
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()
{
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

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 9e91add2c76ce49448b768421496d94d

View File

@@ -4,36 +4,38 @@ using UnityEditor;
using UnityEditor.Rendering;
using UnityEngine;
using static Misaki.HdrpToon.UtsShaderPropertyName.SurfaceInputs;
using static Misaki.HdrpToon.UTSPropertyName.SurfaceInputs;
namespace Misaki.HdrpToon.Editor
{
public class SurfaceInputsScope : MaterialUIScope<ShaderGUIExpandable>
internal class SurfaceInputsScope : MaterialUIScope<ShaderGUIExpandable>
{
private static class Properties
{
public static MaterialProperty NormalMap;
public static MaterialProperty NormalMapScale;
public static MaterialProperty normalMap;
public static MaterialProperty normalMapScale;
public static MaterialProperty MaskMap;
public static MaterialProperty Metallic;
public static MaterialProperty MetallicRemapMin;
public static MaterialProperty MetallicRemapMax;
public static MaterialProperty AORemapMin;
public static MaterialProperty AORemapMax;
public static MaterialProperty Smoothness;
public static MaterialProperty SmoothnessRemapMin;
public static MaterialProperty SmoothnessRemapMax;
public static MaterialProperty maskMap;
public static MaterialProperty metallic;
public static MaterialProperty metallicRemapMin;
public static MaterialProperty metallicRemapMax;
public static MaterialProperty aoRemapMin;
public static MaterialProperty aoRemapMax;
public static MaterialProperty smoothness;
public static MaterialProperty smoothnessRemapMin;
public static MaterialProperty smoothnessRemapMax;
public static MaterialProperty AnisotropyMap;
public static MaterialProperty Anisotropy;
public static MaterialProperty KKColor;
public static MaterialProperty BSDFContribution;
public static MaterialProperty anisotropyMap;
public static MaterialProperty anisotropy;
public static MaterialProperty kkColor;
public static MaterialProperty bsdfContribution;
public static MaterialProperty SpecularColorMap;
public static MaterialProperty SpecularColor;
public static MaterialProperty SpecularFeather;
public static MaterialProperty SpecularStep;
public static MaterialProperty specularColorMap;
public static MaterialProperty specularColor;
public static MaterialProperty specularFeather;
public static MaterialProperty specularStep;
public static MaterialProperty hairBlendingMap;
public static MaterialProperty emissiveColorLDR;
public static MaterialProperty emissiveColorMap;
@@ -45,21 +47,23 @@ namespace Misaki.HdrpToon.Editor
private static class Styles
{
public static readonly GUIContent NormalMapText = new("Normal Map", "A texture that dictates the bumpiness of the material.");
public static readonly GUIContent MaskMapText = new("Mask Map", "A texture that dictates the physical properties of the material. R channel for metallic, G channel for ambient occlusion, A channel for smoothness");
public static readonly GUIContent MetallicText = new("Metallic", "Specifies the metallic value of the material.");
public static readonly GUIContent MetallicRemap = new("Metallic Remap", "Remap the max and min value of metallic");
public static readonly GUIContent AORemap = new("AO Remap", "Remap the max and min value of ambient occlusion");
public static readonly GUIContent SmoothnessText = new("Smoothness", "Specifies the smoothness of the material.");
public static readonly GUIContent SmoothnessRemapText = new("Smoothness Remap", "Remap the max and min value of smoothness");
public static readonly GUIContent normalMapText = new("Normal Map", "A texture that dictates the bumpiness of the material.");
public static readonly GUIContent maskMapText = new("Mask Map", "A texture that dictates the physical properties of the material. R channel for metallic, G channel for ambient occlusion, A channel for smoothness");
public static readonly GUIContent metallicText = new("Metallic", "Specifies the metallic value of the material.");
public static readonly GUIContent metallicRemap = new("Metallic Remap", "Remap the max and min value of metallic");
public static readonly GUIContent aoRemap = new("AO Remap", "Remap the max and min value of ambient occlusion");
public static readonly GUIContent smoothnessText = new("Smoothness", "Specifies the smoothness of the material.");
public static readonly GUIContent smoothnessRemapText = new("Smoothness Remap", "Remap the max and min value of smoothness");
public static readonly GUIContent AnisotropyMapText = new("Anisotropy Map", "Specifies the anisotropy map of the material.");
public static readonly GUIContent anisotropyMapText = new("Anisotropy Map", "Specifies the anisotropy map of the material.");
public static readonly GUIContent KKColorText = new("KK specular Color", "Specifies the color of KK specular.");
public static readonly GUIContent BSDFContributionText = new("BSDF Contribution", "BSDF smoothness contribution, 1 means KK Hair smoothness will fully contribute bsdf calculation");
public static readonly GUIContent kkColorText = new("KK specular Color", "Specifies the color of KK specular.");
public static readonly GUIContent bsdfContributionText = new("BSDF Contribution", "BSDF smoothness contribution, 1 means KK Hair smoothness will fully contribute bsdf calculation");
public static readonly GUIContent SpecularColorMapText = new("Specular Color Map", "Specifies the specular color map of the material.");
public static readonly GUIContent SpecRemap = new("Specular Remap", "Feather and step value of Toon Specular");
public static readonly GUIContent specularColorMapText = new("Specular Color Map", "Specifies the specular color map of the material.");
public static readonly GUIContent specRemap = new("Specular Remap", "Feather and step value of Toon Specular");
public static readonly GUIContent hairBlenderMapText = new("Hair Blending Map", "Specifies the hair blending map of the material.");
public static readonly GUIContent emissiveColorText = new("Emissive Color", "The color and color map to set for emissive effect.");
public static readonly GUIContent albedoAffectEmissiveText = new("Albedo Affect Emissive", "Enable to affect emissive color with base color");
@@ -71,30 +75,32 @@ namespace Misaki.HdrpToon.Editor
protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.SurfaceInputs;
protected override GUIContent Header => new("Surface Inputs");
public override void LoadMaterialProperties()
protected override void LoadMaterialProperties()
{
Properties.NormalMap = FindProperty("_NormalMap");
Properties.NormalMapScale = FindProperty("_NormalScale");
Properties.normalMap = FindProperty("_NormalMap");
Properties.normalMapScale = FindProperty("_NormalScale");
Properties.MaskMap = FindProperty("_MaskMap");
Properties.Metallic = FindProperty("_Metallic");
Properties.MetallicRemapMin = FindProperty("_MetallicRemapMin");
Properties.MetallicRemapMax = FindProperty("_MetallicRemapMax");
Properties.AORemapMin = FindProperty("_AORemapMin");
Properties.AORemapMax = FindProperty("_AORemapMax");
Properties.SmoothnessRemapMin = FindProperty("_SmoothnessRemapMin");
Properties.SmoothnessRemapMax = FindProperty("_SmoothnessRemapMax");
Properties.Smoothness = FindProperty("_Smoothness");
Properties.maskMap = FindProperty("_MaskMap");
Properties.metallic = FindProperty("_Metallic");
Properties.metallicRemapMin = FindProperty("_MetallicRemapMin");
Properties.metallicRemapMax = FindProperty("_MetallicRemapMax");
Properties.aoRemapMin = FindProperty("_AORemapMin");
Properties.aoRemapMax = FindProperty("_AORemapMax");
Properties.smoothnessRemapMin = FindProperty("_SmoothnessRemapMin");
Properties.smoothnessRemapMax = FindProperty("_SmoothnessRemapMax");
Properties.smoothness = FindProperty("_Smoothness");
Properties.AnisotropyMap = FindProperty("_AnisotropyMap");
Properties.Anisotropy = FindProperty("_Anisotropy");
Properties.KKColor = FindProperty("_KKColor");
Properties.BSDFContribution = FindProperty("_BSDFContribution");
Properties.anisotropyMap = FindProperty("_AnisotropyMap");
Properties.anisotropy = FindProperty("_Anisotropy");
Properties.kkColor = FindProperty("_KKColor");
Properties.bsdfContribution = FindProperty("_BSDFContribution");
Properties.SpecularColorMap = FindProperty("_SpecularColorMap");
Properties.SpecularColor = FindProperty("_SpecularColor");
Properties.SpecularFeather = FindProperty("_ToonSpecularFeather");
Properties.SpecularStep = FindProperty("_ToonSpecularStep");
Properties.specularColorMap = FindProperty("_SpecularColorMap");
Properties.specularColor = FindProperty("_SpecularColor");
Properties.specularFeather = FindProperty("_ToonSpecularFeather");
Properties.specularStep = FindProperty("_ToonSpecularStep");
Properties.hairBlendingMap = FindProperty("_HairBlendingMap");
Properties.emissiveColorLDR = FindProperty(EMISSIVE_COLOR_LDR);
Properties.emissiveColorMap = FindProperty(EMISSIVE_COLOR_MAP);
@@ -106,46 +112,55 @@ namespace Misaki.HdrpToon.Editor
protected override void DrawContent()
{
editor.KeywordTexturePropertySingleLine(Styles.NormalMapText, Properties.NormalMap, Properties.NormalMapScale);
editor.KeywordTexturePropertySingleLine(Styles.normalMapText, Properties.normalMap, Properties.normalMapScale);
if (materials.All(mat => mat.GetPBRMode() != PBRMode.Off))
{
if (editor.KeywordTexturePropertySingleLine(Styles.MaskMapText, Properties.MaskMap))
if (editor.KeywordTexturePropertySingleLine(Styles.maskMapText, Properties.maskMap))
{
editor.MinMaxShaderProperty(Properties.MetallicRemapMin, Properties.MetallicRemapMax, 0, 1, Styles.MetallicRemap);
editor.MinMaxShaderProperty(Properties.AORemapMin, Properties.AORemapMax, 0, 1, Styles.AORemap);
editor.MinMaxShaderProperty(Properties.SmoothnessRemapMin, Properties.SmoothnessRemapMax, 0, 1, Styles.SmoothnessRemapText);
editor.MinMaxShaderProperty(Properties.metallicRemapMin, Properties.metallicRemapMax, 0, 1, Styles.metallicRemap);
editor.MinMaxShaderProperty(Properties.aoRemapMin, Properties.aoRemapMax, 0, 1, Styles.aoRemap);
editor.MinMaxShaderProperty(Properties.smoothnessRemapMin, Properties.smoothnessRemapMax, 0, 1, Styles.smoothnessRemapText);
}
else
{
if (materials.All(mat => mat.GetPBRMode() != PBRMode.KKHair))
if (materials.All(mat =>
{
editor.ShaderProperty(Properties.Metallic, Styles.MetallicText);
var pbrMode = mat.GetPBRMode();
return pbrMode != PBRMode.Hair && pbrMode != PBRMode.Toon;
}))
{
editor.ShaderProperty(Properties.metallic, Styles.metallicText);
}
editor.ShaderProperty(Properties.Smoothness, Styles.SmoothnessText);
editor.ShaderProperty(Properties.smoothness, Styles.smoothnessText);
}
}
if (materials.All(mat => mat.GetPBRMode() == PBRMode.Anisotropy || mat.GetPBRMode() == PBRMode.KKHair))
if (materials.All(mat => mat.GetPBRMode() == PBRMode.Anisotropy || mat.GetPBRMode() == PBRMode.Hair))
{
EditorGUILayout.Space();
editor.KeywordTexturePropertySingleLine(Styles.AnisotropyMapText, Properties.AnisotropyMap, Properties.Anisotropy);
if (materials.All(mat => mat.GetPBRMode() == PBRMode.KKHair))
editor.KeywordTexturePropertySingleLine(Styles.anisotropyMapText, Properties.anisotropyMap, Properties.anisotropy);
if (materials.All(mat => mat.GetPBRMode() == PBRMode.Hair))
{
editor.ShaderProperty(Properties.KKColor, Styles.KKColorText);
editor.ShaderProperty(Properties.BSDFContribution, Styles.BSDFContributionText);
editor.ShaderProperty(Properties.kkColor, Styles.kkColorText);
editor.ShaderProperty(Properties.bsdfContribution, Styles.bsdfContributionText);
}
EditorGUILayout.Space();
EditorGUILayout.LabelField("Anisotropy Map only ST");
editor.TextureScaleOffsetProperty(Properties.AnisotropyMap);
editor.TextureScaleOffsetProperty(Properties.anisotropyMap);
}
else if (materials.All(mat => mat.GetPBRMode() == PBRMode.Toon))
{
EditorGUILayout.Space();
editor.KeywordTexturePropertySingleLine(Styles.SpecularColorMapText, Properties.SpecularColorMap, Properties.SpecularColor);
editor.MinMaxShaderProperty(Properties.SpecularFeather, Properties.SpecularStep, 0, 1, Styles.SpecRemap);
editor.KeywordTexturePropertySingleLine(Styles.specularColorMapText, Properties.specularColorMap, Properties.specularColor);
editor.MinMaxShaderProperty(Properties.specularFeather, Properties.specularStep, 0, 1, Styles.specRemap);
}
if (materials.All(mat => mat.IsHairBlendingTarget()))
{
editor.TexturePropertySingleLine(Styles.hairBlenderMapText, Properties.hairBlendingMap);
}
EditorGUILayout.Space();

View File

@@ -2,18 +2,29 @@ using Misaki.ShaderGUI;
using UnityEditor;
using UnityEngine;
using static Misaki.HdrpToon.UTSPropertyName.SurfaceOptions;
namespace Misaki.HdrpToon.Editor
{
internal class SurfaceOptionsScope : MaterialUIScope<ShaderGUIExpandable>
{
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 alphaClip;
public static MaterialProperty cullMode;
public static MaterialProperty doubleSidedNormalMode;
public static MaterialProperty shadingMode;
public static MaterialProperty materialType;
public static MaterialProperty pbrMode;
@@ -24,12 +35,20 @@ namespace Misaki.HdrpToon.Editor
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 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 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 materialTypeText = new("Material Type", "Specifies the material type.");
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");
public override void LoadMaterialProperties()
protected override void LoadMaterialProperties()
{
Properties.transparentMode = FindProperty("_TransparentEnabled");
Properties.surfaceType = FindProperty(SURFACE_TYPE);
Properties.alphaClipEnable = FindProperty("_AlphaCutoffEnable");
Properties.alphaClip = FindProperty("_AlphaCutoff");
Properties.fogOnTransparent = FindProperty(FOG_ON_TRANSPARENT);
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.shadingMode = FindProperty("_Shading_Mode");
Properties.materialType = FindProperty("_Material_Type");
Properties.pbrMode = FindProperty("_PBR_Mode");
Properties.alphaClipEnable = FindProperty(ALPHA_CLIP_ENABLE);
Properties.alphaClip = FindProperty(ALPHA_CUTOFF);
Properties.cullMode = FindProperty(CULL_MODE);
Properties.doubleSidedNormalMode = FindProperty(DOUBLE_SIDED_NORMAL_MODE);
Properties.hairBlendingTarget = FindProperty("_HairBlendingTarget");
Properties.surfaceFeatures = FindProperty("_SurfaceFeatures");
Properties.shadingMode = FindProperty(SHADING_MODE);
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()
{
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);
if (Properties.alphaClipEnable.floatValue == 1.0f)
if (Properties.alphaClipEnable.GetBooleanValue())
{
EditorGUI.indentLevel++;
using var s = new EditorGUI.IndentLevelScope();
editor.ShaderProperty(Properties.alphaClip, Styles.alphaClipText);
EditorGUI.indentLevel--;
}
editor.ShaderProperty(Properties.cullMode, Styles.cullingModeText);
editor.ShaderProperty(Properties.shadingMode, Styles.shadingModeText);
EditorGUI.BeginChangeCheck();
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);
EditorGUI.BeginChangeCheck();
editor.ShaderProperty(Properties.hairBlendingTarget, Styles.hairBlendingTargetText);
if (EditorGUI.EndChangeCheck())
{
foreach (var material in materials)
{
material.SetShaderPassEnabled(UtsShaderPassName.HAIR_BLENDING_TARGET_PASS_NAME, Properties.hairBlendingTarget.floatValue == 1.0f);
}
}
editor.ShaderProperty(Properties.surfaceFeatures, Styles.surfaceFeaturesText);
}
}

View File

@@ -8,6 +8,13 @@ namespace Misaki.HdrpToon.Editor
{
private GUIStyle _headerStyle;
public override void ValidateMaterial(Material material)
{
UTSAPI.SetupPass(material);
UTSAPI.SetupKeywords(material);
UTSAPI.SetupProperties(material);
}
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
if (!initialized)
@@ -24,15 +31,19 @@ namespace Misaki.HdrpToon.Editor
private void OnInitialize(MaterialEditor materialEditor, MaterialProperty[] properties)
{
AddUIScope(new SurfaceOptionsScope());
AddUIScope(new ShadingColorScope());
AddUIScope(new ShadowScope());
AddUIScope(new SurfaceInputsScope());
AddUIScope(new AmbientScope());
AddUIScope(new RimLightScope());
AddUIScope(new AngelRingScope());
AddUIScope(new OutlineScope());
AddUIScope(new AdvanceScope());
AddUIScope<SurfaceOptionsScope>();
AddUIScope<ShadingColorScope>();
AddUIScope<ShadowScope>();
AddUIScope<SurfaceInputsScope>();
AddUIScope<AmbientScope>();
// Surface Features
AddUIScope<AngelRingScope>();
AddUIScope<RimLightScope>();
AddUIScope<StockingScope>();
AddUIScope<OutlineScope>();
AddUIScope<AdvanceScope>();
Initialize(materialEditor, properties);

View File

@@ -41,7 +41,7 @@ The HDRP Toon Shader is designed to provide a high-quality toon shading effect f
## Example
Here are some examples of the HDRP Toon Shader in action:
![preview-01.png](https://s2.loli.net/2024/12/26/zHdfSXho4csURyx.png)
![preview-01.png](https://i.postimg.cc/nV3fT2PR/Screenshot-2025-05-13-212926.png)
## Contributing

View File

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

View File

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

View File

@@ -0,0 +1,148 @@
namespace Misaki.HdrpToon
{
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 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 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 const string EMISSIVE_COLOR = "_EmissiveColor";
public const string EMISSIVE_COLOR_LDR = "_EmissiveColorLDR";
public const string EMISSIVE_COLOR_MAP = "_EmissiveColorMap";
public const string ALBEDO_AFFECT_EMISSIVE = "_AlbedoAffectEmissive";
public const string EMISSIVE_INTENSITY = "_EmissiveIntensity";
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 const string RIM_LIGHT_COLOR = "_RimLightColor";
public const string RIM_LIGHT_INTENSITY = "_RimLightIntensity";
public const string ALBEDO_AFFECT_RIM_LIGHT = "_AlbedoAffectRimLight";
public const string SCREEN_SPACE_RIM_LIGHT = "_Screen_Space_Rim_Light";
public const string RIM_LIGHT_LEVEL = "_RimLightLevel";
public const string LIGHT_BASE_RIM_LIGHT = "_Light_Base_Rim_Light";
public const string LIGHT_DIRECTION_RIM_LIGHT_LEVEL = "_LightDirectionRimLightLevel";
public const string COLOR_BLENDING_MODE = "_Is_BlendAddToRimColor";
public const string RIM_LIGHT_CLIPPING = "_RimLightClipping";
public const string RIM_LIGHT_CLIPPING_LEVEL = "_RimLightClippingLevel";
public const string LIGHT_DIRECTION = "_LightDirection_MaskOn";
public const string INVERTED_DIRECTION_RIM_LIGHT = "_Add_Antipodean_RimLight";
public const string INVERTED_RIM_LIGHT_COLOR = "_Ap_RimLightColor";
public const string INVERSED_RIM_LIGHT_LEVEL = "_Ap_RimLight_Power";
public const string INVERTED_RIM_LIGHT_FEATHER_OFF = "_Ap_RimLight_FeatherOff";
public const string RIM_LIGHT_MASK_MAP = "_Set_RimLightMask";
public const string RIM_LIGHT_MASK_LEVEL = "_Tweak_RimLightMaskLevel";
}
public static class Stocking
{
public const string STOCKING_FRESNEL_WIDTH = "_StockingFresnelWidth";
public const string STOCKING_SPARKLE_SPACING = "_StockingSparkleSpacing";
public const string STOCKING_SPARKLE_AMOUNT = "_StockingSparkleAmount";
public const string STOCKING_SPARKLE_SIZE = "_StockingSparkleSize";
public const string STOCKING_SPARKLE_INTENSITY = "_StockingSparkleIntensity";
}
public static class Outline
{
public const string OUTLINE_STATE = "_OutlineState";
public const string OUTLINE_WIDTH = "_OutlineWidth";
public const string OUTLINE_WIDTH_MAP = "_OutlineWidthMap";
public const string OUTLINE_COLOR = "_OutlineColor";
public const string OUTLINE_COLOR_MAP = "_OutlineColorMap";
public const string ALBEDO_AFFECT_OUTLINE = "_AlbedoAffectOutline";
public const string SKY_COLOR_AFFECT_OUTLINE = "_SkyColorAffectOutline";
public const string SKY_COLOR_INTENSITY = "_SkyColorIntensity";
public const string OUTLINE_FADE_IN = "_OutlineFadeIn";
public const string OUTLINE_FADE_OUT = "_OutlineFadeOut";
public const string USE_SMOOTHED_NORMAL = "_UseSmoothedNormal";
}
public static class Advance
{
public const string MINIMAL_DIFFUSE_CONTRIBUTION = "_Minimal_Diffuse_Contribution";
public const string LIGHT_INTENSITY_MULTIPLIER = "_LightIntensityMultiplier";
public const string CLAMP_LIGHT_COLOR = "_ClampLightColor";
public const string LIGHT_LOOP_MODE = "_Light_Loop_Mode";
}
}
}

View File

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

View File

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

View File

@@ -1,81 +0,0 @@
namespace Misaki.HdrpToon
{
internal static class UtsShaderPropertyName
{
public static class SurfaceOptions
{
public const string SHADING_MODE = "_Shading_Mode";
public const string PBR_MODE = "_PBR_Mode";
public const string SURFACE_FEATURE = "_SurfaceFeatures";
}
public static class SurfaceInputs
{
public const string EMISSIVE_COLOR = "_EmissiveColor";
public const string EMISSIVE_COLOR_LDR = "_EmissiveColorLDR";
public const string EMISSIVE_COLOR_MAP = "_EmissiveColorMap";
public const string ALBEDO_AFFECT_EMISSIVE = "_AlbedoAffectEmissive";
public const string EMISSIVE_INTENSITY = "_EmissiveIntensity";
public const string EMISSIVE_EXPOSURE_WEIGHT = "_EmissiveExposureWeight";
}
public static class RimLight
{
public const string RIM_LIGHT_COLOR = "_RimLightColor";
public const string RIM_LIGHT_INTENSITY = "_RimLightIntensity";
public const string RIM_LIGHT_LEVEL = "_RimLightLevel";
public const string SCREEN_SPACE_RIM_LIGHT = "_Screen_Space_Rim_Light";
public const string LIGHT_BASE_RIM_LIGHT = "_Light_Base_Rim_Light";
public const string LIGHT_DIRECTION_RIM_LIGHT_LEVEL = "_LightDirectionRimLightLevel";
public const string COLOR_BLENDING_MODE = "_Is_BlendAddToRimColor";
public const string RIM_LIGHT_CLIPPING = "_RimLightClipping";
public const string RIM_LIGHT_CLIPPING_LEVEL = "_RimLightClippingLevel";
public const string LIGHT_DIRECTION = "_LightDirection_MaskOn";
public const string INVERTED_DIRECTION_RIM_LIGHT = "_Add_Antipodean_RimLight";
public const string INVERTED_RIM_LIGHT_COLOR = "_Ap_RimLightColor";
public const string INVERSED_RIM_LIGHT_LEVEL = "_Ap_RimLight_Power";
public const string INVERTED_RIM_LIGHT_FEATHER_OFF = "_Ap_RimLight_FeatherOff";
public const string RIM_LIGHT_MASK_MAP = "_Set_RimLightMask";
public const string RIM_LIGHT_MASK_LEVEL = "_Tweak_RimLightMaskLevel";
}
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 Outline
{
public const string OUTLINE_STATE = "_OutlineState";
public const string OUTLINE_WIDTH = "_OutlineWidth";
public const string OUTLINE_WIDTH_MAP = "_OutlineWidthMap";
public const string OUTLINE_COLOR = "_OutlineColor";
public const string OUTLINE_COLOR_MAP = "_OutlineColorMap";
public const string ALBEDO_AFFECT_OUTLINE = "_AlbedoAffectOutline";
public const string SKY_COLOR_AFFECT_OUTLINE = "_SkyColorAffectOutline";
public const string SKY_COLOR_INTENSITY = "_SkyColorIntensity";
public const string OUTLINE_FADE_IN = "_OutlineFadeIn";
public const string OUTLINE_FADE_OUT = "_OutlineFadeOut";
public const string USE_SMOOTHED_NORMAL = "_UseSmoothedNormal";
}
public static class Advance
{
public const string LIGHT_INTENSITY_MULTIPLIER = "_LightIntensityMultiplier";
public const string CLAMP_LIGHT_COLOR = "_ClampLightColor";
public const string LIGHT_LOOP_MODE = "_Light_Loop_Mode";
}
}
}

View File

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

View File

@@ -1,9 +1,22 @@
namespace Misaki.HdrpToon
{
internal enum SurfaceType
{
Opaque,
Transparent
}
internal enum DoubleSidedMode
{
None,
Mirror,
Flip
}
internal enum ShadingMode
{
Standard,
SDF,
SDF
}
internal enum MaterialType
@@ -19,7 +32,8 @@ namespace Misaki.HdrpToon
Off,
Standard,
Anisotropy,
KKHair,
Hair,
Fabric,
Toon
}

View File

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

View File

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

View File

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

View File

@@ -2,67 +2,52 @@ Shader "HDRP/Toon"
{
Properties
{
//TODO: Use custom rendering data.
[ToggleUI] _UseShadowThreshold("_UseShadowThreshold", Float) = 0.0
[ToggleUI] _AlphaCutoffEnable("Alpha Cutoff Enable", Float) = 0.0
_AlphaCutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
//TODO: Write HDRP properties to UTS properties
[ToggleUI] _UseShadowThreshold("_UseShadowThreshold", Integer) = 0
_AlphaCutoffShadow("_AlphaCutoffShadow", 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
[ToggleUI] _TransparentDepthPrepassEnable("_TransparentDepthPrepassEnable", Float) = 0.0
[ToggleUI] _TransparentBackfaceEnable("_TransparentBackfaceEnable", Float) = 0.0
[ToggleUI] _TransparentDepthPostpassEnable("_TransparentDepthPostpassEnable", Float) = 0.0
_TransparentSortPriority("_TransparentSortPriority", Float) = 0
_TransparentSortPriority("_TransparentSortPriority", Integer) = 0
// Transparency
[Enum(None, 0, Box, 1, Sphere, 2, Thin, 3)]_RefractionModel("Refraction Model", Int) = 0
[Enum(Proxy, 1, HiZ, 2)]_SSRefractionProjectionModel("Refraction Projection Model", Int) = 1
[Enum(None, 0, Box, 1, Sphere, 2, Thin, 3)]_RefractionModel("Refraction Model", Integer) = 0
[Enum(Proxy, 1, HiZ, 2)]_SSRefractionProjectionModel("Refraction Projection Model", Integer) = 1
_Ior("Index Of Refraction", Range(1.0, 2.5)) = 1.0
_ThicknessMultiplier("Thickness Multiplier", Float) = 1.0
_TransmittanceColor("Transmittance Color", Color) = (1.0, 1.0, 1.0)
_TransmittanceColorMap("TransmittanceColorMap", 2D) = "white" {}
_ATDistance("Transmittance Absorption Distance", Float) = 1.0
[ToggleUI] _TransparentWritingMotionVec("_TransparentWritingMotionVec", Float) = 0.0
// Forward
[HideInInspector] _StencilRef("_StencilRef", Int) = 2 // StencilLightingUsage.RegularLighting
[HideInInspector] _StencilWriteMask("_StencilWriteMask", Int) = 3 // StencilMask.Lighting
[HideInInspector] _StencilRef("_StencilRef", Integer) = 0 // StencilUsage.Clear
[HideInInspector] _StencilWriteMask("_StencilWriteMask", Integer) = 3 // StencilUsage.RequiresDeferredLighting | StencilUsage.SubsurfaceScattering
// GBuffer
[HideInInspector] _StencilRefGBuffer("_StencilRefGBuffer", Int) = 2 // StencilLightingUsage.RegularLighting
[HideInInspector] _StencilWriteMaskGBuffer("_StencilWriteMaskGBuffer", Int) = 3 // StencilMask.Lighting
[HideInInspector] _StencilRefGBuffer("_StencilRefGBuffer", Integer) = 2 // StencilUsage.RequiresDeferredLighting
[HideInInspector] _StencilWriteMaskGBuffer("_StencilWriteMaskGBuffer", Integer) = 3 // StencilUsage.RequiresDeferredLighting | StencilUsage.SubsurfaceScattering
// Depth prepass
[HideInInspector] _StencilRefDepth("_StencilRefDepth", Int) = 0 // Nothing
[HideInInspector] _StencilWriteMaskDepth("_StencilWriteMaskDepth", Int) = 32 // DoesntReceiveSSR
[HideInInspector] _StencilRefDepth("_StencilRefDepth", Integer) = 0 // Nothing
[HideInInspector] _StencilWriteMaskDepth("_StencilWriteMaskDepth", Integer) = 8 // StencilUsage.TraceReflectionRay
// Motion vector pass
[HideInInspector] _StencilRefMV("_StencilRefMV", Int) = 128 // StencilBitMask.ObjectMotionVectors
[HideInInspector] _StencilWriteMaskMV("_StencilWriteMaskMV", Int) = 128 // StencilBitMask.ObjectMotionVectors
[HideInInspector] _StencilRefMV("_StencilRefMV", Integer) = 32 // StencilBitMask.ObjectMotionVectors
[HideInInspector] _StencilWriteMaskMV("_StencilWriteMaskMV", Integer) = 32 // StencilBitMask.ObjectMotionVectors
// Distortion vector pass
[HideInInspector] _StencilRefDistortionVec("_StencilRefDistortionVec", Int) = 64 // StencilBitMask.DistortionVectors
[HideInInspector] _StencilWriteMaskDistortionVec("_StencilWriteMaskDistortionVec", Int) = 64 // StencilBitMask.DistortionVectors
[HideInInspector] _StencilRefDistortionVec("_StencilRefDistortionVec", Integer) = 64 // StencilBitMask.DistortionVectors
[HideInInspector] _StencilWriteMaskDistortionVec("_StencilWriteMaskDistortionVec", Integer) = 64 // StencilBitMask.DistortionVectors
// Blending state
[HideInInspector] _SurfaceType("__surfacetype", Float) = 0.0
[HideInInspector] _BlendMode("__blendmode", Float) = 0.0
[HideInInspector] _SrcBlend("__src", Float) = 1.0
[HideInInspector] _DstBlend("__dst", Float) = 0.0
[HideInInspector] _AlphaSrcBlend("__alphaSrc", Float) = 1.0
[HideInInspector] _AlphaDstBlend("__alphaDst", Float) = 0.0
[HideInInspector][ToggleUI] _ZWrite("__zw", Float) = 1.0
[HideInInspector][ToggleUI] _TransparentZWrite("_TransparentZWrite", Float) = 0.0
//[Enum(Off, 0, Front, 1, Back, 2)] _CullMode("__cullmode", Float) = 2.0
[HideInInspector] _CullModeForward("__cullmodeForward", Float) = 2.0 // This mode is dedicated to Forward to correctly handle backface then front face rendering thin transparent
[HideInInspector] _TransparentCullMode("_TransparentCullMode", Int) = 2 // Back culling by default
[HideInInspector] _ZTestDepthEqualForOpaque("_ZTestDepthEqualForOpaque", Int) = 4 // Less equal
[HideInInspector] _ZTestModeDistortion("_ZTestModeDistortion", Int) = 8
[HideInInspector] _ZTestGBuffer("_ZTestGBuffer", Int) = 4
[HideInInspector] _ZTestMode("_ZTestMode", Int) = 4
[Enum(UnityEngine.Rendering.CompareFunction)] _ZTestTransparent("Transparent ZTest", Int) = 4 // Less equal
_BlendMode("__blendmode", Integer) = 0
[HideInInspector] _SrcBlend("__src", Integer) = 1
[HideInInspector] _DstBlend("__dst", Integer) = 0
[HideInInspector] _AlphaSrcBlend("__alphaSrc", Integer) = 1
[HideInInspector] _AlphaDstBlend("__alphaDst", Integer) = 0
[HideInInspector][ToggleUI] _ZWrite("__zw", Integer) = 1
[HideInInspector] _CullModeForward("__cullmodeForward", Integer) = 2.0 // This mode is dedicated to Forward to correctly handle backface then front face rendering thin transparent
[HideInInspector] _ZTestDepthEqualForOpaque("_ZTestDepthEqualForOpaque", Integer) = 4 // Less equal
[HideInInspector] _ZTestModeDistortion("_ZTestModeDistortion", Integer) = 8
[HideInInspector] _ZTestGBuffer("_ZTestGBuffer", Integer) = 4
[HideInInspector] _ZTestMode("_ZTestMode", Integer) = 4
[Enum(UnityEngine.Rendering.CompareFunction)] _ZTestTransparent("Transparent ZTest", Integer) = 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] _UVMappingMask("_UVMappingMask", Color) = (1, 0, 0, 0)
@@ -72,7 +57,6 @@ Shader "HDRP/Toon"
_Color("Color", Color) = (1,1,1,1)
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
@@ -85,13 +69,24 @@ Shader "HDRP/Toon"
//TODO: Move more properties here for better organization
// Surface Options
[Popup] _TransparentEnabled("Transparent Mode", Integer) = 0
[ToggleUI] _AlphaCutoffEnable("Alpha Cutoff Enable", Float) = 0.0
[Enum(Misaki.HdrpToon.SurfaceType)]_SurfaceType("__surfacetype", Integer) = 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
[Enum(Off, 0, Front, 1, Back, 2)] _CullMode("Cull Mode", Integer) = 2
[KeywordEnum(Standard, SDF)] _Shading_Mode("Shading mode", Integer) = 0
[KeywordEnum(Standard, FrontHair, Face, Eye)] _Material_Type("Material Type", Integer) = 0
[KeywordEnum(Off, Standard, Anisotropy, Hair, Toon)] _PBR_Mode("PBR Mode", Integer) = 0
[Enum(Misaki.HdrpToon.DoubleSidedMode)] _DoubleSidedNormalMode("Double sided normal mode", Integer) = 1
[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
[EnumFlagsUI(Misaki.HdrpToon.SurfaceFeature, Misaki.HdrpToon)]_SurfaceFeatures("Surface Features", Integer) = 0
@@ -123,13 +118,15 @@ Shader "HDRP/Toon"
_SDFShadowSmoothLevel("SDFShadowSmoothLevel", Range(0.0, 0.1)) = 0.02
_SDFHighlightStrength("SDFHighlightStrength", Range(0.0, 1.0)) = 0.75
_HairBlendingFactor("HairBlendingFactor", Range(0.0, 1.0)) = 0.5
// Shadow
[Popup] _Receive_Light_Shadow("Receive Light Shadow", Integer) = 0
[Popup] _Receive_Screen_Space_Shadow("Receive Screen Space Shadow", Integer) = 0
[Popup] _Receive_Hair_Shadow("Receive Hair Shadow", Integer) = 0
_ShadowDistanceBias("ShadowBias", Range(0.0, 5.0)) = 0.0
_ShadowNormalBias("ShadowNormalBias", Range(0.0, 5.0)) = 0.0
_ShadowNormalBias("ShadowNormalBias", Range(-5.0, 5.0)) = 0.0
//_Tweak_SystemShadowsLevel("Tweak_SystemShadowsLevel", Range(-0.5, 0.5)) = 0
// Surface Inputs
@@ -174,8 +171,8 @@ Shader "HDRP/Toon"
_EmissiveExposureWeight("Emissive Pre Exposure", Range(0.0, 1.0)) = 1.0
// Ambient
[KeywordEnum(Off, IBL, MatCap, Ramp)]_Indirect_Diffuse_Mode("_Indirect_Diffuse_Mode", Integer) = 1
[KeywordEnum(Off, IBL, MatCap)]_Indirect_Specular_Mode("_Indirect_Specular_Mode", Integer) = 1
[KeywordEnumType(Misaki.HdrpToon.IndirectDiffuseMode, Misaki.HdrpToon)] _Indirect_Diffuse_Mode("_Indirect_Diffuse_Mode", Integer) = 1
[KeywordEnumType(Misaki.HdrpToon.IndirectSpecularMode, Misaki.HdrpToon)] _Indirect_Specular_Mode("_Indirect_Specular_Mode", Integer) = 1
_IndirectDiffuseMatCapMap("IndirectDiffuseMatCapMap", 2D) = "black" {}
_IndirectDiffuseMatCapLod("IndirectDiffuseMatCapMapLOD", Range(-5, 5)) = 0.0
@@ -187,12 +184,24 @@ Shader "HDRP/Toon"
_IndirectSpecularMatCapMap("IndirectSpecularMatCapMap", 2D) = "black" {}
_IndirectSpecularMatCapLod("IndirectSpecularMatCapMapLOD", Range(-5, 5)) = 0.0
_IndirectDiffuseRampMap("_IndirectDiffuseRampMap", 2DArray) = "black" {}
_IndirectDiffuseRampIndex("IndirectDiffuseRampIndex", Integer) = 0
_IndirectDiffuseRampPosition("IndirectDiffuseRampPosition", Range(0, 1)) = 0.5
_IndirectSpecularIntensity("Indirect Specular Intensity", Range(0, 5)) = 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
_RimLightColor("Rim Light Color", Color) = (1, 1, 1, 1)
_RimLightIntensity("Rim Light Intensity", Range(0, 10)) = 1
[ToggleUI] _AlbedoAffectRimLight("Albedo Affect Rim Light", Integer) = 0
[Popup] _Screen_Space_Rim_Light ("Screen Space Rim Light", Integer) = 0
_RimLightLevel("RimLight Level", Range(0, 1)) = 0.1
[ToggleUI] _RimLightClipping("Rim Light Clipping", Float) = 0.25
@@ -214,12 +223,12 @@ Shader "HDRP/Toon"
_Set_RimLightMask("Set_RimLightMask", 2D) = "white" {}
_Tweak_RimLightMaskLevel("Tweak_RimLightMaskLevel", Range(-1, 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
// Stocking
_StockingFresnelWidth("Stocking Fresnel Width", Range(0, 10)) = 2.0
[PowerSlider(2.0)]_StockingSparkleSpacing("Stocking Sparking Spacing", Range(64.0, 1024.0)) = 128.0
_StockingSparkleAmount("Stocking Sparking Amount", Range(0, 2)) = 1.0
_StockingSparkleSize("Stocking Sparking Intensity", Range(0, 2)) = 0.5
_StockingSparkleIntensity("Stocking Sparking Intensity", Range(0, 10)) = 1.0
// Outline
[PassPopup(Outline)] _OutlineState("Outline State", Integer) = 1
@@ -229,16 +238,41 @@ Shader "HDRP/Toon"
_OutlineColorMap("Outline Color Map", 2D) = "white" {}
[ToggleUI] _AlbedoAffectOutline("Albedo 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
_OutlineFadeOut("Outline Fade Out", Float) = 100
[ToggleUI] _UseSmoothedNormal("Use Smoothed Normal", Float) = 0
// Advance
_LightIntensityMultiplier("Light_Intensity_Multiplier" , Range(0, 1)) = 0.5
_LightIntensityMultiplier("Light_Intensity_Multiplier" , Range(0, 3)) = 1
[ToggleUI] _ClampLightColor("VRChat : SceneLights HiCut_Filter", Float) = 0
_Minimal_Diffuse_Contribution("Minimal_Diffuse_Contribution", Range(0, 1)) = 0.05
[KeywordEnum(Single, Full, Custom)] _Light_Loop_Mode ("Light Loop Mode", Float) = 1
//TODO: Clear hdrp default properties
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3)] _UVDetail("UV Set for detail", Float) = 0
[HideInInspector] _UVDetailsMappingMask("_UVDetailsMappingMask", Color) = (1, 0, 0, 0)
[ToggleUI] _LinkDetailsWithBase("LinkDetailsWithBase", Float) = 1.0
[Enum(Use Emissive Color, 0, Use Emissive Mask, 1)] _EmissiveColorMode("Emissive color mode", Float) = 1
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5, Same as Base, 6)] _UVEmissive("UV Set for emissive", Float) = 0
[Enum(WorldSpace, 0, ObjectSpace, 1)] _ObjectSpaceUVMappingEmissive("Mapping space", Float) = 0.0
_TexWorldScaleEmissive("Scale to apply on world coordinate", Float) = 1.0
[HideInInspector] _UVMappingMaskEmissive("_UVMappingMaskEmissive", Color) = (1, 0, 0, 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] _DiffusionProfileHash("Diffusion Profile Hash", Float) = 0
}
HLSLINCLUDE
@@ -250,14 +284,8 @@ Shader "HDRP/Toon"
// Variant
//-------------------------------------------------------------------------------------
#pragma shader_feature_local _ALPHATEST_ON
#pragma shader_feature_local _DEPTHOFFSET_ON
#pragma multi_compile _ DOTS_INSTANCING_ON
#pragma shader_feature_local _DOUBLESIDED_ON
#pragma shader_feature_local _ _VERTEX_DISPLACEMENT _PIXEL_DISPLACEMENT
#pragma shader_feature_local _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
#pragma shader_feature_local _DISPLACEMENT_LOCK_TILING_SCALE
#pragma shader_feature_local _PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE
#pragma shader_feature_local _TESSELLATION_PHONG
#pragma shader_feature_local _NORMALMAP_TANGENT_SPACE
#pragma shader_feature_local _ _REQUIRE_UV2 _REQUIRE_UV3
@@ -327,6 +355,7 @@ Shader "HDRP/Toon"
HLSLPROGRAM
#pragma shader_feature_local _ALPHATEST_ON
// Note: Require _ObjectId and _PassValue variables
// We reuse depth prepass for the scene selection, allow to handle alpha correctly as well as tessellation and vertex animation
@@ -367,7 +396,6 @@ Shader "HDRP/Toon"
#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch
#pragma instancing_options renderinglayer
#pragma multi_compile _ DOTS_INSTANCING_ON
#pragma multi_compile _ DEBUG_DISPLAY
@@ -379,10 +407,13 @@ Shader "HDRP/Toon"
#pragma multi_compile DECALS_OFF DECALS_3RT DECALS_4RT
#pragma multi_compile _ LIGHT_LAYERS
#pragma shader_feature _SURFACE_TYPE_TRANSPARENT
#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 _NORMALMAP
#pragma shader_feature_local_fragment _ANISOTROPYMAP
#pragma shader_feature_local_fragment _SPECULARCOLORMAP
@@ -411,7 +442,7 @@ Shader "HDRP/Toon"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitSharePass.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitData.hlsl"
#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/ShaderPass/UtsShaderPassGBuffer.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassGBuffer.hlsl"
#pragma vertex Vert
#pragma fragment Frag
@@ -430,6 +461,16 @@ Shader "HDRP/Toon"
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 _SURFACE_TYPE_TRANSPARENT
#pragma shader_feature_local_fragment _ENABLE_FOG_ON_TRANSPARENT
// 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,
// both direct and indirect lighting) will hand up in the "regular" lightmap->LIGHTMAP_ON.
@@ -462,6 +503,8 @@ Shader "HDRP/Toon"
HLSLPROGRAM
#pragma shader_feature_local _ALPHATEST_ON
#define SHADERPASS SHADERPASS_SHADOWS
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl"
@@ -481,7 +524,7 @@ Shader "HDRP/Toon"
Tags{ "LightMode" = "DepthForwardOnly" }
Cull[_CullMode]
AlphaToMask [_AlphaCutoffEnable]
// To be able to tag stencil with disableSSR information for forward
Stencil
{
@@ -495,6 +538,12 @@ Shader "HDRP/Toon"
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
// In deferred, depth only pass don't output anything.
// In forward it output the normal buffer
#pragma multi_compile _ WRITE_NORMAL_BUFFER
@@ -534,13 +583,19 @@ Shader "HDRP/Toon"
}
Cull[_CullMode]
AlphaToMask [_AlphaCutoffEnable]
ZWrite On
HLSLPROGRAM
#pragma multi_compile _ WRITE_NORMAL_BUFFER
#pragma multi_compile _ WRITE_MSAA_DEPTH
#pragma shader_feature_local _ALPHATEST_ON
#pragma shader_feature _SURFACE_TYPE_TRANSPARENT
#define SHADERPASS SHADERPASS_MOTION_VECTORS
#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"
@@ -603,8 +658,22 @@ Shader "HDRP/Toon"
HLSLPROGRAM
#define SHADERPASS SHADERPASS_DEPTH_ONLY
#define CUTOFF_TRANSPARENT_DEPTH_PREPASS
#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 _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
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitDepthPass.hlsl"
@@ -630,6 +699,19 @@ Shader "HDRP/Toon"
ZTest [_ZTestTransparent]
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 _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 _ LIGHTMAP_ON
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
@@ -679,22 +761,28 @@ Shader "HDRP/Toon"
Name "ForwardOnly"
Tags { "LightMode" = "ForwardOnly" }
ZWrite [_ZWriteMode]
ZTest [_ZTestMode]
Cull [_CullMode]
Blend SrcAlpha OneMinusSrcAlpha
Stencil {
ZWrite [_ZWrite]
ZTest [_ZTestDepthEqualForOpaque]
Cull [_CullModeForward]
Ref[_StencilNo]
Comp[_StencilComp]
Pass[_StencilOpPass]
Fail[_StencilOpFail]
Blend [_SrcBlend] [_DstBlend], [_AlphaSrcBlend] [_AlphaDstBlend]
// ForwardOpaque | ForwardTransparent
Blend 1 One OneMinusSrcAlpha // VT feedback | VT feedback <- if VT is off, all targets below are shifted by 1
Blend 2 One [_DstBlend2] // diffuse lighting | motion vector
Blend 3 One [_DstBlend2] // SSS buffer | before refraction <- This target (or the one above if VT off) needs blending in transparent but not in opaque
Blend 4 One OneMinusSrcAlpha // | before refraction alpha
Stencil
{
WriteMask [_StencilWriteMask]
Ref [_StencilRef]
Comp Always
Pass Replace
}
HLSLPROGRAM
//#pragma multi_compile _ UTS_DEBUG_SHADOWMAP_BINALIZATION
#pragma multi_compile _ DEBUG_DISPLAY
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
@@ -705,26 +793,13 @@ Shader "HDRP/Toon"
#pragma multi_compile SCREEN_SPACE_SHADOWS_OFF SCREEN_SPACE_SHADOWS_ON
#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 DIRECTIONAL_SHADOW_LOW DIRECTIONAL_SHADOW_MEDIUM DIRECTIONAL_SHADOW_HIGH
//#pragma multi_compile_fragment AREA_SHADOW_MEDIUM AREA_SHADOW_HIGH
#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
// used in ShadingGradeMap
#pragma shader_feature _IS_TRANSCLIPPING_OFF _IS_TRANSCLIPPING_ON
#pragma shader_feature _IS_ANGELRING_OFF _IS_ANGELRING_ON
// used in Shadow calculation
#pragma shader_feature _ UTS_USE_RAYTRACING_SHADOW
// used in DoubleShadeWithFeather
#pragma shader_feature _IS_CLIPPING_OFF _IS_CLIPPING_MODE _IS_CLIPPING_TRANSMODE
// controlling mask rendering
#pragma shader_feature _ _IS_CLIPPING_MATTE
#pragma shader_feature _EMISSIVE_SIMPLE _EMISSIVE_ANIMATION
#pragma shader_feature ENABLE_UTS_HAIR_SHAOW
@@ -734,7 +809,7 @@ Shader "HDRP/Toon"
#pragma shader_feature_local_fragment _SHADING_MODE_STANDARD _SHADING_MODE_SDF
#pragma shader_feature_local_fragment _MATERIAL_TYPE_STANDARD _MATERIAL_TYPE_FRONTHAIR _MATERIAL_TYPE_FACE _MATERIAL_TYPE_EYE
#pragma shader_feature_local_fragment _PBR_MODE_OFF _PBR_MODE_STANDARD _PBR_MODE_ANISOTROPY _PBR_MODE_HAIR _PBR_MODE_TOON
#pragma shader_feature_local_fragment _PBR_MODE_OFF _PBR_MODE_STANDARD _PBR_MODE_ANISOTROPY _PBR_MODE_HAIR _PBR_MODE_FABRIC _PBR_MODE_TOON
#pragma shader_feature_local_fragment _USE_SHADING_RAMP_MAP_ON
@@ -750,15 +825,23 @@ Shader "HDRP/Toon"
#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 _NORMALMAP
#pragma shader_feature_local_fragment _ANISOTROPYMAP
#pragma shader_feature_local_fragment _SPECULARCOLORMAP
#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 _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 DIRECTIONAL_SHADOW_MEDIUM
#define AREA_SHADOW_MEDIUM
@@ -768,10 +851,15 @@ Shader "HDRP/Toon"
#define USE_FPTL_LIGHTLIST
#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/Lighting/Lighting.hlsl"
@@ -819,6 +907,10 @@ Shader "HDRP/Toon"
ColorMask 0
HLSLPROGRAM
#pragma shader_feature_local _ALPHATEST_ON
#pragma shader_feature _SURFACE_TYPE_TRANSPARENT
#define SHADERPASS SHADERPASS_DEPTH_ONLY
#define CUTOFF_TRANSPARENT_DEPTH_POSTPASS
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl"
@@ -866,11 +958,22 @@ Shader "HDRP/Toon"
Tags { "LightMode" = "Outline" }
Cull Front
Blend Off
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
#define AREA_SHADOW_LOW
#define SHADERPASS SHADERPASS_FORWARD
#define SHADOW_LOW
@@ -884,13 +987,6 @@ Shader "HDRP/Toon"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl"
#endif
// The light loop (or lighting architecture) is in charge to:
// - Define light list
// - Define the light loop
// - Setup the constant/data
// - Do the reflection hierarchy
// - Provide sampling function for shadowmap, ies, cookie and reflection (depends on the specific use with the light loops like index array or atlas or single and texture format (cubemap/latlong))
#define HAS_LIGHTLOOP
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoopDef.hlsl"
@@ -901,8 +997,6 @@ Shader "HDRP/Toon"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitSharePass.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitData.hlsl"
#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Common/UtsHead.hlsl"
#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/ShaderPass/HDRPToonOutline.hlsl"
@@ -928,6 +1022,9 @@ Shader "HDRP/Toon"
HLSLPROGRAM
#define SHADERPASS SHADERPASS_SHADOWS
#pragma shader_feature_local _ALPHATEST_ON
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitDepthPass.hlsl"
@@ -993,11 +1090,16 @@ Shader "HDRP/Toon"
#pragma multi_compile PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#define SHADERPASS SHADERPASS_RAYTRACING_INDIRECT
// multi compile that allows us to strip the recursive code
#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.
// 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
@@ -1045,6 +1147,11 @@ Shader "HDRP/Toon"
#pragma multi_compile PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2
#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
// If you need to change this, be sure to read this comment.
@@ -1095,6 +1202,11 @@ Shader "HDRP/Toon"
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#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
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingMacros.hlsl"
@@ -1126,6 +1238,11 @@ Shader "HDRP/Toon"
#pragma only_renderers d3d11 ps5
#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
#pragma multi_compile _ TRANSPARENT_COLOR_SHADOW
@@ -1157,6 +1274,11 @@ Shader "HDRP/Toon"
#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
// This is just because it needs to be defined, shadow maps are not used.

View File

@@ -50,6 +50,56 @@ float3 UtsComputeDiffuseColor(float3 baseColor, float metallic)
return UtsComputeDiffuseColor(baseColor, metallic, 0.0);
}
float Random(float2 uv)
{
return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453);
}
inline float2 voronoi_noise_random_vector (float2 UV, float offset)
{
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 Voronoi(float2 UV, float AngleOffset, float CellDensity)
{
float2 g = floor(UV * CellDensity);
float2 f = frac(UV * CellDensity);
float t = 8.0;
float res = 8.0;
for(int y=-1; y<=1; y++)
{
for(int x=-1; x<=1; x++)
{
float2 lattice = float2(x,y);
float2 offset = voronoi_noise_random_vector(lattice + g, AngleOffset);
float d = distance(lattice + offset, f);
if(d < res)
{
res = d;
}
}
}
return res;
}
float Dither(float In, float4 positionSS)
{
float2 uv = positionSS.xy;
float DITHER_THRESHOLDS[16] =
{
1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0,
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,
16.0 / 17.0, 8.0 / 17.0, 14.0 / 17.0, 6.0 / 17.0
};
uint index = (uint(uv.x) % 4) * 4 + uint(uv.y) % 4;
return In - DITHER_THRESHOLDS[index];
}
#define SampleRampSignalLine(texture, u) (SAMPLE_TEXTURE2D_LOD(texture, s_linear_clamp_sampler, float2(u, 0.5), 0))
// Exposure

View File

@@ -74,6 +74,24 @@ struct UtsBSDFData
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 output;
@@ -124,11 +142,11 @@ UTSSurfaceData GetUTSSurfaceData(FragInputs input, float3 V)
float4 normalLocal = float4(0, 0, 1.0, 1.0);
#if _NORMALMAP
if (_Use_SSSLut)
{
normalLocal = SAMPLE_TEXTURE2D_LOD(_NormalMap, sampler_NormalMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap), _SSSIntensity);
}
else
// if (_Use_SSSLut)
// {
// normalLocal = SAMPLE_TEXTURE2D_LOD(_NormalMap, sampler_NormalMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap), _SSSIntensity);
// }
// else
{
normalLocal = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap));
normalLocal.rgb = UnpackNormalScale(normalLocal, _NormalScale);
@@ -173,11 +191,13 @@ UTSSurfaceData GetUTSSurfaceData(FragInputs input, float3 V)
smoothness *=_BSDFContribution;
#endif
#ifdef _PBR_Mode_TOON
// TODO: Specular color is not handle correctly.
#ifdef _PBR_MODE_TOON
metallic = 0.0;
specularColor = _SpecularColor;
#ifdef _SPECULARCOLORMAP
specularColor = SAMPLE_TEXTURE2D(_SpecularColorMap, sampler_SpecularColorMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap)).rgb * _SpecularColor;
specularColor *= SAMPLE_TEXTURE2D(_SpecularColorMap, sampler_SpecularColorMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap)).rgb;
#endif
specularColor = GetSpecularColor(output.baseColor, metallic);
#endif
output.metallic = metallic;
@@ -190,7 +210,8 @@ UTSSurfaceData GetUTSSurfaceData(FragInputs input, float3 V)
output.geomNormalWS = input.tangentToWorld[2];
output.tangentWS = Orthonormalize(input.tangentToWorld[0].rgb, normalWS);
output.subsurfaceColor = SAMPLE_TEXTURE2D(_SSSLutMap, s_linear_clamp_sampler, TRANSFORM_TEX(input.texCoord0, _BaseColorMap)) * _SSSIntensity;
// output.subsurfaceColor = SAMPLE_TEXTURE2D(_SSSLutMap, s_linear_clamp_sampler, TRANSFORM_TEX(input.texCoord0, _BaseColorMap)) * _SSSIntensity;
output.subsurfaceColor = 0.0;
output.anisotropy = anisotropy;
@@ -203,12 +224,19 @@ UtsBSDFData ConvertUTSSurfaceDataToUTSBSDFData(UTSSurfaceData surfaceData)
output.surfaceFeatures = surfaceData.surfaceFeatures;
output.diffuseColor = UtsComputeDiffuseColor(surfaceData.baseColor, surfaceData.metallic, 0.05);
output.firstShadingDiffuseColor = UtsComputeDiffuseColor(surfaceData.firstShadingColor, surfaceData.metallic, 0.05);
output.secondShadingDiffuseColor = UtsComputeDiffuseColor(surfaceData.secondShadingColor, surfaceData.metallic, 0.05);
#if _PBR_MODE_TOON
float m = Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b);
#else
float m = surfaceData.metallic;
#endif
output.diffuseColor = UtsComputeDiffuseColor(surfaceData.baseColor, m, _Minimal_Diffuse_Contribution);
output.firstShadingDiffuseColor = UtsComputeDiffuseColor(surfaceData.firstShadingColor, m, _Minimal_Diffuse_Contribution);
output.secondShadingDiffuseColor = UtsComputeDiffuseColor(surfaceData.secondShadingColor, m, _Minimal_Diffuse_Contribution);
#if _PBR_MODE_OFF
output.fresnel0 = surfaceData.baseColor;
output.fresnel0 = 0.22;
#elif _PBR_MODE_TOON
output.fresnel0 = surfaceData.specularColor;
#else
output.fresnel0 = ComputeFresnel0(surfaceData.baseColor, surfaceData.metallic, 0.22);
#endif

View File

@@ -264,7 +264,6 @@ void UtsGetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInput
#endif
float3 doubleSidedConstants = GetDoubleSidedConstants();
ApplyDoubleSidedFlipOrMirror(input, doubleSidedConstants); // Apply double sided flip on the vertex normal
LayerTexCoord layerTexCoord;
@@ -295,7 +294,7 @@ void UtsGetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInput
#else
float alphaCutoff = _AlphaCutoff;
#endif
// clip(-0.1);
GENERIC_ALPHA_TEST(alphaValue, alphaCutoff);
#endif

View File

@@ -1,6 +1,25 @@
#ifndef UTS_SURFACE_FEATURE_EVALUATION
#define UTS_SURFACE_FEATURE_EVALUATION
void UtsEvaluateLighting_Stocking(FragInputs input, PositionInputs posInput, PreLightData preLightData, float3 N, float3 V, inout AggregateLighting aggregateLighting)
{
float fresnel = pow(preLightData.NdotV, _StockingFresnelWidth);
#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;
// NOTE: Should we use sparkle texture instead of Voronoi?
float screenSparkle = smoothstep(1.0 - (0.5 * _StockingSparkleAmount), 1, 1.0 - Voronoi(shiftedNDC * _ScreenParams.xy / spacing, 5, 5.0));
float objectSparkle = smoothstep(1.0 - (0.5 * _StockingSparkleSize), 1, 1.0 - Voronoi(input.texCoord0, 5, 100.0));
float sparkle = objectSparkle * screenSparkle * _StockingSparkleIntensity * 5;
aggregateLighting.direct.specular += sparkle * aggregateLighting.direct.specular;
#endif
aggregateLighting.direct.diffuse *= fresnel;
}
DirectLighting UtsEvaluateLighting_RimLight(PositionInputs posInput, UtsBSDFData bsdfData, PreLightData preLightData
#if _LIGHT_BASE_RIM_LIGHT_ON
, float3 L, float3 lightColor
@@ -11,6 +30,7 @@ DirectLighting UtsEvaluateLighting_RimLight(PositionInputs posInput, UtsBSDFData
ZERO_INITIALIZE(DirectLighting, lighting);
float3 rimLightColor = _RimLightColor.rgb * _RimLightIntensity;
rimLightColor = lerp(rimLightColor, rimLightColor * bsdfData.diffuseColor.rgb, _AlbedoAffectRimLight * _RimLightColor.a);
#if _SCREEN_SPACE_RIM_LIGHT_ON
float3 normalVS = normalize(mul((float3x3)UNITY_MATRIX_V, bsdfData.geomNormalWS));
@@ -38,7 +58,7 @@ DirectLighting UtsEvaluateLighting_RimLight(PositionInputs posInput, UtsBSDFData
return lighting;
}
DirectLighting UtsEvaluateLighting_AngelRing(FragInputs input, float3 normalWS, float3 V)
DirectLighting UtsEvaluateLighting_AngelRing(FragInputs input, float3 N, float3 V)
{
DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
@@ -54,15 +74,16 @@ DirectLighting UtsEvaluateLighting_AngelRing(FragInputs input, float3 normalWS,
float3 cameraRoll = acos(clamp(cameraRollCos, -1.0, 1.0));
float cameraDir = cameraRight.y < 0 ? -1.0 : 1.0;
float2 arOffsetU = lerp(mul(UNITY_MATRIX_V, float4(normalWS, 0)).xyz, float3(0, 0, 1), _AngelRingOffsetU).xy;
float2 arOffsetU = lerp(mul(UNITY_MATRIX_V, float4(N, 0)).xyz, float3(0, 0, 1), _AngelRingOffsetU).xy;
arOffsetU = arOffsetU * 0.5 + 0.5;
float2 arvnRotate = RotateUV(arOffsetU, -(cameraDir * cameraRoll).x, 0.5, 1.0);
float2 arOffsetUV = float2(arvnRotate.x, lerp(input.texCoord0.y, arvnRotate.y, _AngelRingOffsetV));
float4 angelRingColor = SAMPLE_TEXTURE2D(_AngelRingColorMap, sampler_AngelRingColorMap, TRANSFORM_TEX(arOffsetUV, _AngelRingColorMap)) * _AngelRingColor * _AngelRingIntensity;
float weight = saturate(dot(normalize(V), normalWS));
float weight = saturate(dot(V, N));
lighting.specular = angelRingColor.r * angelRingColor.a * weight;
lighting.specular = angelRingColor * angelRingColor.a * weight;
return lighting;
}

View File

@@ -11,13 +11,6 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
// We dont have to calculate lighting here if we are using sdf shadow
#ifndef _SDFShadow
#ifdef _IS_CLIPPING_MATTE
if (_ClippingMatteMode != 0)
{
return float3(0.0f, 0.0f, 0.0f);
}
#endif // _IS_CLIPPING_MATTE
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
// input.positionSS is SV_Position

View File

@@ -49,16 +49,17 @@ DirectLighting UtsEvaluateBSDF_Directional(LightLoopContext lightLoopContext, Po
float3 L = -lightData.forward;
SHADOW_TYPE shadow = 1.0;
// TODO: Should we disable the contact shadow?
#if _RECEIVE_LIGHT_SHADOW_ON
shadow = EvaluateShadow_Directional(lightLoopContext, posInput, lightData, builtinData, bsdfData.geomNormalWS);
#endif
if (lightData.lightDimmer > 0.0)
{
// TODO: Colored shadow will overwrite the first and second shading diffuse color
//float3 shadowColor = ComputeShadowColor(shadow, lightData.shadowTint, lightData.penumbraTint);
// TODO: Support ray traced transparent colored shadow
float3 shadowColor = ComputeShadowColor(shadow, lightData.shadowTint, lightData.penumbraTint);
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);
@@ -84,8 +85,8 @@ DirectLighting UtsEvaluateBSDF_Punctual(LightLoopContext lightLoopContext, Posit
if (lightData.lightDimmer > 0.0)
{
// TODO: Colored shadow will overwrite the first and second shading diffuse color
//float3 shadowColor = ComputeShadowColor(shadow, lightData.shadowTint, lightData.penumbraTint);
// TODO: Support ray traced transparent colored shadow
float3 shadowColor = ComputeShadowColor(shadow, lightData.shadowTint, lightData.penumbraTint);
float4 lightColor = EvaluateLight_Punctual(lightLoopContext, posInput, lightData, L, distances);
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)
ApplyScreenSpaceReflectionWeight(ssrLighting);
reflectionHierarchyWeight = ssrLighting.a;
reflectionHierarchyWeight = ssrLighting.a * _SSRWeight;
lighting.specularReflected = lerp(lighting.specularReflected, ssrLighting.rgb * preLightData.specularFGD, _SSRWeight);
}
@@ -194,9 +195,10 @@ IndirectLighting UtsEvaluateBSDF_MatCapSpecular(float3 positionWS, UtsBSDFData b
return lighting;
}
void UtsEvaluateBSDF_Ramp(PositionInputs posInput, UtsBSDFData bsdfData, float3 L, inout BuiltinData builtinData)
void UtsEvaluateBSDF_Ramp(PositionInputs posInput, UtsBSDFData bsdfData, inout BuiltinData builtinData)
{
// TODO
float3 lighting = SAMPLE_TEXTURE2D_ARRAY(_IndirectDiffuseRampMap, s_trilinear_clamp_sampler, float2(_IndirectDiffuseRampPosition, 0.0), _IndirectDiffuseRampIndex).rgb;
builtinData.bakeDiffuseLighting = lighting * GetInverseCurrentExposureMultiplier();
}
IndirectLighting UtsEvaluateBSDF_Env(LightLoopContext lightLoopContext, PositionInputs posInput, PreLightData preLightData, EnvLightData lightData, UtsBSDFData bsdfData, int influenceShapeType, int GPUImageBasedLightingType, inout float hierarchyWeight)
@@ -244,9 +246,9 @@ IndirectLighting UtsEvaluateBSDF_Env(LightLoopContext lightLoopContext, Position
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.direct.diffuse = APPLY_WEIGHT(lighting.direct.diffuse, aoFactor.directAmbientOcclusion, _SSAOWeight);
lighting.direct.specular = APPLY_WEIGHT(lighting.direct.specular, aoFactor.directSpecularOcclusion, _SSAOWeight);
@@ -264,7 +266,7 @@ void UtsPostEvaluateBSDF(PositionInputs posInput, PreLightData preLightData, Uts
#if !defined(_INDIRECT_DIFFUSE_MODE_OFF) || !defined(_INDIRECT_SPECULAR_MODE_OFF)
AmbientOcclusionFactor 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
AdjustIndirectLighting(preLightData, bsdfData, builtinData, lighting);
@@ -273,7 +275,6 @@ void UtsPostEvaluateBSDF(PositionInputs posInput, PreLightData preLightData, Uts
lightLoopOutput.specularLighting = lighting.direct.specular + lighting.indirect.specularReflected;
// Rescale the GGX to account for the multiple scattering.
lightLoopOutput.specularLighting *= 1.0 + bsdfData.fresnel0 * preLightData.energyCompensation;
ApplyExposureAdjustment(lightLoopOutput.diffuseLighting);
ApplyExposureAdjustment(lightLoopOutput.specularLighting);
}

View File

@@ -19,25 +19,6 @@ int eAngelRing = 4;
int eRimLight = 5;
int eOutline = 6;
int GetNextDirectionalLightIndex(BuiltinData builtinData, int currentIndex, int mainLightIndex)
{
int i = 0; // Declare once to avoid the D3D11 compiler warning.
for (i = 0; i < (int)_DirectionalLightCount; ++i)
{
if (IsMatchingLightLayer(_DirectionalLightDatas[i].lightLayers, builtinData.renderingLayers))
{
if (mainLightIndex != i)
{
if (currentIndex < i)
{
return i;
}
}
}
}
return -1; // not found
}
bool UtsUseScreenSpaceShadow(DirectionalLightData light, float3 normalWS)
{
#if defined(RAY_TRACED_SCREEN_SPACE_SHADOW_FLAG)
@@ -87,10 +68,11 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
float3 L = -light.forward;
// Is it worth sampling the shadow map?
if ((light.lightDimmer > 0) && (light.shadowDimmer > 0))
// Should we skip it if NdotL is negative? (i.e. transmission)
if ((light.lightDimmer > 0) && (light.shadowDimmer > 0) && IsNonZeroBSDF(L, bsdfData))
{
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);
}
}
@@ -214,7 +196,7 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
// 3. Sky Reflection
// 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);
AccumulateIndirectLighting(lighting, aggregateLighting);
@@ -317,7 +299,6 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
AccumulateIndirectLighting(lighting, aggregateLighting);
}
}
}
}
#elif _INDIRECT_SPECULAR_MODE_MATCAP
@@ -346,6 +327,12 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
#endif
}
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_ANGEL_RING))
{
DirectLighting lighting = UtsEvaluateLighting_AngelRing(fragInputs, bsdfData.normalWS, V);
AccumulateDirectLighting(lighting, aggregateLighting);
}
#ifndef _LIGHT_BASE_RIM_LIGHT_ON
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_RIM_LIGHT))
{
@@ -354,10 +341,9 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
}
#endif
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_ANGEL_RING))
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_STOCKING))
{
DirectLighting lighting = UtsEvaluateLighting_AngelRing(fragInputs, bsdfData.normalWS, V);
AccumulateDirectLighting(lighting, aggregateLighting);
UtsEvaluateLighting_Stocking(fragInputs, posInput, preLightData, bsdfData.normalWS, V, aggregateLighting);
}
UtsPostEvaluateBSDF(posInput, preLightData, bsdfData, builtinData, aggregateLighting, lightLoopOutput);

View File

@@ -53,21 +53,26 @@ float3 ComputeSpecularTerm(UtsBSDFData bsdfData, PreLightData preLightData, floa
DV = DV_SmithJointGGXAniso(TdotH, BdotH, NdotH, clampedNdotV, TdotL, BdotL, abs(NdotL), bsdfData.roughnessT, bsdfData.roughnessB, partLambdaV);
#elif _PBR_MODE_HAIR
// TODO: Double layer anisotropic specular.
float3 t = ShiftTangent(bsdfData.bitangentWS, N, bsdfData.anisotropy);
float specularExponent = RoughnessToBlinnPhongSpecularExponent(PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness));
DV = D_KajiyaKay(t, H, specularExponent);
float normalizeSpec = DV * rcp(specularExponent + 2) * 2 * PI;
float normalizeSpec = DV * rcp(specularExponent + 2.0) * TWO_PI;
DV = DV * normalizeSpec * _KKColor.rgb;
#elif _PBR_MODE_FABRIC
float D = D_Charlie(NdotH, bsdfData.roughnessT);
// V_Charlie is expensive, use approx with V_Ashikhmin instead
// float V = V_Charlie(NdotL, clampedNdotV, bsdfData.roughness);
float Vis = V_Ashikhmin(NdotL, clampedNdotV);
DV = D * Vis;
#elif _PBR_MODE_TOON
float specularExponent = RoughnessToBlinnPhongSpecularExponent(PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness));
DV = pow(NdotH, 5.0 * specularExponent);
DV = StepFeatherToon(DV, _ToonSpecularStep, _ToonSpecularFeather);
//specTerm = pow(NdotH, 5.0 * specularExponent);
//specTerm = StepFeatherToon(specTerm, _ToonSpecularStep, _ToonSpecularFeather);
//return specTerm * ColorSpaceDielectricSpec.rgb * clampedNdotL;
#endif
// We use specularFGD here to approximate F.
specTerm = DV * preLightData.specularFGD * clampedNdotL;
return specTerm;
#endif
@@ -115,7 +120,7 @@ DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, Pr
{
SHADOW_TYPE sharpShadow = smoothstep(0.4, 0.6, shadow);
#if _RECEIVE_HAIR_SHADOW_ON && ENABLE_UTS_HAIR_SHAOW
sharpShadow *= GetHairShadow(posInput, L);
sharpShadow *= GetHairShadow(posInput, L, bsdfData.normalWS);
#endif
#if _SHADING_MODE_SDF
@@ -129,6 +134,8 @@ DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, Pr
float3 diffuseTerm = 0.0;
float3 specularTerm = ComputeSpecularTerm(bsdfData, preLightData, V, L);
float NdotL = dot(bsdfData.normalWS, L);
#if _USE_SHADING_RAMP_MAP_ON
float rampMask = _ShadingRampMask;
#if _SHADING_RAMP_MASK_MAP
@@ -136,22 +143,20 @@ DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, Pr
#endif
#if _SHADING_MODE_STANDARD
float NdotL = dot(bsdfData.normalWS, L);
float halfLambert = 0.5 * NdotL + 0.5;
float3 rampColor = SAMPLE_TEXTURE2D_ARRAY_LOD(_ShadingRampMap, s_linear_clamp_sampler, float2(halfLambert * shadow.x, rampMask), _ShadingIndex, 0.0).rgb;
float3 rampColor = SAMPLE_TEXTURE2D_ARRAY_LOD(_ShadingRampMap, s_linear_clamp_sampler, float2(halfLambert * sharpShadow.x, rampMask), _ShadingIndex, 0).rgb;
diffuseTerm = bsdfData.diffuseColor * rampColor;
diffuseTerm = bsdfData.diffuseColor * rampColor * INV_PI;
specularTerm *= saturate(NdotL) * sharpShadow;
#elif _SHADING_MODE_SDF
float3 rampColor = SAMPLE_TEXTURE2D_ARRAY_LOD(_ShadingRampMap, s_linear_clamp_sampler, float2(sdfShadowMask * sharpShadow.x, rampMask), _ShadingIndex, 0.0).rgb;
float3 rampColor = SAMPLE_TEXTURE2D_ARRAY_LOD(_ShadingRampMap, s_linear_clamp_sampler, float2(sdfShadowMask * sharpShadow.x, rampMask), _ShadingIndex, 0).rgb;
diffuseTerm = bsdfData.diffuseColor * rampColor;
diffuseTerm = bsdfData.diffuseColor * rampColor * INV_PI;
specularTerm = (specularTerm + sdfHighlight) * sdfShadowMask * sharpShadow;
#endif
#else
#if _SHADING_MODE_STANDARD
float NdotL = dot(bsdfData.normalWS, L);
float halfLambert = 0.5 * NdotL + 0.5;
// float firstColorFeatherForMask = lerp(_1stShadeColorFeather, 0.0, max(_ComposerMaskMode, _FirstShadeOverridden));
@@ -161,12 +166,12 @@ DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, Pr
// float secondColorFeatherForMask = lerp(_2ndShadeColorFeather, 0.0, max(_SecondShadeOverridden, _ComposerMaskMode));
float firstShadeMask = saturate((halfLambert - (_2ndShadeColorStep - _2ndShadeColorFeather)) / (_2ndShadeColorStep - (_2ndShadeColorStep - _2ndShadeColorFeather)));
diffuseTerm = lerp(lerp(bsdfData.secondShadingDiffuseColor, bsdfData.firstShadingDiffuseColor, firstShadeMask), bsdfData.diffuseColor, baseShadeMask);
diffuseTerm = lerp(lerp(bsdfData.secondShadingDiffuseColor, bsdfData.firstShadingDiffuseColor, firstShadeMask), bsdfData.diffuseColor, baseShadeMask) * INV_PI;
specularTerm *= baseShadeMask;
#elif _SHADING_MODE_SDF
float shadeMask = sdfShadowMask * sdfTexture.b * sharpShadow.x;
diffuseTerm = lerp(bsdfData.firstShadingDiffuseColor, bsdfData.diffuseColor, shadeMask);
diffuseTerm = lerp(bsdfData.firstShadingDiffuseColor, bsdfData.diffuseColor, shadeMask) * INV_PI;
specularTerm = (specularTerm + sdfHighlight) * shadeMask;
#endif
#endif

View File

@@ -6,13 +6,21 @@ float3 UtsGetShadowNormal(UtsBSDFData bsdfData)
#if _MATERIAL_TYPE_FACE
return normalize(mul(UNITY_MATRIX_M, float4(0.0, 0.0, 1.0, 0.0))).xyz;
#else
return bsdfData.geomNormalWS * (1.0 + _ShadowNormalBias);
return bsdfData.normalWS * (1.0 + _ShadowNormalBias);
#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)
{
// TODO: Move sdf sample result to UtsBSDFData to avoid sampleing in a loop
float2 right_uv = float2(1 - uv.x, uv.y);
float3 left_SDFTex = SAMPLE_TEXTURE2D(_SDFShadingMap, sampler_SDFShadingMap, uv).rgb;
float3 right_SDFTex = SAMPLE_TEXTURE2D(_SDFShadingMap, sampler_SDFShadingMap, right_uv).rgb;
@@ -27,7 +35,7 @@ float3 SampleSDFTexture(float3 L, float2 uv, out float angle)
return isRightSide ? right_SDFTex : left_SDFTex;
}
float GetHairShadow(PositionInputs posInput, float3 L)
float GetHairShadow(PositionInputs posInput, float3 L, float N)
{
float shadow = 1.0;
@@ -37,17 +45,21 @@ float GetHairShadow(PositionInputs posInput, float3 L)
if (hairShadowOpacity > 0.0)
{
float3 viewLightDir = TransformWorldToViewDir(L);
float shadowLengthY = _HairShadowDistance * 5.0 * max(0.5, posInput.linearDepth * _HairShadowDistanceScaleFactor) / posInput.linearDepth;
float2 shadowLength = float2(shadowLengthY * 2.0f, shadowLengthY);
float distance = _HairShadowDistance + max(0.0, posInput.linearDepth * _HairShadowDistanceScaleFactor);
float3 viewOffsetPos = TransformWorldToView(posInput.positionWS) + viewLightDir * distance * 0.01;
float4 clipPos = mul(UNITY_MATRIX_P, float4(viewOffsetPos, 1.0));
float2 samplingPointSS = clipPos.xy / clipPos.w;
samplingPointSS = samplingPointSS * 0.5 + 0.5;
float3 cameraDirOS = normalize(TransformWorldToObject(GetCameraPositionWS()));
float cameraDirFactor = 1 - smoothstep(0.1, 0.9, cameraDirOS.y);
shadowLength.y *= cameraDirFactor;
#if UNITY_UV_STARTS_AT_TOP
samplingPointSS.y = 1.0 - samplingPointSS.y;
#endif
float2 samplingPoint = (posInput.positionSS + shadowLength * viewLightDir.xy * (_ScreenSize.xy / float2(1920.0f, 1080.0f))) * _ScreenSize.zw; // Use 1080p as the reference resolution to achieve consistent shadow lengths across various screen resolutions.
float NdotL = saturate(dot(N, L));
float slopeBias = (1.0 - NdotL) * _HairShadowDepthBias;
float2 scaledUVs = samplingPoint * _HairShadowRTHandleScale.xy; // We have to including the scaling factor for our shadow map since we are not going to allocate new texture if the rendering resolution changed.
float hairShadow = SAMPLE_TEXTURE2D_SHADOW(_HairShadowTex, s_linear_clamp_compare_sampler, float3(scaledUVs, posInput.deviceDepth + _HairShadowDepthBias)).r;
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);
}
@@ -76,9 +88,9 @@ SHADOW_TYPE UtsEvaluateShadow_Punctual(LightLoopContext lightLoopContext, Positi
}
else
#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
// 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

@@ -62,11 +62,11 @@ float _ToonIgnoreExposureMultiplier;
float _Outline_MaxWidth;
float4 _HairShadowRTHandleScale;
float4 _HairBlendingRTHandleScale;
float _HairShadowDistance;
float _HairShadowDistanceScaleFactor;
float _HairShadowDepthBias;
float _HairShadowFadeInDistance;
float _HairShadowFadeOutDistance;
// float2 _HairShadowRTHandleScale;
// float2 _HairBlendingRTHandleScale;

View File

@@ -33,6 +33,13 @@ TEXTURE2D(_SSSLutMap);
TEXTURE2D(_HairBlendingMap);
SAMPLER(sampler_HairBlendingMap);
TEXTURE2D(_EmissiveColorMap);
SAMPLER(sampler_EmissiveColorMap);
// Stocking
TEXTURE2D(_StockingSparkingMap);
SAMPLER(sampler_StockingSparkingMap);
// Global
TEXTURE2D(_HairShadowTex);
TEXTURE2D_X(_HairBlendingTex);
@@ -42,6 +49,8 @@ TEXTURE2D_X(_HairBlendingTex);
TEXTURE2D(_IndirectDiffuseMatCapMap);
TEXTURE2D(_IndirectSpecularMatCapMap);
TEXTURE2D_ARRAY(_IndirectDiffuseRampMap);
TEXTURE2D(_ClippingMask);
TEXTURE2D(_AngelRingColorMap);

View File

@@ -1,5 +1,9 @@
// Surface Option
float _SurfaceFeatures;
half _AlphaCutoffEnable;
float _AlphaCutoff;
half _BlendMode;
float4 _DoubleSidedConstants;
// Shading Color
float4 _BaseColor;
@@ -7,8 +11,8 @@ float4 _BaseColorMap_ST;
float4 _BaseColorMap_TexelSize;
float4 _BaseColorMap_MipInfo;
float _ShadingIndex;
half _ShadingRampMask;
int _ShadingIndex;
float _ShadingRampMask;
float4 _1stShadeColor;
float4 _2ndShadeColor;
@@ -58,18 +62,23 @@ float _ToonSpecularFeather;
float _BSDFContribution;
float _EnergyConservingSpecularColor;
float _SSSIntensity;
int _Use_SSSLut;
// float _SSSIntensity;
// int _Use_SSSLut;
float3 _EmissiveColor;
half _AlbedoAffectEmissive;
half _EmissiveExposureWeight;
float4 _EmissiveColorMap_ST;
half _TexWorldScaleEmissive;
float _ObjectSpaceUVMappingEmissive;
// Ambient
float _IndirectDiffuseMatCapLod;
int _IndirectDiffuseRampIndex;
float _IndirectDiffuseRampPosition;
float _IndirectDiffuseIntensity;
float _SSAOWeight;
float _SSGIWeight;
@@ -79,15 +88,6 @@ float _IndirectSpecularMatCapLod;
float _IndirectSpecularIntensity;
float _SSRWeight;
//Rim Light
float4 _RimLightColor;
float _RimLightIntensity;
float _RimLightLevel;
half _RimLightClipping;
float _RimLightClippingLevel;
float _LightDirectionRimLightLevel;
// Angle Ring
float4 _AngelRingColor;
float4 _AngelRingColorMap_ST;
@@ -95,6 +95,23 @@ float _AngelRingIntensity;
float _AngelRingOffsetU;
float _AngelRingOffsetV;
//Rim Light
float4 _RimLightColor;
float _RimLightIntensity;
half _AlbedoAffectRimLight;
float _RimLightLevel;
half _RimLightClipping;
float _RimLightClippingLevel;
float _LightDirectionRimLightLevel;
// Stocking
float _StockingFresnelWidth;
float _StockingSparkleSpacing;
float _StockingSparkleAmount;
float _StockingSparkleSize;
float _StockingSparkleIntensity;
// Outline
float _OutlineWidth;
float4 _OutlineColor;
@@ -114,15 +131,13 @@ float _HairBlendingFactor;
// Advance
half _ClampLightColor;
float _LightIntensityMultiplier;
float _Minimal_Diffuse_Contribution;
// Light Loop
float3 _ObjectCenterPositionWS;
// NOTE: Not sure what these are for
// float _FirstShadeOverridden;
// float _SecondShadeOverridden;
float _UseShadowThreshold;
float _AlphaCutoffShadow;
float _ComposerMaskMode;
#if defined(_UTS_TOON_EV_PER_MODEL)

View File

@@ -63,7 +63,7 @@ void Frag(PackedVaryingsToPS packedInput,
#ifdef _DEPTHOFFSET_ON
, out float outputDepth : SV_Depth
#endif
)
)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput);
FragInputs input = UnpackVaryingsMeshToFragInputs(packedInput.vmesh);
@@ -73,7 +73,6 @@ void Frag(PackedVaryingsToPS packedInput,
// The following temporary definition of unity_AmbientEquator is for HDRP only.
//float4 unity_AmbientEquator = float4(0.05, 0.05, 0.05, 1.0); //Todo.
//v.2.0.9
//float3 envLightSource_GradientEquator = unity_AmbientEquator.rgb > 0.05 ? unity_AmbientEquator.rgb : half3(0.05, 0.05, 0.05);
float3 envLightSource_GradientEquator = ShadeSH9(float4(0, 1, 0, 0));
float3 envLightSource_SkyboxIntensity = max(
@@ -83,8 +82,8 @@ void Frag(PackedVaryingsToPS packedInput,
float3 ambientSkyColor = envLightSource_SkyboxIntensity.rgb > 0.0 ? envLightSource_SkyboxIntensity : envLightSource_GradientEquator;
ambientSkyColor *= GetCurrentExposureMultiplier();
float4 _BlendingTex_var = SAMPLE_TEXTURE2D(_HairBlendingMap, sampler_HairBlendingMap, TRANSFORM_TEX(Set_UV0, _BaseColorMap));
outColor = float4(_BlendingTex_var.rgb * ambientSkyColor, _BlendingTex_var.a);
float4 blendingTex = SAMPLE_TEXTURE2D(_HairBlendingMap, sampler_HairBlendingMap, TRANSFORM_TEX(Set_UV0, _BaseColorMap));
outColor = float4(blendingTex.rgb + ambientSkyColor, blendingTex.a);
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.deviceDepth;

View File

@@ -41,7 +41,6 @@ PackedVaryingsType Vert(AttributesMesh inputMesh)
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
#ifdef UNITY_VIRTUAL_TEXTURING
#define VT_BUFFER_TARGET SV_Target1
#define EXTRA_BUFFER_TARGET SV_Target2
@@ -49,8 +48,6 @@ PackedVaryingsType Vert(AttributesMesh inputMesh)
#define EXTRA_BUFFER_TARGET SV_Target1
#endif
void Frag(PackedVaryingsToPS packedInput,
#ifdef OUTPUT_SPLIT_LIGHTING
out float4 outColor : SV_Target0, // outSpecularLighting
@@ -82,44 +79,45 @@ void Frag(PackedVaryingsToPS packedInput,
discard;
}
#endif
#ifdef _IS_CLIPPING_MATTE
if (_ClippingMatteMode != 0)
{
discard;
}
#endif // _IS_CLIPPING_MATTE
#if defined(UTS_DEBUG_SHADOWMAP_NO_OUTLINE)
discard;
#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;
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;
outlineColor.rgb = lerp(outlineColor.rgb, outlineColor.rgb + ambientSkyColor, _SkyColorAffectOutline);
#if _OUTLINECOLORMAP
outlineColor *= SAMPLE_TEXTURE2D(_OutlineColorMap, sampler_OutlineColorMap, TRANSFORM_TEX(uv0, _BaseColorMap)).rgb;
#endif
outlineColor.rgb = lerp(outlineColor.rgb, outlineColor.rgb * baseColor, _AlbedoAffectOutline);
float3 volColor, volOpacity;
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;
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
// 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);
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
float3 volColor, volOpacity;
EvaluateAtmosphericScattering(posInput, V, volColor, volOpacity); // Premultiplied alpha
outlineColor.rgb = outlineColor.rgb * (1 - volOpacity) + volColor;
outColor = outlineColor;
@@ -131,5 +129,3 @@ void Frag(PackedVaryingsToPS packedInput,
outVTFeedback = builtinData.vtPackedFeedback;
#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);
//v.2.0.4.3 baked Normal Texture for Outline
float3 normalDir = UnityObjectToWorldNormal(inputMesh.normalOS);
float3 tangentDir = normalize(mul(unity_ObjectToWorld, float4(inputMesh.tangentOS.xyz, 0.0)).xyz);
float3 tangentDir = normalize(mul(UNITY_MATRIX_M, float4(inputMesh.tangentOS.xyz, 0.0)).xyz);
float3 bitangentDir = normalize(cross(normalDir, tangentDir) * inputMesh.tangentOS.w);
float3x3 tangentTransform = float3x3(tangentDir, bitangentDir, normalDir);
//end

View File

@@ -1,6 +1,4 @@
//Unity Toon Shader/HDRP
//nobuyuki@unity3d.com
//toshiyuki@unity3d.com (Universal RP/HDRP)
#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Common/UtsLitData.hlsl"
#define APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
@@ -81,32 +79,22 @@ void Frag(PackedVaryingsToPS packedInput,
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput);
FragInputs input = UnpackVaryingsMeshToFragInputs(packedInput.vmesh);
#if defined(PLATFORM_SUPPORTS_PRIMITIVE_ID_IN_PIXEL_SHADER) && SHADER_STAGE_FRAGMENT
#if (defined(VARYINGS_NEED_PRIMITIVEID) || (SHADERPASS == SHADERPASS_FULL_SCREEN_DEBUG))
input.primitiveID = packedInput.primitiveID;
#endif
#endif
#if defined(VARYINGS_NEED_CULLFACE) && SHADER_STAGE_FRAGMENT
input.isFrontFace = IS_FRONT_VFACE(packedInput.cullFace, true, false);
#endif
FragInputs input = UnpackVaryingsToFragInputs(packedInput);
// We need to readapt the SS position as our screen space positions are for a low res buffer, but we try to access a full res buffer.
input.positionSS.xy = _OffScreenRendering > 0 ? (input.positionSS.xy * _OffScreenDownsampleFactor) : input.positionSS.xy;
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);
#ifdef VARYINGS_NEED_POSITION_WS
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
#ifdef MATERIAL_TYPE_EYE
// Must have view Dir to work
float2 viewT = TransformObjectToTangent(V, input.tangentToWorld);
float2 parallaxOffset = viewT;
parallaxOffset.y = -parallaxOffset.y;
input.texCoord0.xy = clamp(input.texCoord0.xy -_EyeParallaxAmount * parallaxOffset, 0, 1);
// Must have view Dir to work
float2 viewT = TransformObjectToTangent(V, input.tangentToWorld);
float2 parallaxOffset = viewT;
parallaxOffset.y = -parallaxOffset.y;
input.texCoord0.xy = clamp(input.texCoord0.xy -_EyeParallaxAmount * parallaxOffset, 0, 1);
#endif
#else
@@ -121,7 +109,11 @@ void Frag(PackedVaryingsToPS packedInput,
SurfaceData tempSurfaceData;
BuiltinData builtinData;
GetSurfaceAndBuiltinData(input, V, posInput, tempSurfaceData, builtinData);
UtsGetSurfaceAndBuiltinData(input, V, posInput, tempSurfaceData, builtinData);
float3 doubleSidedConstants = GetDoubleSidedConstants();
ApplyDoubleSidedFlipOrMirror(input, doubleSidedConstants);
UTSSurfaceData surfaceData = GetUTSSurfaceData(input, V);
UtsBSDFData bsdfData = ConvertUTSSurfaceDataToUTSBSDFData(surfaceData);
@@ -132,11 +124,9 @@ void Frag(PackedVaryingsToPS packedInput,
context.shadowContext = InitShadowContext();
context.shadowValue = 1;
context.sampleReflection = 0.0;
#if UNITY_VERSION >= 202120 && UNITY_VERSION < 202320
context.splineVisibility = -1;
#endif
#ifdef APPLY_FOG_ON_SKY_REFLECTIONS
context.positionWS = posInput.positionWS;
context.positionWS = posInput.positionWS;
#endif
// With XR single-pass and camera-relative: offset position to do lighting computations from the combined center view (original camera matrix).
@@ -146,31 +136,21 @@ void Frag(PackedVaryingsToPS packedInput,
// Initialize the contactShadow and contactShadowFade fields
InitContactShadow(posInput, context);
float channelAlpha = 0.0f;
LightLoopOutput lightLoopOutput;
ZERO_INITIALIZE(LightLoopOutput, lightLoopOutput);
UtsLightLoop(input, posInput, bsdfData, builtinData, V, featureFlags, lightLoopOutput);
float3 finalColor = lightLoopOutput.diffuseLighting + lightLoopOutput.specularLighting;
#ifdef _IS_TRANSCLIPPING_OFF
outColor = float4(finalColor, 1 * ApplyChannelAlpha(channelAlpha));
#elif _IS_TRANSCLIPPING_ON
float Set_Opacity = saturate((inverseClipping + _Tweak_transparency));
outColor = EvaluateAtmosphericScattering(posInput, V, float4(finalColor, 1));
outColor = float4(outColor.rgb, Set_Opacity * ApplyChannelAlpha(channelAlpha));
#endif
outColor = ApplyBlendMode(lightLoopOutput.diffuseLighting, lightLoopOutput.specularLighting, builtinData.opacity);
#if _MATERIAL_TYPE_FRONTHAIR && ENABLE_UTS_HAIR_BLENDING
float2 screenUV = posInput.positionNDC * _HairBlendingRTHandleScale.xy;
float4 hairBlendingMap = LOAD_TEXTURE2D_X(_HairBlendingTex, screenUV);
outColor.rgb = lerp(outColor.rgb, hairBlendingMap.rgb, hairBlendingMap.a * _HairBlendingFactor);
float2 screenUV = posInput.positionSS; // * _HairBlendingRTHandleScale.xy; // Why we don't need to scale? Does unity handle it internally?
float4 hairBlendingTex = LOAD_TEXTURE2D_X(_HairBlendingTex, screenUV);
outColor.rgb = lerp(outColor.rgb, hairBlendingTex.rgb, hairBlendingTex.a * _HairBlendingFactor);
#endif
#if _ENABLE_FOG_ON_TRANSPARENT && _SURFACE_TYPE_TRANSPARENT
outColor = EvaluateAtmosphericScattering(posInput, V, outColor);
#endif
#if UTS_DEBUG_SHADOWMAP || UTS_DEBUG_SELFSHADOW
@@ -196,4 +176,5 @@ void Frag(PackedVaryingsToPS packedInput,
outVTFeedback = builtinData.vtPackedFeedback;
#endif
//outColor.rgb = input.isFrontFace;
}

View File

@@ -23,14 +23,18 @@ namespace Misaki.HdrpToon
Shader.SetGlobalFloat("_Outline_MaxWidth", utsRenderer.outlineMaxWidth.value * 0.01f);
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,
renderQueueRange = GetRenderQueueRange(RenderQueueType.All),
renderQueueRange = GetRenderQueueRange(RenderQueueType.AllOpaque),
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

@@ -21,15 +21,12 @@ namespace Misaki.HdrpToon
private const string _TOON_LIGHT_FILTER_PROP_NAME = "_ToonLightHiCutFilter";
private const string _IGNORE_VOLUME_EXPOSURE_PROP_NAME = "_ToonIgnoreExposureMultiplier";
private const string _HAIR_SHADOW_RTHANDLE_SCALE_PROP_NAME = "_HairShadowRTHandleScale";
private const string _HAIR_SHADOW_DISTANCE_PROP_NAME = "_HairShadowDistance";
private const string _HAIR_SHADOW_DISTANCE_SCALE_PROP_NAME = "_HairShadowDistanceScaleFactor";
private const string _HAIR_SHADOW_DEPTH_BIAS_PROP_NAME = "_HairShadowDepthBias";
private const string _HAIR_SHADOW_FADEIN_PROP_NAME = "_HairShadowFadeInDistance";
private const string _HAIR_SHADOW_FADE_OUT_PROP_NAME = "_HairShadowFadeOutDistance";
private const string _HAIR_BLENDING_RTHANDLE_SCALE_PROP_NAME = "_HairBlendingRTHandleScale";
private const string _HAIR_SHADOW_RT_PROP_NAME = "_HairShadowTex";
private const string _HAIR_BLENDING_PROP_NAME = "_HairBlendingTex";
@@ -43,7 +40,9 @@ namespace Misaki.HdrpToon
private RTHandle _hairShadowRTHandle;
private bool _needReallocateHairShadow;
// TODO: Possible to avoid another RTHandle for depth?
private RTHandle _hairBlendingRTHandle;
private RTHandle _hairBlendingDepthRTHandle;
private bool _needReallocateHairBlending;
private bool _enableHairShadow;
@@ -128,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()
@@ -142,25 +141,20 @@ namespace Misaki.HdrpToon
}
#endif
var scale = _hairShadowQuality switch
var format = _hairShadowQuality switch
{
BufferQuality.Low => new Vector2(0.5f, 0.5f),
BufferQuality.High => Vector2.one,
_ => Vector2.zero
BufferQuality.Low => GraphicsFormat.D16_UNorm,
BufferQuality.High => GraphicsFormat.D32_SFloat,
_ => GraphicsFormat.D16_UNorm
};
_hairShadowRTHandle?.Release();
_hairShadowRTHandle = RTHandles.Alloc(scale, useDynamicScale: true, format: GraphicsFormat.D16_UNorm, isShadowMap: true, name: _HAIR_SHADOW_RT_PROP_NAME);
_hairShadowRTHandle = RTHandles.Alloc(Vector2.one, useDynamicScale: true, format: format, isShadowMap: true, name: _HAIR_SHADOW_RT_PROP_NAME);
Shader.SetGlobalTexture(_HAIR_SHADOW_RT_PROP_NAME, _hairShadowRTHandle);
_needReallocateHairShadow = false;
}
private bool ShouldReallocateHairBlendingBuffer()
{
return _hairBlendingRTHandle == null || _hairBlendingRTHandle.rt == null || !_hairBlendingRTHandle.rt.IsCreated() || _needReallocateHairBlending;
}
private void ReallocateHairBlendingBuffer()
{
#if UNITY_EDITOR
@@ -179,6 +173,13 @@ namespace Misaki.HdrpToon
_hairBlendingRTHandle?.Release();
_hairBlendingRTHandle = RTHandles.Alloc(Vector2.one, useDynamicScale: true, dimension: TextureXR.dimension, colorFormat: format, name: _HAIR_BLENDING_PROP_NAME);
if (_hairBlendingDepthRTHandle == null || _hairBlendingDepthRTHandle.rt == null || !_hairBlendingDepthRTHandle.rt.IsCreated())
{
_hairBlendingDepthRTHandle?.Release();
_hairBlendingDepthRTHandle = RTHandles.Alloc(Vector2.one, useDynamicScale: true, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.D16_UNorm, name: _HAIR_BLENDING_PROP_NAME + "_depth");
}
Shader.SetGlobalTexture(_HAIR_BLENDING_PROP_NAME, _hairBlendingRTHandle);
_needReallocateHairBlending = false;
@@ -255,7 +256,7 @@ namespace Misaki.HdrpToon
return;
}
if (ShouldReallocateHairShadowBuffer())
if (!IsRTHandleValid(_hairShadowRTHandle) || _needReallocateHairShadow)
{
ReallocateHairShadowBuffer();
return;
@@ -265,16 +266,19 @@ namespace Misaki.HdrpToon
{
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),
sortingCriteria = SortingCriteria.CommonOpaque,
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.SetGlobalVector(_HAIR_SHADOW_RTHANDLE_SCALE_PROP_NAME, _hairShadowRTHandle.rtHandleProperties.rtHandleScale);
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_DEPTH_BIAS_PROP_NAME, utsRenderer.shadowDepthBias.value);
@@ -290,7 +294,7 @@ namespace Misaki.HdrpToon
return;
}
if (ShouldReallocateHairBlendingBuffer())
if (!IsRTHandleValid(_hairBlendingRTHandle) || _needReallocateHairBlending)
{
ReallocateHairBlendingBuffer();
return;
@@ -298,17 +302,20 @@ namespace Misaki.HdrpToon
using (new ProfilingScope(ctx.cmd, _hairBlendingProfilingSampler))
{
CoreUtils.SetRenderTarget(ctx.cmd, _hairBlendingRTHandle, ctx.cameraDepthBuffer, ClearFlag.Color);
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),
sortingCriteria = SortingCriteria.CommonOpaque,
excludeObjectMotionVectors = false,
};
CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result));
Shader.SetGlobalVector(_HAIR_BLENDING_RTHANDLE_SCALE_PROP_NAME, _hairBlendingRTHandle.rtHandleProperties.rtHandleScale);
#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
}
}
@@ -326,6 +333,7 @@ namespace Misaki.HdrpToon
_exposureArray = null;
_hairShadowRTHandle?.Release();
_hairBlendingRTHandle?.Release();
_hairBlendingDepthRTHandle?.Release();
}
}
}

View File

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

View File

@@ -19,7 +19,7 @@ namespace Misaki.HdrpToon
public BoolParameter enableHairShadow = new(false);
public ClampedFloatParameter shadowDistance = new(5.0f, 0.0f, 20.0f);
public ClampedFloatParameter shadowDistanceScale = new(0.5f, 0.0f, 1.0f);
public ClampedFloatParameter shadowDepthBias = new(0f, 0.0f, 0.01f);
public ClampedFloatParameter shadowDepthBias = new(0f, -0.01f, 0.01f);
public FloatParameter shadowFadeIn = new(45f);
public FloatParameter shadowFadeOut = new(50f);

View File

@@ -44,8 +44,36 @@ Shader "Hidden/Shader/UTSTonemapping"
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);
#endif
}
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.
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);
float3 color = UTSToonmap(sourceColor * whiteScale);
color *= whiteScale;
#endif
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",
"version": "2.1.0",
"version": "3.0.2",
"displayName": "HDRP Toon",
"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",
@@ -21,6 +21,6 @@
},
"dependencies": {
"com.unity.render-pipelines.high-definition": "17.0.0",
"com.misaki.shader-gui": "1.1.2"
"com.misaki.shader-gui": "1.1.5"
}
}