13 Commits

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

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

View File

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

View File

@@ -1649,11 +1649,11 @@ namespace UnityEditor.Rendering.Toon
m_MaterialEditor.TexturePropertySingleLine(Styles.hairBlendingTargetMapText, hairBlendingMap);
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
{
@@ -49,7 +49,7 @@ namespace Misaki.HdrpToon.Editor
public static bool IsHairBlendingTarget(this Material material)
{
return material.GetShaderPassEnabled(UtsShaderPassName.HAIR_BLENDING_TARGET_PASS_NAME);
return material.GetShaderPassEnabled(UTSPassName.HAIR_BLENDING_TARGET_PASS_NAME);
}
}
}

View File

@@ -5,20 +5,14 @@ namespace Misaki.HdrpToon.Editor
SurfaceOptions = 1 << 0,
ShadingColor = 1 << 1,
Shadow = 1 << 2,
MaterialFeature = 1 << 3,
SurfaceInputs = 1 << 4,
Ambient = 1 << 5,
Highlight = 1 << 6,
Rimlight = 1 << 7,
MatCap = 1 << 8,
Stocking = 1 << 9,
AngelRing = 1 << 10,
Emission = 1 << 11,
Outline = 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,11 +2,11 @@ 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
{
@@ -20,7 +20,7 @@ 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 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.");
@@ -32,7 +32,7 @@ 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);

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");
@@ -52,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");
@@ -99,11 +99,9 @@ namespace Misaki.HdrpToon.Editor
private static void DrawIndirectSpecularHeader()
{
EditorGUILayout.Space();
using (var indentLevelScope = new EditorGUI.IndentLevelScope(-1))
{
using var indentLevelScope = new EditorGUI.IndentLevelScope(-1);
EditorGUILayout.LabelField("Indirect Specular", EditorStyles.boldLabel);
}
}
protected override void DrawContent()
{

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,11 +3,11 @@ 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
{
@@ -43,7 +43,7 @@ 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);

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
{
@@ -85,7 +85,7 @@ namespace Misaki.HdrpToon.Editor
}
}
public override void LoadMaterialProperties()
protected override void LoadMaterialProperties()
{
Properties.shadingRampMapState = FindProperty("_Use_Shading_Ramp_Map");

View File

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

View File

@@ -1,22 +1,52 @@
using Misaki.ShaderGUI;
using System.Linq;
using UnityEditor;
using UnityEngine;
using static Misaki.HdrpToon.UTSPropertyName.Stocking;
namespace Misaki.HdrpToon.Editor
{
public class StockingScope : MaterialUIScope<ShaderGUIExpandable>
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 GUIContent Header => throw new System.NotImplementedException();
public override void LoadMaterialProperties()
protected override void LoadMaterialProperties()
{
throw new System.NotImplementedException();
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()
{
throw new System.NotImplementedException();
editor.ShaderProperty(Properties.stockingFresnelWidth, Styles.stockingFresnelWidthText);
editor.ShaderProperty(Properties.stockingSparkleSpacing, Styles.stockingSparkleSpacingText);
editor.ShaderProperty(Properties.stockingSparkleAmount, Styles.stockingSparkleAmountText);
editor.ShaderProperty(Properties.stockingSparkleSize, Styles.stockingSparkleSizeText);
editor.ShaderProperty(Properties.stockingSparkleIntensity, Styles.stockingSparkleIntensityText);
}
}
}

View File

@@ -4,11 +4,11 @@ using UnityEditor;
using UnityEditor.Rendering;
using 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
{
@@ -75,7 +75,7 @@ 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");

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.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.GetBooleanValue());
}
}
editor.ShaderProperty(Properties.surfaceFeatures, Styles.surfaceFeaturesText);
}
}

View File

@@ -1,7 +1,6 @@
using Misaki.ShaderGUI;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
namespace Misaki.HdrpToon.Editor
{
@@ -11,24 +10,9 @@ namespace Misaki.HdrpToon.Editor
public override void ValidateMaterial(Material material)
{
material.SetShaderPassEnabled(UtsShaderPassName.HAIR_SHADOW_CASTER_PASS_NAME, (MaterialType)material.GetInteger("_Material_Type") == MaterialType.FrontHair);
material.SetShaderPassEnabled(UtsShaderPassName.HAIR_BLENDING_TARGET_PASS_NAME, material.GetInteger("_HairBlendingTarget") == 1);
if (material.GetInteger("_AlphaCutoffEnable") > 0.0f)
{
material.SetInt("_ZTestGBuffer", (int)CompareFunction.Equal);
}
else
{
material.SetInt("_ZTestGBuffer", (int)CompareFunction.LessEqual);
}
//if (surfaceType == SurfaceType.Opaque)
//{
material.SetInt("_ZTestDepthEqualForOpaque", (int)CompareFunction.Equal);
//}
//else
// material.SetInt(kZTestDepthEqualForOpaque, (int)material.GetTransparentZTest());
UTSAPI.SetupPass(material);
UTSAPI.SetupKeywords(material);
UTSAPI.SetupProperties(material);
}
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
@@ -47,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

@@ -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

@@ -1,13 +1,67 @@
namespace Misaki.HdrpToon
{
internal static class UtsShaderPropertyName
internal static class UTSPropertyName
{
public static class InternalProperties
{
public const string SURFACE_TYPE = "_SurfaceType";
public const string DOUBLE_SIDED_CONSTANTS = "_DoubleSidedConstants";
public const string TRANSPARENT_DEPTH_PREPASS_ENABLE = "_TransparentDepthPrepassEnable";
public const string TRANSPARENT_BACKFACE_ENABLE = "_TransparentBackfaceEnable";
public const string TRANSPARENT_DEPTH_POSTPASS_ENABLE = "_TransparentDepthPostpassEnable";
public const string TRANSPARENT_CULL_MODE = "_TransparentCullMode";
public const string OPAQUE_CULL_MODE = "_OpaqueCullMode";
public const string SRC_BLEND = "_SrcBlend";
public const string DEST_BLEND = "_DstBlend";
public const string DEST_BLEND2 = "_DstBlend2";
public const string ALPHA_SRC_BLEND = "_AlphaSrcBlend";
public const string ALPHA_DEST_BLEND = "_AlphaDstBlend";
public const string CULL_MODE_FORWARD = "_CullModeForward";
public const string ZTEST_GBUFFER = "_ZTestGBuffer";
public const string ZTEST_DEPTH_EQUAL_FOR_OPAQUE = "_ZTestDepthEqualForOpaque";
public const string ZTEST_TRANSPARENT = "_ZTestTransparent";
public const string ZWRITE = "_ZWrite";
public const string STENCIL_REF = "_StencilRef";
public const string STENCIL_WRITE_MASK = "_StencilWriteMask";
public const string STENCIL_REF_DEPTH = "_StencilRefDepth";
public const string STENCIL_WRITE_MASK_DEPTH = "_StencilWriteMaskDepth";
public const string STENCIL_REF_G_BUFFER = "_StencilRefGBuffer";
public const string STENCIL_WRITE_MASK_G_BUFFER = "_StencilWriteMaskGBuffer";
public const string STENCIL_REF_MV = "_StencilRefMV";
public const string STENCIL_WRITE_MASK_MV = "_StencilWriteMaskMV";
public const string STENCIL_REF_DISTORTION_VEC = "_StencilRefDistortionVec";
public const string STENCIL_WRITE_MASK_DISTORTION_VEC = "_StencilWriteMaskDistortionVec";
}
public static class SurfaceOptions
{
public 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 PBR_MODE = "_PBR_Mode";
public const string SURFACE_FEATURE = "_SurfaceFeatures";
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
@@ -22,6 +76,15 @@ namespace Misaki.HdrpToon
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";
@@ -46,13 +109,13 @@ namespace Misaki.HdrpToon
public const string RIM_LIGHT_MASK_LEVEL = "_Tweak_RimLightMaskLevel";
}
public static class AngelRing
public static class Stocking
{
public const string ANGEL_RING_COLOR = "_AngelRingColor";
public const string 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 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -8,9 +8,9 @@
// Misaki.HdrpToon.SurfaceFeature: static fields
//
#define SURFACEFEATURE_NONE (0)
#define SURFACEFEATURE_STOCKING (1)
#define SURFACEFEATURE_ANGEL_RING (1)
#define SURFACEFEATURE_RIM_LIGHT (2)
#define SURFACEFEATURE_ANGEL_RING (4)
#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,64 +2,52 @@ Shader "HDRP/Toon"
{
Properties
{
//TODO: Use custom rendering data.
[ToggleUI] _UseShadowThreshold("_UseShadowThreshold", Float) = 0.0
//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
[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)
@@ -81,13 +69,24 @@ Shader "HDRP/Toon"
//TODO: Move more properties here for better organization
// Surface Options
[Popup] _TransparentEnabled("Transparent Mode", Integer) = 0
[Popup(_ALPHATEST_ON)] _AlphaCutoffEnable("Alpha Cutoff Enable", Integer) = 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, Fabric, 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
@@ -172,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
@@ -192,6 +191,13 @@ Shader "HDRP/Toon"
_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
@@ -217,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
@@ -232,7 +238,7 @@ 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
@@ -256,7 +262,15 @@ Shader "HDRP/Toon"
_TexWorldScaleEmissive("Scale to apply on world coordinate", Float) = 1.0
[HideInInspector] _UVMappingMaskEmissive("_UVMappingMaskEmissive", Color) = (1, 0, 0, 0)
[HideInInspector] _DiffusionProfile("Obsolete, kept for migration purpose", Int) = 0
_SubsurfaceMask("Subsurface Radius", Range(0.0, 1.0)) = 1.0
_SubsurfaceMaskMap("Subsurface Radius Map", 2D) = "white" {}
_TransmissionMask("Transmission Mask", Range(0.0, 1.0)) = 1.0
_TransmissionMaskMap("Transmission Mask Map", 2D) = "white" {}
_Thickness("Thickness", Float) = 1.0
_ThicknessMap("Thickness Map", 2D) = "white" {}
_ThicknessRemap("Thickness Remap", Vector) = (0, 1, 0, 0)
[HideInInspector] _DiffusionProfile("Obsolete, kept for migration purpose", Integer) = 0
[HideInInspector] _DiffusionProfileAsset("Diffusion Profile Asset", Vector) = (0, 0, 0, 0)
[HideInInspector] _DiffusionProfileHash("Diffusion Profile Hash", Float) = 0
}
@@ -269,6 +283,8 @@ Shader "HDRP/Toon"
//-------------------------------------------------------------------------------------
// Variant
//-------------------------------------------------------------------------------------
#pragma multi_compile _ DOTS_INSTANCING_ON
#pragma shader_feature_local _DOUBLESIDED_ON
#pragma shader_feature_local _NORMALMAP_TANGENT_SPACE
@@ -380,7 +396,6 @@ Shader "HDRP/Toon"
#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch
#pragma instancing_options renderinglayer
#pragma multi_compile _ DOTS_INSTANCING_ON
#pragma multi_compile _ DEBUG_DISPLAY
@@ -392,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
@@ -443,7 +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.
@@ -511,9 +538,9 @@ Shader "HDRP/Toon"
HLSLPROGRAM
#pragma shader_feature_local_fragment _MASKMAP
#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
@@ -561,10 +588,12 @@ Shader "HDRP/Toon"
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
@@ -629,11 +658,22 @@ 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
#pragma shader_feature _SURFACE_TYPE_TRANSPARENT
#pragma shader_feature_local _DISABLE_SSR_TRANSPARENT
#define SHADERPASS SHADERPASS_TRANSPARENT_DEPTH_PREPASS
// If the transparent surface should have reflections, then we should output normal
#if !defined(_DISABLE_SSR_TRANSPARENT)
#define WRITE_NORMAL_BUFFER
#endif
#define SHADERPASS SHADERPASS_DEPTH_ONLY
#define CUTOFF_TRANSPARENT_DEPTH_PREPASS
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitDepthPass.hlsl"
@@ -660,7 +700,17 @@ 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_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
@@ -711,9 +761,9 @@ Shader "HDRP/Toon"
Name "ForwardOnly"
Tags { "LightMode" = "ForwardOnly" }
ZWrite [_ZWriteMode]
ZWrite [_ZWrite]
ZTest [_ZTestDepthEqualForOpaque]
Cull [_CullMode]
Cull [_CullModeForward]
Blend [_SrcBlend] [_DstBlend], [_AlphaSrcBlend] [_AlphaDstBlend]
// ForwardOpaque | ForwardTransparent
@@ -724,15 +774,15 @@ Shader "HDRP/Toon"
Stencil
{
Ref[_StencilNo]
Comp[_StencilComp]
Pass[_StencilOpPass]
Fail[_StencilOpFail]
WriteMask [_StencilWriteMask]
Ref [_StencilRef]
Comp Always
Pass Replace
}
HLSLPROGRAM
#pragma multi_compile _ DEBUG_DISPLAY
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
@@ -743,18 +793,13 @@ Shader "HDRP/Toon"
#pragma multi_compile SCREEN_SPACE_SHADOWS_OFF SCREEN_SPACE_SHADOWS_ON
#pragma multi_compile_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
#pragma shader_feature _EMISSIVE_SIMPLE _EMISSIVE_ANIMATION
#pragma shader_feature ENABLE_UTS_HAIR_SHAOW
@@ -780,16 +825,21 @@ Shader "HDRP/Toon"
#pragma shader_feature_local_fragment _SHADING_RAMP_MASK_MAP
#pragma shader_feature_local _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
@@ -801,6 +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"
@@ -850,6 +909,7 @@ Shader "HDRP/Toon"
HLSLPROGRAM
#pragma shader_feature_local _ALPHATEST_ON
#pragma shader_feature _SURFACE_TYPE_TRANSPARENT
#define SHADERPASS SHADERPASS_DEPTH_ONLY
#define CUTOFF_TRANSPARENT_DEPTH_POSTPASS
@@ -898,7 +958,19 @@ Shader "HDRP/Toon"
Tags { "LightMode" = "Outline" }
Cull Front
Blend SrcAlpha OneMinusSrcAlpha
ZWrite On
ZTest LEqual
// // NOTE: We disable taa and tau for outline because it can't provide motion vector. This will reduce the ghosting but introduce some jittering.
// // Worth it to write motion vector for outline? It will introduce additional drawcall.
// Stencil
// {
// WriteMask 3
// Ref 0
// Comp Always
// Pass Replace
// }
HLSLPROGRAM
@@ -1018,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
@@ -1070,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.
@@ -1120,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"
@@ -1151,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
@@ -1182,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

@@ -55,50 +55,49 @@ float Random(float2 uv)
return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453);
}
float unity_noise_interpolate (float a, float b, float t)
inline float2 voronoi_noise_random_vector (float2 UV, float offset)
{
return (1.0-t)*a + (t*b);
float2x2 m = float2x2(15.27, 47.63, 99.41, 89.98);
UV = frac(sin(mul(UV, m)) * 46839.32);
return float2(sin(UV.y*+offset)*0.5+0.5, cos(UV.x*offset)*0.5+0.5);
}
float ValueNoise (float2 uv)
float Voronoi(float2 UV, float AngleOffset, float CellDensity)
{
float2 i = floor(uv);
float2 f = frac(uv);
f = f * f * (3.0 - 2.0 * f);
float2 g = floor(UV * CellDensity);
float2 f = frac(UV * CellDensity);
float t = 8.0;
float res = 8.0;
uv = abs(frac(uv) - 0.5);
float2 c0 = i + float2(0.0, 0.0);
float2 c1 = i + float2(1.0, 0.0);
float2 c2 = i + float2(0.0, 1.0);
float2 c3 = i + float2(1.0, 1.0);
float r0 = Random(c0);
float r1 = Random(c1);
float r2 = Random(c2);
float r3 = Random(c3);
float bottomOfGrid = unity_noise_interpolate(r0, r1, f.x);
float topOfGrid = unity_noise_interpolate(r2, r3, f.x);
float t = unity_noise_interpolate(bottomOfGrid, topOfGrid, f.y);
return t;
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;
}
}
}
float SimpleNoise(float2 UV, float Scale)
return res;
}
float Dither(float In, float4 positionSS)
{
float t = 0.0;
float freq = pow(2.0, float(0));
float amp = pow(0.5, float(3-0));
t += ValueNoise(float2(UV.x*Scale/freq, UV.y*Scale/freq))*amp;
freq = pow(2.0, float(1));
amp = pow(0.5, float(3-1));
t += ValueNoise(float2(UV.x*Scale/freq, UV.y*Scale/freq))*amp;
freq = pow(2.0, float(2));
amp = pow(0.5, float(3-2));
t += ValueNoise(float2(UV.x*Scale/freq, UV.y*Scale/freq))*amp;
return t;
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))

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;

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;

View File

@@ -1,20 +1,23 @@
#ifndef UTS_SURFACE_FEATURE_EVALUATION
#define UTS_SURFACE_FEATURE_EVALUATION
void UtsEvaluateLighting_Stocking(FragInputs input, PositionInputs posInput, float3 normalWS, float3 V, inout AggregateLighting aggregateLighting)
void UtsEvaluateLighting_Stocking(FragInputs input, PositionInputs posInput, PreLightData preLightData, float3 N, float3 V, inout AggregateLighting aggregateLighting)
{
float NdotV = saturate(dot(normalize(V), normalWS));
float fresnel = pow(preLightData.NdotV, _StockingFresnelWidth);
NdotV = pow(NdotV, 2.0);
#if _STOCKING_SPARKING_MAP
float viewAngleFactor = saturate(1.0 - preLightData.NdotV);
float2 shiftedNDC = posInput.positionNDC.xy + viewAngleFactor * 0.05;
float spacing = (1.0 - posInput.linearDepth) * _StockingSparkleSpacing;
// TODO: Move sparkle to bsdf evaluation?
// float sparkle = Random(posInput.positionNDC.xy);
// sparkle = step(0.995, sparkle);
// float noise = SimpleNoise(posInput.positionNDC.xy, 500.0);
// sparkle = noise < sparkle ? 1.0 : 0.0;
// 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 *= NdotV;
// aggregateLighting.direct.specular = saturate(aggregateLighting.direct.specular + sparkle * (1.0 - NdotV) * 0.5);
aggregateLighting.direct.diffuse *= fresnel;
}
DirectLighting UtsEvaluateLighting_RimLight(PositionInputs posInput, UtsBSDFData bsdfData, PreLightData preLightData
@@ -55,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);
@@ -71,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

@@ -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);
}
@@ -245,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);
@@ -265,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);
@@ -274,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)
@@ -53,17 +34,6 @@ bool UtsUseScreenSpaceShadow(DirectionalLightData light, float3 normalWS)
#endif
}
bool IsNonZeroBSDF(float3 L, UtsBSDFData bsdfData)
{
#if _MATERIAL_TYPE_FACE
return true;
#else
float NdotL = dot(bsdfData.normalWS, L);
return NdotL > 0.0;
#endif
}
void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bsdfData, BuiltinData builtinData,
float3 V, uint featureFlags, out LightLoopOutput lightLoopOutput)
{
@@ -99,10 +69,10 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
// Is it worth sampling the shadow map?
// Should we skip it if NdotL is negative? (i.e. transmission)
if ((light.lightDimmer > 0) && (light.shadowDimmer > 0))
if ((light.lightDimmer > 0) && (light.shadowDimmer > 0) && IsNonZeroBSDF(L, bsdfData))
{
context.shadowValue = GetDirectionalShadowAttenuation(context.shadowContext,
posInput.positionSS, posInput.positionWS + L * _ShadowDistanceBias, UtsGetShadowNormal(bsdfData),
posInput.positionSS, posInput.positionWS + L * UtsGetShadowSlopeBias(bsdfData.normalWS, L), UtsGetShadowNormal(bsdfData),
light.shadowIndex, L);
}
}
@@ -226,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);
@@ -357,9 +327,10 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
#endif
}
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_STOCKING))
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_ANGEL_RING))
{
UtsEvaluateLighting_Stocking(fragInputs, posInput, bsdfData.normalWS, V, aggregateLighting);
DirectLighting lighting = UtsEvaluateLighting_AngelRing(fragInputs, bsdfData.normalWS, V);
AccumulateDirectLighting(lighting, aggregateLighting);
}
#ifndef _LIGHT_BASE_RIM_LIGHT_ON
@@ -370,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,6 +53,7 @@ float3 ComputeSpecularTerm(UtsBSDFData bsdfData, PreLightData preLightData, floa
DV = DV_SmithJointGGXAniso(TdotH, BdotH, NdotH, clampedNdotV, TdotL, BdotL, abs(NdotL), bsdfData.roughnessT, bsdfData.roughnessB, partLambdaV);
#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);
@@ -119,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
@@ -133,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
@@ -140,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(_ShadingRampMap, s_linear_clamp_sampler, float2(halfLambert * shadow.x, rampMask), _ShadingIndex).rgb;
float3 rampColor = SAMPLE_TEXTURE2D_ARRAY_LOD(_ShadingRampMap, s_linear_clamp_sampler, float2(halfLambert * sharpShadow.x, rampMask), _ShadingIndex, 0).rgb;
diffuseTerm = bsdfData.diffuseColor * rampColor * INV_PI;
specularTerm *= saturate(NdotL) * sharpShadow;
#elif _SHADING_MODE_SDF
float3 rampColor = SAMPLE_TEXTURE2D_ARRAY(_ShadingRampMap, s_linear_clamp_sampler, float2(sdfShadowMask * sharpShadow.x, rampMask), _ShadingIndex).rgb;
float3 rampColor = SAMPLE_TEXTURE2D_ARRAY_LOD(_ShadingRampMap, s_linear_clamp_sampler, float2(sdfShadowMask * sharpShadow.x, rampMask), _ShadingIndex, 0).rgb;
diffuseTerm = bsdfData.diffuseColor * rampColor * INV_PI;
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));

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,18 +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.0 - smoothstep(0.1, 0.9, cameraDirOS.y);
// shadowLength.y *= cameraDirFactor;
#if UNITY_UV_STARTS_AT_TOP
samplingPointSS.y = 1.0 - samplingPointSS.y;
#endif
// TODO: sample point is still shifting when fov change.
float2 samplingPoint = (posInput.positionSS + shadowLength * viewLightDir.xy) * _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 * _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 + _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);
}
@@ -77,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

@@ -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);

View File

@@ -2,6 +2,8 @@
float _SurfaceFeatures;
half _AlphaCutoffEnable;
float _AlphaCutoff;
half _BlendMode;
float4 _DoubleSidedConstants;
// Shading Color
float4 _BaseColor;
@@ -66,6 +68,8 @@ float _EnergyConservingSpecularColor;
float3 _EmissiveColor;
half _AlbedoAffectEmissive;
half _EmissiveExposureWeight;
float4 _EmissiveColorMap_ST;
half _TexWorldScaleEmissive;
float _ObjectSpaceUVMappingEmissive;
@@ -84,6 +88,13 @@ float _IndirectSpecularMatCapLod;
float _IndirectSpecularIntensity;
float _SSRWeight;
// Angle Ring
float4 _AngelRingColor;
float4 _AngelRingColorMap_ST;
float _AngelRingIntensity;
float _AngelRingOffsetU;
float _AngelRingOffsetV;
//Rim Light
float4 _RimLightColor;
float _RimLightIntensity;
@@ -94,12 +105,12 @@ float _RimLightClippingLevel;
float _LightDirectionRimLightLevel;
// Angle Ring
float4 _AngelRingColor;
float4 _AngelRingColorMap_ST;
float _AngelRingIntensity;
float _AngelRingOffsetU;
float _AngelRingOffsetV;
// Stocking
float _StockingFresnelWidth;
float _StockingSparkleSpacing;
float _StockingSparkleAmount;
float _StockingSparkleSize;
float _StockingSparkleIntensity;
// Outline
float _OutlineWidth;
@@ -125,10 +136,6 @@ 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;

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
@@ -87,34 +84,40 @@ void Frag(PackedVaryingsToPS packedInput,
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;
@@ -126,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

@@ -79,16 +79,7 @@ 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;
@@ -119,6 +110,10 @@ void Frag(PackedVaryingsToPS packedInput,
SurfaceData tempSurfaceData;
BuiltinData builtinData;
UtsGetSurfaceAndBuiltinData(input, V, posInput, tempSurfaceData, builtinData);
float3 doubleSidedConstants = GetDoubleSidedConstants();
ApplyDoubleSidedFlipOrMirror(input, doubleSidedConstants);
UTSSurfaceData surfaceData = GetUTSSurfaceData(input, V);
UtsBSDFData bsdfData = ConvertUTSSurfaceDataToUTSBSDFData(surfaceData);
@@ -154,6 +149,10 @@ void Frag(PackedVaryingsToPS packedInput,
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
outColor.rgb = 1;
#ifdef UTS_DEBUG_SELFSHADOW
@@ -177,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

@@ -127,9 +127,9 @@ namespace Misaki.HdrpToon
}
}
private bool ShouldReallocateHairShadowBuffer()
private static bool IsRTHandleValid(RTHandle rtHandle)
{
return _hairShadowRTHandle == null || _hairShadowRTHandle.rt == null || !_hairShadowRTHandle.rt.IsCreated() || _needReallocateHairShadow;
return rtHandle != null && rtHandle.rt != null && rtHandle.rt.IsCreated();
}
private void ReallocateHairShadowBuffer()
@@ -141,12 +141,11 @@ namespace Misaki.HdrpToon
}
#endif
// Use R8 or R16 directly?
var format = _hairShadowQuality switch
{
BufferQuality.Low => GraphicsFormat.D16_UNorm,
BufferQuality.High => GraphicsFormat.D32_SFloat,
_ => GraphicsFormat.R16G16B16A16_SFloat
_ => GraphicsFormat.D16_UNorm
};
_hairShadowRTHandle?.Release();
@@ -156,11 +155,6 @@ namespace Misaki.HdrpToon
_needReallocateHairShadow = false;
}
private bool ShouldReallocateHairBlendingBuffer()
{
return _hairBlendingRTHandle == null || _hairBlendingRTHandle.rt == null || !_hairBlendingRTHandle.rt.IsCreated() || _needReallocateHairBlending;
}
private void ReallocateHairBlendingBuffer()
{
#if UNITY_EDITOR
@@ -262,7 +256,7 @@ namespace Misaki.HdrpToon
return;
}
if (ShouldReallocateHairShadowBuffer())
if (!IsRTHandleValid(_hairShadowRTHandle) || _needReallocateHairShadow)
{
ReallocateHairShadowBuffer();
return;
@@ -272,14 +266,18 @@ 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.SetGlobalFloat(_HAIR_SHADOW_DISTANCE_PROP_NAME, utsRenderer.shadowDistance.value);
Shader.SetGlobalFloat(_HAIR_SHADOW_DISTANCE_SCALE_PROP_NAME, utsRenderer.shadowDistanceScale.value);
@@ -296,7 +294,7 @@ namespace Misaki.HdrpToon
return;
}
if (ShouldReallocateHairBlendingBuffer())
if (!IsRTHandleValid(_hairBlendingRTHandle) || _needReallocateHairBlending)
{
ReallocateHairBlendingBuffer();
return;
@@ -306,14 +304,18 @@ namespace Misaki.HdrpToon
{
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));
#if UNITY_6000_3_OR_NEWER
CoreUtils.DrawRendererList(ctx.cmd, ctx.renderContext.CreateRendererList(result));
#else
CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, ctx.renderContext.CreateRendererList(result, ctx.hdCamera));
#endif
}
}

View File

@@ -31,7 +31,7 @@ namespace Misaki.HdrpToon
targetDepthBuffer = CustomPass.TargetBuffer.None,
};
_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

@@ -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": "3.0.1-pre",
"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.4"
"com.misaki.shader-gui": "1.1.5"
}
}