36 Commits

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

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

Fixed the issue that diffuse bsdf is not energy conserving.
Fixed the bug that shader can not render alpha clip properly;
2025-05-15 16:07:54 +09:00
d19322b768 Fixed the engergy conservation problem when pbr mode is toon. 2025-05-13 21:35:52 +09:00
961db806e9 Added hair blending support. 2025-05-06 23:39:49 +09:00
10331b93ff Added new ramp diffuse ambient mode. 2025-05-06 00:01:08 +09:00
abdf6196ed Fixed the bug that alpha clip does not working properly; 2025-03-24 21:41:58 +09:00
410af63578 Merge pull request 'feature/properties-clean-up' (#3) from feature/properties-clean-up into release/3.0.0
Reviewed-on: #3
2025-03-24 12:36:54 +00:00
5a282e0812 Shader properties clean up; 2025-03-24 14:58:28 +09:00
b205c1523d Added AdvanceScope;
Added energy conservation to diffuse lighting;
Clean up shader properties;
2025-03-23 21:30:34 +09:00
ea3e83157c Added UtsSingleLightLoop 2025-03-23 17:53:36 +09:00
ee0b720b6d Added new Shadow SSS Lut;
Fixed the issue that SSGI and SSAO weight not works properly;
2025-03-17 00:02:46 +09:00
b2136e1ff4 Organized folder structure;
Added new SSS Lut Baker;
Removed old SubsurfaceLookupTextureIntegrator;
2025-03-16 15:13:06 +09:00
4ce84572d0 Shader code cleanupand bug fix. 2025-02-17 22:15:27 +09:00
eacbbc9b8b Organize folder structure;
Update RimLighting;
2025-02-04 21:21:44 +09:00
d44ff7d58c Merge branch 'release/3.0.0' of https://git.personalnas.com/Misaki/com.misaki.hdrp-toon into release/3.0.0 2025-02-03 23:02:10 +09:00
de370f845e Changing UI style;
Updating RImeLight;
2025-02-03 23:01:57 +09:00
3d06bb8129 Merge pull request 'Added UtsGetSurfaceAndBuiltinData to change metallic and smothness when PBR mode off;' (#2) from feature/custom-gbuffer into release/3.0.0
Reviewed-on: #2
Reviewed-by: Misaki <misaki_39@outlook.com>
2025-02-03 11:38:17 +00:00
680ebb72e5 Remove BOM; 2025-02-03 19:35:38 +08:00
74263900ac Added UtsGetSurfaceAndBuiltinData to change metallic and smothness when PBR mode off; 2025-02-03 19:17:25 +08:00
886432db7b Updated OutlineScope;
Reorgnize shader code;
2025-02-03 13:46:31 +09:00
281dfbc4f0 Improve AmbientScope and OutlineScope 2025-02-02 17:04:05 +09:00
ecd0cfdb9f Added AmbientScope; 2025-02-01 23:34:34 +08:00
3273812902 Added ShadowScope;
Renamed PBRScope to SurfaceInputsScope;
2025-02-01 20:51:22 +09:00
Misaki
458afd880f Update dependency 2025-02-01 14:45:04 +09:00
Misaki
a9b989fb19 Update ShadingColorScope; 2025-02-01 14:44:23 +09:00
111 changed files with 3989 additions and 2707 deletions

View File

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

74
.gitignore vendored
View File

@@ -1,74 +0,0 @@
# ---> Unity
# This .gitignore file should be placed at the root of your Unity project directory
#
# Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore
#
/[Ll]ibrary/
/[Tt]emp/
/[Oo]bj/
/[Bb]uild/
/[Bb]uilds/
/[Ll]ogs/
/[Uu]ser[Ss]ettings/
# MemoryCaptures can get excessive in size.
# They also could contain extremely sensitive data
/[Mm]emoryCaptures/
# Recordings can get excessive in size
/[Rr]ecordings/
# Uncomment this line if you wish to ignore the asset store tools plugin
# /[Aa]ssets/AssetStoreTools*
# Autogenerated Jetbrains Rider plugin
/[Aa]ssets/Plugins/Editor/JetBrains*
# Visual Studio cache directory
.vs/
# Gradle cache directory
.gradle/
# Autogenerated VS/MD/Consulo solution and project files
ExportedObj/
.consulo/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
*.pdb
*.mdb
*.opendb
*.VC.db
# Unity3D generated meta files
*.pidb.meta
*.pdb.meta
*.mdb.meta
# Unity3D generated file on crash reports
sysinfo.txt
# Builds
*.apk
*.aab
*.unitypackage
*.app
# Crashlytics generated file
crashlytics-build.properties
# Packed Addressables
/[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin*
# Temporary auto-generated Android Assets
/[Aa]ssets/[Ss]treamingAssets/aa.meta
/[Aa]ssets/[Ss]treamingAssets/aa/*

View File

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

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

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

View File

@@ -0,0 +1,55 @@
using UnityEngine;
using static Misaki.HdrpToon.UTSPropertyName;
namespace Misaki.HdrpToon.Editor
{
internal static class MaterialHelpers
{
public static ShadingMode GetShadingMode(this Material material)
{
if (!material.HasProperty(SurfaceOptions.SHADING_MODE))
{
return ShadingMode.Standard;
}
return (ShadingMode)material.GetInteger(SurfaceOptions.SHADING_MODE);
}
public static PBRMode GetPBRMode(this Material material)
{
if (!material.HasProperty(SurfaceOptions.PBR_MODE))
{
return PBRMode.Off;
}
return (PBRMode)material.GetInteger(SurfaceOptions.PBR_MODE);
}
public static MaterialType GetMaterialType(this Material material)
{
if (!material.HasProperty(SurfaceOptions.MATERIAL_TYPE))
{
return MaterialType.Standard;
}
return (MaterialType)material.GetInteger(SurfaceOptions.MATERIAL_TYPE);
}
public static bool HasFeature(this Material material, SurfaceFeature feature)
{
if (!material.HasProperty(SurfaceOptions.SURFACE_FEATURE))
{
return false;
}
var value = (SurfaceFeature)material.GetInteger(SurfaceOptions.SURFACE_FEATURE);
return (value & feature) != 0;
}
public static bool IsHairBlendingTarget(this Material material)
{
return material.GetShaderPassEnabled(UTSPassName.HAIR_BLENDING_TARGET_PASS_NAME);
}
}
}

View File

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

View File

@@ -4,20 +4,15 @@ namespace Misaki.HdrpToon.Editor
{
SurfaceOptions = 1 << 0,
ShadingColor = 1 << 1,
ShadingGrade = 1 << 2,
MaterialFeature = 1 << 3,
PBR = 1 << 4,
AmbientMode = 1 << 5,
Highlight = 1 << 6,
Rimlight = 1 << 7,
MatCap = 1 << 8,
AngelRing = 1 << 9,
Emission = 1 << 10,
Outline = 1 << 11,
TessellationLegacy = 1 << 12,
TessellationHDRP = 1 << 13,
SceneLight = 1 << 14,
EnvironmentalLightEffectiveness = 1 << 15,
MetaverseSettings = 1 << 16,
Shadow = 1 << 2,
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

@@ -0,0 +1,55 @@
using Misaki.ShaderGUI;
using UnityEditor;
using UnityEngine;
using static Misaki.HdrpToon.UTSPropertyName.Advance;
namespace Misaki.HdrpToon.Editor
{
internal class AdvanceScope : MaterialUIScope<ShaderGUIExpandable>
{
private static class Properties
{
public static MaterialProperty diffuseMin;
public static MaterialProperty lightIntensityMultiplier;
public static MaterialProperty clampLightColor;
public static MaterialProperty lightLoopMode;
}
private static class Styles
{
public static readonly GUIContent diffuseMinText = new("Minimal Diffuse Contribution", "Specifies the minimum contribution of the base color to the diffuse light. Keep it 0 to make sure energy conservation.");
public static readonly GUIContent lightIntensityMultiplierText = new("Light Intensity Multiplier", "Specifies the intensity multiplier of the light.");
public static readonly GUIContent clampLightColorText = new("Clamp Light Color", "Specifies whether to clamp the light color.");
public static readonly GUIContent lightLoopModeText = new("Light Loop Mode", "Specifies the light loop mode.");
}
protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.Advance;
protected override GUIContent Header => EditorGUIUtility.TrTextContent("Advance Settings");
protected override void LoadMaterialProperties()
{
Properties.diffuseMin = FindProperty(MINIMAL_DIFFUSE_CONTRIBUTION);
Properties.lightIntensityMultiplier = FindProperty(LIGHT_INTENSITY_MULTIPLIER);
Properties.clampLightColor = FindProperty(CLAMP_LIGHT_COLOR);
Properties.lightLoopMode = FindProperty(LIGHT_LOOP_MODE);
}
protected override void DrawContent()
{
editor.ShaderProperty(Properties.diffuseMin, Styles.diffuseMinText);
editor.ShaderProperty(Properties.lightIntensityMultiplier, Styles.lightIntensityMultiplierText);
editor.ShaderProperty(Properties.clampLightColor, Styles.clampLightColorText);
editor.ShaderProperty(Properties.lightLoopMode, Styles.lightLoopModeText);
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 3acfee7f0a1007e4bb2a3b42a6282d52

View File

@@ -0,0 +1,156 @@
using Misaki.ShaderGUI;
using UnityEditor;
using UnityEngine;
namespace Misaki.HdrpToon.Editor
{
internal class AmbientScope : MaterialUIScope<ShaderGUIExpandable>
{
protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.Ambient;
protected override GUIContent Header => new("Ambient Settings");
private static class Properties
{
public static MaterialProperty indirectDiffuseMode;
public static MaterialProperty indirectSpecularMode;
public static MaterialProperty indirectDiffuseMatCapMap;
public static MaterialProperty indirectDiffuseMatCapLod;
public static MaterialProperty indirectDiffuseRampMap;
public static MaterialProperty indirectDiffuseRampIndex;
public static MaterialProperty indirectDiffuseRampPosition;
public static MaterialProperty indirectDiffuseIntensity;
public static MaterialProperty ssaoWeight;
public static MaterialProperty ssgiWeight;
public static MaterialProperty indirectSpecularMatCapMap;
public static MaterialProperty indirectSpecularMatCapLod;
public static MaterialProperty indirectReflectionIntensity;
public static MaterialProperty ssrWeight;
}
private static class Styles
{
public static readonly GUIContent indirectDiffuseModeText = new("Indirect Diffuse Mode", "Specifies indirect diffuse mode.");
public static readonly GUIContent indirectSpecularModeText = new("Indirect Specular Mode", "Specifies indirect specular mode.");
public static readonly GUIContent indirectDiffuseMatCapMapText = new("MatCap Map", "The material capture map for indirect diffuse evaluation, with the additional setting for controlling the LOD offset when sampling the indirect diffuse material capture map.");
public static readonly GUIContent indirectDiffuseRampMapText = new("Ramp Map", "The ramp map for indirect diffuse evaluation, with the additional setting for controlling the sampling index of the ramp map.");
public static readonly GUIContent indirectDiffuseRampPositionText = new("Ramp Position", "The ramp position for indirect diffuse evaluation.");
public static readonly GUIContent indirectDiffuseIntensityText = new("Intensity", "The indirect diffuse color is added to the material color according to the intensity value.");
public static readonly GUIContent ssaoWeightText = new("SSAO Weight", "The weight of SSAO.");
public static readonly GUIContent ssgiWeightText = new("SSGI Weight", "The weight of SSGI.");
public static readonly GUIContent indirectSpecularMatCapMapText = new("MatCap Map", "The material capture map for indirect specular evaluation, with the additional setting for controlling the LOD offset when sampling the indirect specular material capture map.");
public static readonly GUIContent indirectReflectionIntensityText = new("Intensity", "The indirect reflection color is added to the material color according to the intensity value.");
public static readonly GUIContent ssrWeightText = new("SSR Weight", "SSR Weight");
}
protected override void LoadMaterialProperties()
{
Properties.indirectDiffuseMode = FindProperty("_Indirect_Diffuse_Mode");
Properties.indirectSpecularMode = FindProperty("_Indirect_Specular_Mode");
Properties.indirectDiffuseMatCapMap = FindProperty("_IndirectDiffuseMatCapMap");
Properties.indirectDiffuseMatCapLod = FindProperty("_IndirectDiffuseMatCapLod");
Properties.indirectDiffuseRampMap = FindProperty("_IndirectDiffuseRampMap");
Properties.indirectDiffuseRampIndex = FindProperty("_IndirectDiffuseRampIndex");
Properties.indirectDiffuseRampPosition = FindProperty("_IndirectDiffuseRampPosition");
Properties.indirectDiffuseIntensity = FindProperty("_IndirectDiffuseIntensity");
Properties.ssaoWeight = FindProperty("_SSAOWeight");
Properties.ssgiWeight = FindProperty("_SSGIWeight");
Properties.indirectSpecularMatCapMap = FindProperty("_IndirectSpecularMatCapMap");
Properties.indirectSpecularMatCapLod = FindProperty("_IndirectSpecularMatCapLod");
Properties.indirectReflectionIntensity = FindProperty("_IndirectSpecularIntensity");
Properties.ssrWeight = FindProperty("_SSRWeight");
}
private static void DrawIndirectDiffuseHeader()
{
EditorGUILayout.Space();
using var indentLevelScope = new EditorGUI.IndentLevelScope(-1);
EditorGUILayout.LabelField("Indirect Diffuse", EditorStyles.boldLabel);
}
private void DrawIndirectDiffuseProperties()
{
EditorGUILayout.Space();
editor.ShaderProperty(Properties.indirectDiffuseIntensity, Styles.indirectDiffuseIntensityText);
editor.ShaderProperty(Properties.ssaoWeight, Styles.ssaoWeightText);
}
private void DrawIndirectSpecularProperties()
{
EditorGUILayout.Space();
editor.ShaderProperty(Properties.indirectReflectionIntensity, Styles.indirectReflectionIntensityText);
editor.ShaderProperty(Properties.ssrWeight, Styles.ssrWeightText);
}
private static void DrawIndirectSpecularHeader()
{
EditorGUILayout.Space();
using var indentLevelScope = new EditorGUI.IndentLevelScope(-1);
EditorGUILayout.LabelField("Indirect Specular", EditorStyles.boldLabel);
}
protected override void DrawContent()
{
editor.ShaderProperty(Properties.indirectDiffuseMode, Styles.indirectDiffuseModeText);
editor.ShaderProperty(Properties.indirectSpecularMode, Styles.indirectSpecularModeText);
var indirectDiffuseMode = Properties.indirectDiffuseMode.GetEnumValue<IndirectDiffuseMode>();
var indirectSpecularMode = Properties.indirectSpecularMode.GetEnumValue<IndirectSpecularMode>();
if (indirectDiffuseMode != IndirectDiffuseMode.Off)
{
DrawIndirectDiffuseHeader();
switch (indirectDiffuseMode)
{
case IndirectDiffuseMode.IBL:
editor.ShaderProperty(Properties.ssgiWeight, Styles.ssgiWeightText);
break;
case IndirectDiffuseMode.Matcap:
editor.TexturePropertySingleLine(Styles.indirectDiffuseMatCapMapText, Properties.indirectDiffuseMatCapMap, Properties.indirectDiffuseMatCapLod);
break;
case IndirectDiffuseMode.Ramp:
editor.TexturePropertySingleLine(Styles.indirectDiffuseRampMapText, Properties.indirectDiffuseRampMap, Properties.indirectDiffuseRampIndex);
editor.ShaderProperty(Properties.indirectDiffuseRampPosition, Styles.indirectDiffuseRampPositionText);
break;
default:
break;
}
DrawIndirectDiffuseProperties();
}
if (indirectSpecularMode != IndirectSpecularMode.Off)
{
DrawIndirectSpecularHeader();
switch (indirectSpecularMode)
{
case IndirectSpecularMode.IBL:
break;
case IndirectSpecularMode.Matcap:
editor.TexturePropertySingleLine(Styles.indirectSpecularMatCapMapText, Properties.indirectSpecularMatCapMap, Properties.indirectSpecularMatCapLod);
break;
default:
break;
}
DrawIndirectSpecularProperties();
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0f3997bcef824e5a9bd3728830006bd1
timeCreated: 1738419718

View File

@@ -1,7 +1,10 @@
using Misaki.ShaderGUI;
using System.Linq;
using UnityEditor;
using UnityEngine;
using static Misaki.HdrpToon.UTSPropertyName.AngelRing;
namespace Misaki.HdrpToon.Editor
{
internal class AngelRingScope : MaterialUIScope<ShaderGUIExpandable>
@@ -23,19 +26,19 @@ namespace Misaki.HdrpToon.Editor
public static readonly GUIContent angelRingOffsetVText = new("Angel Ring Offset V", "Specifies the offset of the angel ring in the V direction.");
}
protected override bool ShowSection => SurfaceOptionsScope.HasFeature(SurfaceFeatureFlags.AngelRing);
protected override bool ShowSection => materials.All(mat => mat.HasFeature(SurfaceFeature.AngelRing));
protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.AngelRing;
protected override GUIContent Header => EditorGUIUtility.TrTextContent("Angel Ring Settings");
public override void LoadMaterialProperties()
protected override void LoadMaterialProperties()
{
Properties.angelRingColor = FindProperty("_AngelRingColor");
Properties.angelRingColorMap = FindProperty("_AngelRingColorMap");
Properties.angelRingIntensity = FindProperty("_AngelRingIntensity");
Properties.angelRingOffsetU = FindProperty("_AngelRingOffsetU");
Properties.angelRingOffsetV = FindProperty("_AngelRingOffsetV");
Properties.angelRingColor = FindProperty(ANGEL_RING_COLOR);
Properties.angelRingColorMap = FindProperty(ANGEL_RING_COLOR_MAP);
Properties.angelRingIntensity = FindProperty(ANGEL_RING_INTENSITY);
Properties.angelRingOffsetU = FindProperty(ANGEL_RING_OFFSET_U);
Properties.angelRingOffsetV = FindProperty(ANGEL_RING_OFFSET_V);
}
protected override void DrawContent()

View File

@@ -1,19 +1,27 @@
using Misaki.ShaderGUI;
using System.Linq;
using UnityEditor;
using UnityEngine;
using static Misaki.HdrpToon.UTSPropertyName.Outline;
using static UnityEditor.EditorGUI;
namespace Misaki.HdrpToon.Editor
{
internal class OutlineScope : MaterialUIScope<ShaderGUIExpandable>
{
private static class Properties
{
public static MaterialProperty outlineState;
public static MaterialProperty outlineWidth;
public static MaterialProperty outlineWidthMap;
public static MaterialProperty outlineColor;
public static MaterialProperty outlineColorMap;
public static MaterialProperty albedoAffectOutline;
public static MaterialProperty skyColorAffectOutline;
public static MaterialProperty skyColorIntensity;
public static MaterialProperty fadeIn;
public static MaterialProperty fadeOut;
@@ -23,43 +31,72 @@ namespace Misaki.HdrpToon.Editor
private static class Styles
{
public static readonly GUIContent outlineStateText = new("Outline State", "Enable the outline pass for this material instance.");
public static readonly GUIContent outlineWidthText = new("Outline Width", "Specifies the width of the outline.");
public static readonly GUIContent outlineColorText = new("Outline Color", "Specifies the color of the outline.");
public static readonly GUIContent albedoAffectOutlineText = new("Albedo Affect Outline", "Enable to affect the outline color with the albedo color.");
public static readonly GUIContent skyColorAffectOutlineText = new("Sky Color Affect Outline", "Enable to affect the outline color with the sky color.");
public static readonly GUIContent skyColorIntensityText = new("Sky Color Intensity", "The intensity of the sky color when add to the outline color.");
public static readonly GUIContent fadeInText = new("Fade In Distance", "Specify the nearest distance, where the outline width changes with the distance between the camera and the object. The outline will be the maximum width at this distance.");
public static readonly GUIContent fadeOutText = new("Fade Out Distance", "Specify the furthest distance, where the outline width changes with the distance between the camera and the object. The outline will be zero at this distance.");
public static readonly GUIContent useSmoothedNormalText = new("Use Smoothed Normal", "Enable to use smoothed normal(that packed in uv2) for outline calculation.");
}
protected override bool ShowSection => SurfaceOptionsScope.HasFeature(SurfaceFeatureFlags.Outline);
protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.Outline;
protected override GUIContent Header => EditorGUIUtility.TrTextContent("Outline Settings");
public override void LoadMaterialProperties()
protected override void LoadMaterialProperties()
{
Properties.outlineWidth = FindProperty("_OutlineWidth");
Properties.outlineWidthMap = FindProperty("_OutlineWidthMap");
Properties.outlineState = FindProperty(OUTLINE_STATE);
Properties.outlineColor = FindProperty("_OutlineColor");
Properties.outlineColorMap = FindProperty("_OutlineColorMap");
Properties.albedoAffectOutline = FindProperty("_AlbedoAffectOutline");
Properties.outlineWidth = FindProperty(OUTLINE_WIDTH);
Properties.outlineWidthMap = FindProperty(OUTLINE_WIDTH_MAP);
Properties.fadeIn = FindProperty("_OutlineFadeIn");
Properties.fadeOut = FindProperty("_OutlineFadeOut");
Properties.outlineColor = FindProperty(OUTLINE_COLOR);
Properties.outlineColorMap = FindProperty(OUTLINE_COLOR_MAP);
Properties.albedoAffectOutline = FindProperty(ALBEDO_AFFECT_OUTLINE);
Properties.skyColorAffectOutline = FindProperty(SKY_COLOR_AFFECT_OUTLINE);
Properties.skyColorIntensity = FindProperty(SKY_COLOR_INTENSITY);
Properties.useSmoothedNormal = FindProperty("_UseSmoothedNormal");
Properties.fadeIn = FindProperty(OUTLINE_FADE_IN);
Properties.fadeOut = FindProperty(OUTLINE_FADE_OUT);
Properties.useSmoothedNormal = FindProperty(USE_SMOOTHED_NORMAL);
}
protected override void DrawContent()
{
editor.ShaderProperty(Properties.outlineState, Styles.outlineStateText);
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);
editor.ShaderProperty(Properties.albedoAffectOutline, Styles.albedoAffectOutlineText);
editor.ShaderProperty(Properties.skyColorAffectOutline, Styles.skyColorAffectOutlineText);
if (Properties.skyColorAffectOutline.GetBooleanValue())
{
using var skyColorIndentLevelScope = new EditorGUI.IndentLevelScope();
editor.ShaderProperty(Properties.skyColorIntensity, Styles.skyColorIntensityText);
}
EditorGUILayout.Space();
editor.ShaderProperty(Properties.fadeIn, Styles.fadeInText);
editor.ShaderProperty(Properties.fadeOut, Styles.fadeOutText);
editor.ShaderProperty(Properties.useSmoothedNormal, Styles.useSmoothedNormalText);
}
}
}
}

View File

@@ -1,224 +0,0 @@
using System.Linq;
using Misaki.ShaderGUI;
using UnityEditor;
using UnityEditor.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
namespace Misaki.HdrpToon.Editor
{
public class PBRScope : MaterialUIScope<ShaderGUIExpandable>
{
private static class Properties
{
public static MaterialProperty PbrMode;
public static MaterialProperty NormalMap;
public static MaterialProperty NormalMapScale;
public static MaterialProperty MaskMap;
public static MaterialProperty Metallic;
public static MaterialProperty MetallicRemapMin;
public static MaterialProperty MetallicRemapMax;
public static MaterialProperty AORemapMin;
public static MaterialProperty AORemapMax;
public static MaterialProperty RoughnessRemapMin;
public static MaterialProperty RoughnessRemapMax;
public static MaterialProperty Smoothness;
public static MaterialProperty AnisotropyMap;
public static MaterialProperty Anisotropy;
public static MaterialProperty KKColor;
public static MaterialProperty BSDFContribution;
public static MaterialProperty SpecularColorMap;
public static MaterialProperty SpecularColor;
public static MaterialProperty SpecularFeather;
public static MaterialProperty SpecularStep;
}
private static class Styles
{
public static readonly GUIContent PbrModeText = new("PBR Mode", "PBR Mode");
public static readonly GUIContent NormalMapText =
new("Normal Map", "A texture that dictates the bumpiness of the material.");
public static readonly GUIContent MaskMapText = new("Mask Map",
"A texture that dictates the physical properties of the material. R: Metallic, G: Occlusion, A: Smoothness");
public static readonly GUIContent MetallicText =
new("Metallic", "Specifies the metallicness of the material.");
public static readonly GUIContent MetallicRemap =
new("Metallic Remap", "Remap the max and min value of metallic");
public static readonly GUIContent AORemap =
new GUIContent("AO Remap", "Remap the max and min value of ambient occlusion");
public static readonly GUIContent RoughnessRemap =
new GUIContent("Smoothness Remap", "Remap the max and min value of smoothness");
public static readonly GUIContent SmoothnessText =
new("Smoothness", "Specifies the smoothness of the material.");
public static readonly GUIContent AnisotropyMapText =
new("Anisotropy Map", "Specifies the anisotropy map of the material.");
public static readonly GUIContent KKColorText = new("KK specular Color",
"Specifies the color of KK specular.");
public static readonly GUIContent BSDFContributionText = new("BSDF Contribution",
"BSDF smoothness contribution, 1 means KK Hair smoothness will fully contribute bsdf calculation");
public static readonly GUIContent SpecularColorMapText = new("Specular Color Map",
"Specifies the specular color map of the material.");
public static readonly GUIContent SpecRemap = new("Specular Remap",
"Feather and step value of Toon Specular");
}
public override void LoadMaterialProperties()
{
Properties.PbrMode = FindProperty("_PBR_Mode");
Properties.NormalMap = FindProperty("_NormalMap");
Properties.NormalMapScale = FindProperty("_NormalScale");
Properties.MaskMap = FindProperty("_MaskMap");
Properties.Metallic = FindProperty("_Metallic");
Properties.MetallicRemapMin = FindProperty("_MetallicRemapMin");
Properties.MetallicRemapMax = FindProperty("_MetallicRemapMax");
Properties.AORemapMin = FindProperty("_AORemapMin");
Properties.AORemapMax = FindProperty("_AORemapMax");
Properties.RoughnessRemapMin = FindProperty("_SmoothnessRemapMin");
Properties.RoughnessRemapMax = FindProperty("_SmoothnessRemapMax");
Properties.Smoothness = FindProperty("_Smoothness");
Properties.AnisotropyMap = FindProperty("_AnisotropyMap");
Properties.Anisotropy = FindProperty("_Anisotropy");
Properties.KKColor = FindProperty("_KKColor");
Properties.BSDFContribution = FindProperty("_BSDFContribution");
Properties.SpecularColorMap = FindProperty("_SpecularColorMap");
Properties.SpecularColor = FindProperty("_SpecularColor");
Properties.SpecularFeather = FindProperty("_ToonSpecularFeather");
Properties.SpecularStep = FindProperty("_ToonSpecularStep");
}
protected override void DrawContent()
{
editor.ShaderProperty(Properties.PbrMode, Styles.PbrModeText);
EditorGUILayout.Space();
editor.TexturePropertySingleLine(Styles.NormalMapText, Properties.NormalMap, Properties.NormalMapScale);
var materials = GetMaterials().ToList();
foreach (Material material in materials)
{
material.SetKeyword(new LocalKeyword(material.shader, "_NORMAL_MAP"),
Properties.NormalMap.textureValue != null);
}
PBRMode pbrMode = (PBRMode)Properties.PbrMode.floatValue;
if (pbrMode != PBRMode.Off)
{
editor.TexturePropertySingleLine(Styles.MaskMapText, Properties.MaskMap);
if (Properties.MaskMap.textureValue == null)
{
foreach (Material material in materials)
{
material.DisableKeyword(new LocalKeyword(material.shader, "_MASK_MAP"));
}
if (pbrMode != PBRMode.KKHair)
editor.ShaderProperty(Properties.Metallic, Styles.MetallicText);
editor.ShaderProperty(Properties.Smoothness, Styles.SmoothnessText);
}
else
{
foreach (Material material in materials)
{
material.EnableKeyword(new LocalKeyword(material.shader, "_MASK_MAP"));
}
editor.MinMaxShaderProperty(Properties.MetallicRemapMin, Properties.MetallicRemapMax, 0, 1,
Styles.MetallicRemap);
editor.MinMaxShaderProperty(Properties.AORemapMin, Properties.AORemapMax, 0, 1, Styles.AORemap);
editor.MinMaxShaderProperty(Properties.RoughnessRemapMin, Properties.RoughnessRemapMax, 0, 1,
Styles.RoughnessRemap);
}
}
else
{
foreach (Material material in materials)
{
material.DisableKeyword(new LocalKeyword(material.shader, "_MASK_MAP"));
material.DisableKeyword(new LocalKeyword(material.shader, "_ANISOTROPY_MAP"));
material.DisableKeyword(new LocalKeyword(material.shader, "_SPECULAR_COLOR_MAP"));
}
}
switch (pbrMode)
{
case PBRMode.Anisotropy or PBRMode.KKHair:
{
editor.TexturePropertySingleLine(Styles.AnisotropyMapText, Properties.AnisotropyMap,
Properties.Anisotropy);
if (pbrMode == PBRMode.KKHair)
{
editor.ShaderProperty(Properties.KKColor, Styles.KKColorText);
editor.ShaderProperty(Properties.BSDFContribution, Styles.BSDFContributionText);
}
EditorGUILayout.Space();
EditorGUILayout.LabelField("Anisotropy Map only ST");
editor.TextureScaleOffsetProperty(Properties.AnisotropyMap);
if (Properties.AnisotropyMap.textureValue == null)
{
foreach (Material material in materials)
{
material.DisableKeyword(new LocalKeyword(material.shader, "_ANISOTROPY_MAP"));
}
}
else
{
foreach (Material material in materials)
{
material.EnableKeyword(new LocalKeyword(material.shader, "_ANISOTROPY_MAP"));
}
}
break;
}
case PBRMode.Toon:
{
editor.TexturePropertySingleLine(Styles.SpecularColorMapText, Properties.SpecularColorMap,
Properties.SpecularColor);
if (Properties.SpecularColorMap.textureValue == null)
{
foreach (Material material in materials)
{
material.DisableKeyword(new LocalKeyword(material.shader, "_SPECULAR_COLOR_MAP"));
}
}
else
{
foreach (Material material in materials)
{
material.EnableKeyword(new LocalKeyword(material.shader, "_SPECULAR_COLOR_MAP"));
}
}
editor.MinMaxShaderProperty(Properties.SpecularFeather, Properties.SpecularStep, 0, 1,
Styles.SpecRemap);
break;
}
}
}
private enum PBRMode
{
Off,
Standard,
Anisotropy,
KKHair,
Toon
}
protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.PBR;
protected override GUIContent Header => new("PBR Settings");
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: f611f3d462b5414f9241ed80e4f1d0bb
timeCreated: 1738325165

View File

@@ -1,142 +1,88 @@
using Misaki.ShaderGUI;
using System.Linq;
using UnityEditor;
using UnityEngine;
using static Misaki.HdrpToon.UTSPropertyName.RimLight;
namespace Misaki.HdrpToon.Editor
{
public class RimLightScope : MaterialUIScope<ShaderGUIExpandable>
internal class RimLightScope : MaterialUIScope<ShaderGUIExpandable>
{
private static class Properties
{
public static MaterialProperty rimLightEnabled;
public static MaterialProperty rimLightColor;
public static MaterialProperty rimLightStrength;
public static MaterialProperty rimLightIntensity;
public static MaterialProperty albedoAffectRimLight;
public static MaterialProperty screenSpaceRimLight;
public static MaterialProperty rimLightLevel;
public static MaterialProperty colorBlendingMode;
public static MaterialProperty adjustRimLightArea;
public static MaterialProperty rimLightFeatherOff;
public static MaterialProperty lightDirection;
public static MaterialProperty rimLightClipping;
public static MaterialProperty rimLightClippingLevel;
public static MaterialProperty lightBaseRimLight;
public static MaterialProperty lightDirectionRimLightLevel;
public static MaterialProperty invertedDirectionRimLight;
public static MaterialProperty invertedRimLightColor;
public static MaterialProperty inversedRimLightLevel;
public static MaterialProperty invertedRimLightFeatherOff;
public static MaterialProperty rimLightMaskMap;
public static MaterialProperty rimLightMaskLevel;
}
private static class Styles
{
public static readonly GUIContent rimLightEnabledText = new("Rim Light",
"A light that hits the 3D model from behind and emphasizes the contours of the model from the front.");
public static readonly GUIContent rimLightColorText = new("Rim Light Color", "Specifies the color of rim light.");
public static readonly GUIContent rimLightIntensityText = new("Rim Light Strength", "Specifies Rim Light strength.");
public static readonly GUIContent rimLightColorText =
new("Rim Light Color", "Specifies the color of rim light.");
public static readonly GUIContent albedoAffectRimLightText = new("Albedo Affect Rim Light", "Enable to let the albedo color affect the rim light color. The alpha channel of rim light color will be the blending weight.");
public static readonly GUIContent screenSpaceRimLightText = new("Screen Space Rim Light", "Enable to make the rim light width constant in screen space.");
public static readonly GUIContent rimLightLevelText = new("Rim Light Level", "Specifies Rim Light power intensity.");
public static readonly GUIContent rimLightClippingText = new("Rim Light Clipping", "Enable to Clip the rim light at specific level");
public static readonly GUIContent rimLightClippingLevelText = new("Clipping Level", "The Clipping value of the rim light.");
public static readonly GUIContent rimLightStrengthText =
new("Rim Light Strength", "Specifies Rim Light strength.");
public static readonly GUIContent rimLightLevelText =
new("Rim Light Level", "Specifies Rim Light power intensity.");
public static readonly GUIContent colorBlendingModeText =
new("Color Blending Mode", "Rim light color blending mode. Multiply or Add.");
public static readonly GUIContent adjustRimLightAreaText =
new("Adjust Rim Light Area", "Increasing this value narrows the area of influence of Rim Light.");
public static readonly GUIContent rimLightFeatherOffText =
new("Rim Light Feather Off", "Disable Rim light feather.");
public static readonly GUIContent lightDirectionText =
new("Light Direction",
"When Enabled, rim light is generated only in the direction of the light source.");
public static readonly GUIContent lightDirectionRimLightLevelText =
new("Light Direction Rim Light Level",
"Specifies intensity of Rim Light in the light source direction,");
public static readonly GUIContent invertedDirectionRimLightText =
new("Inverted Direction Rim Light", "Rim light from inverted/antipodean direction.");
public static readonly GUIContent invertedRimLightColorText =
new("Inverted Rim Light Color", "Specifies the color of inverted/antipodean rim light.");
public static readonly GUIContent inversedRimLightLevelText =
new("Inversed Rim Light Level", "Specifies Inverted/Antipodean Rim Light Level.");
public static readonly GUIContent invertedRimLightFeatherOffText =
new("Inverted Rim Light Feather Off", "Disable Inverted Rim light feather.");
public static readonly GUIContent rimLightMaskMapText = new("Rim Light Mask",
"Rim Light Mask : Texture(linear). The white part of the texture is displayed as Rim Light, and the black part is masked and not displayed.");
public static readonly GUIContent rimLightMaskLevelText =
new("Rim Light Mask Level",
"-1 gives 0% for the Rim Light effect, 0 gives 100% for the Rim Light and Mask effect, 1 gives 100% for the Rim Light and 0% for the Mask effect.");
}
public override void LoadMaterialProperties()
{
Properties.rimLightEnabled = FindProperty("_RimLight");
Properties.rimLightColor = FindProperty("_RimLightColor");
Properties.rimLightStrength = FindProperty("_RimLight_Strength");
Properties.rimLightLevel = FindProperty("_RimLight_Power");
Properties.colorBlendingMode = FindProperty("_Is_BlendAddToRimColor");
Properties.adjustRimLightArea = FindProperty("_RimLight_InsideMask");
Properties.rimLightFeatherOff = FindProperty("_RimLight_FeatherOff");
Properties.lightDirection = FindProperty("_LightDirection_MaskOn");
Properties.lightDirectionRimLightLevel = FindProperty("_Tweak_LightDirection_MaskLevel");
Properties.invertedDirectionRimLight = FindProperty("_Add_Antipodean_RimLight");
Properties.invertedRimLightColor = FindProperty("_Ap_RimLightColor");
Properties.inversedRimLightLevel = FindProperty("_Ap_RimLight_Power");
Properties.invertedRimLightFeatherOff = FindProperty("_Ap_RimLight_FeatherOff");
Properties.rimLightMaskMap = FindProperty("_Set_RimLightMask");
Properties.rimLightMaskLevel = FindProperty("_Tweak_RimLightMaskLevel");
}
protected override void DrawContent()
{
editor.ShaderProperty(Properties.rimLightEnabled, Styles.rimLightEnabledText);
EditorGUI.BeginDisabledGroup(Properties.rimLightEnabled.floatValue == 0);
{
EditorGUI.indentLevel++;
editor.ShaderProperty(Properties.rimLightColor, Styles.rimLightColorText);
editor.ShaderProperty(Properties.rimLightStrength, Styles.rimLightStrengthText);
editor.ShaderProperty(Properties.rimLightLevel, Styles.rimLightLevelText);
editor.ShaderProperty(Properties.colorBlendingMode, Styles.colorBlendingModeText);
editor.ShaderProperty(Properties.adjustRimLightArea, Styles.adjustRimLightAreaText);
editor.ShaderProperty(Properties.rimLightFeatherOff, Styles.rimLightFeatherOffText);
editor.ShaderProperty(Properties.lightDirection, Styles.lightDirectionText);
EditorGUI.BeginDisabledGroup(Properties.lightDirection.floatValue == 0);
{
EditorGUI.indentLevel++;
editor.ShaderProperty(Properties.lightDirectionRimLightLevel,
Styles.lightDirectionRimLightLevelText);
editor.ShaderProperty(Properties.invertedDirectionRimLight,
Styles.invertedDirectionRimLightText);
EditorGUI.BeginDisabledGroup(Properties.invertedDirectionRimLight.floatValue == 0);
{
EditorGUI.indentLevel++;
editor.ShaderProperty(Properties.invertedRimLightColor, Styles.invertedRimLightColorText);
editor.ShaderProperty(Properties.inversedRimLightLevel, Styles.inversedRimLightLevelText);
editor.ShaderProperty(Properties.invertedRimLightFeatherOff,
Styles.invertedRimLightFeatherOffText);
}
EditorGUI.EndDisabledGroup();
EditorGUI.indentLevel--;
}
EditorGUI.EndDisabledGroup();
EditorGUILayout.Space();
EditorGUI.indentLevel--;
editor.TexturePropertySingleLine(Styles.rimLightMaskMapText, Properties.rimLightMaskMap);
editor.ShaderProperty(Properties.rimLightMaskLevel, Styles.rimLightMaskLevelText);
}
EditorGUI.EndDisabledGroup();
public static readonly GUIContent lightBaseRimLightText = new("Light Base Rim Light", "Enable to let rim light calculate per light.");
public static readonly GUIContent lightDirectionRimLightLevelText = new("Light Direction Level", "Specifies intensity of Rim Light in the light source direction,");
}
protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.Rimlight;
protected override GUIContent Header => EditorGUIUtility.TrTextContent("Rim Light Settings");
protected override bool ShowSection => SurfaceOptionsScope.HasFeature(SurfaceFeatureFlags.RimLight);
protected override bool ShowSection => materials.All(mat => mat.HasFeature(SurfaceFeature.RimLight));
protected override void LoadMaterialProperties()
{
Properties.rimLightColor = FindProperty(RIM_LIGHT_COLOR);
Properties.rimLightIntensity = FindProperty(RIM_LIGHT_INTENSITY);
Properties.albedoAffectRimLight = FindProperty(ALBEDO_AFFECT_RIM_LIGHT);
Properties.screenSpaceRimLight = FindProperty(SCREEN_SPACE_RIM_LIGHT);
Properties.rimLightLevel = FindProperty(RIM_LIGHT_LEVEL);
Properties.rimLightClipping = FindProperty(RIM_LIGHT_CLIPPING);
Properties.rimLightClippingLevel = FindProperty(RIM_LIGHT_CLIPPING_LEVEL);
Properties.lightBaseRimLight = FindProperty(LIGHT_BASE_RIM_LIGHT);
Properties.lightDirectionRimLightLevel = FindProperty(LIGHT_DIRECTION_RIM_LIGHT_LEVEL);
}
protected override void DrawContent()
{
editor.ShaderProperty(Properties.rimLightColor, Styles.rimLightColorText);
editor.ShaderProperty(Properties.rimLightIntensity, Styles.rimLightIntensityText);
editor.ShaderProperty(Properties.albedoAffectRimLight, Styles.albedoAffectRimLightText);
editor.ShaderProperty(Properties.screenSpaceRimLight, Styles.screenSpaceRimLightText);
editor.ShaderProperty(Properties.rimLightLevel, Styles.rimLightLevelText);
if (!Properties.screenSpaceRimLight.GetBooleanValue())
{
editor.ShaderProperty(Properties.rimLightClipping, Styles.rimLightClippingText);
if (Properties.rimLightClipping.GetBooleanValue())
{
using var clippingLevelIndentLevelScope = new EditorGUI.IndentLevelScope();
editor.ShaderProperty(Properties.rimLightClippingLevel, Styles.rimLightClippingLevelText);
}
}
EditorGUILayout.Space();
editor.ShaderProperty(Properties.lightBaseRimLight, Styles.lightBaseRimLightText);
if (Properties.lightBaseRimLight.GetBooleanValue())
{
editor.ShaderProperty(Properties.lightDirectionRimLightLevel, Styles.lightDirectionRimLightLevelText);
}
}
}
}

View File

@@ -1,13 +1,16 @@
using Misaki.ShaderGUI;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace Misaki.HdrpToon.Editor
{
public class ShadingColorScope : MaterialUIScope<ShaderGUIExpandable>
internal class ShadingColorScope : MaterialUIScope<ShaderGUIExpandable>
{
private static class Properties
{
public static MaterialProperty shadingRampMapState;
public static MaterialProperty baseColor;
public static MaterialProperty baseColorMap;
public static MaterialProperty applyTo1stShadingMapEnable;
@@ -17,91 +20,75 @@ namespace Misaki.HdrpToon.Editor
public static MaterialProperty secondShadingColor;
public static MaterialProperty secondShadingMap;
public static MaterialProperty sdfShadowMap;
public static MaterialProperty firstShadeColorStep;
public static MaterialProperty firstShadeColorFeather;
public static MaterialProperty secondShadeColorStep;
public static MaterialProperty secondShadeColorFeather;
public static MaterialProperty shadingRampMap;
public static MaterialProperty shadingIndex;
public static MaterialProperty shadingRampMaskMap;
public static MaterialProperty shadingRampMask;
public static MaterialProperty sdfShadingMap;
public static MaterialProperty sdfShadowLevel;
public static MaterialProperty sdfSmoothLevel;
public static MaterialProperty sdfHighlightStrength;
public static MaterialProperty sdfHighlightSmoothLevel;
public static MaterialProperty shadingGradeMap;
public static MaterialProperty shadingIndex;
public static MaterialProperty hairBlendingFactor;
}
private static class Styles
{
public static readonly GUIContent baseMapText = new("Base Map", "Base Color : Texture(sRGB) x Color(RGB) Default:White");
public static readonly GUIContent shadingRampMapStateText = new("Shading Ramp Map State", "Use Shading Ramp Map to control the shading color instead of manually setting the shading color.");
public static readonly GUIContent baseColorText = new("Base Map", "Base Color : Texture(sRGB) x Color(RGB) Default:White");
public static readonly GUIContent applyTo1stShadingMapText = new("Apply to 1st shading map", "Apply Base map to the 1st shading map.");
public static readonly GUIContent firstShadingMapText = new("1st Shading Map", "The map used for the brighter portions of the shadow.");
public static readonly GUIContent applyTo2ndShadingMapText = new("Apply to 2nd shading map", "Apply Base map or the 1st shading map to the 2st shading map.");
public static readonly GUIContent secondShadingMapText = new("2nd Shading Map", "The map used for the darker portions of the shadow.");
public static readonly GUIContent sdfShadowMapText = new("SDF Shadow Map", "SDF Shadow Map");
public static readonly GUIContent sdfShadowLevelText = new("SDF Shadow Level", "SDF Shadow Level");
public static readonly GUIContent sdfSmoothLevelText = new("SDF Smooth Level", "SDF Smooth Level");
public static readonly GUIContent sdfHighlightStrengthText = new("SDF Highlight Strength", "SDF Highlight Strength");
public static readonly GUIContent sdfHighlightSmoothLevelText = new("SDF Highlight Smooth Level", "SDF Highlight Smooth Level");
public static readonly GUIContent firstShadeColorStepText = new("1st Shade Color Step", "Sets the step between the Base color and 1st Shade Color, the same as the BaseColor_Step property.");
public static readonly GUIContent firstShadeColorFeatherText = new("1st Shade Color Feather", "Sets the feather between the Base color and 1st Shade Color, the same as the BaseColor_Feather property.");
public static readonly GUIContent secondShadeColorStepText = new("2nd Shade Color Step", "Sets the step between the 1st Shade color and 2nd Shade Color, the same as the 1stShadeColorStep property.");
public static readonly GUIContent secondShadeColorFeatherText = new("2nd Shade Color Feather", "Sets the feather between the 1st Shade color and 2nd Shade Color, the same as the 1stShadeColorFeather property.");
public static readonly GUIContent shadingGradeMapText = new("Shading Grade Map", "Shading Grade Map");
public static readonly GUIContent shadingIndexText = new("Shading Index", "The index to choose when sampling the texture 2d array.");
public static readonly GUIContent sdfShadingMapText = new("SDF Shading Map", "The map used for the SDF shading. R channel for SDF shadow, G channel for highlight, B channel for fixed shadow.");
public static readonly GUIContent sdfShadowLevelText = new("SDF Shadow Level", "Control the sampling position of the shadow in the SDF shading map.");
public static readonly GUIContent sdfSmoothLevelText = new("SDF Smooth Level", "Control the smoothness of the shadow edge.");
public static readonly GUIContent shadingRampMapText = new("Shading Ramp Map", "A texture 2D array that contains a ramp color in each slice, and the index to choose when sampling the shading ramp map.");
public static readonly GUIContent shadingRampMaskMapText = new("Shading Ramp Mask Map", "A texture that contains the mask for the shading ramp map.");
public static readonly GUIContent sdfHighlightStrengthText = new("SDF Highlight Strength", "Control the strength of the highlight in the SDF shading map.");
public static readonly GUIContent hairBlendingFactorText = new("Hair Blending Factor", "The blending factor for hair shading.");
}
protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.ShadingColor;
protected override GUIContent Header => EditorGUIUtility.TrTextContent("Shading Color Settings");
private void DrawSecondShadingMapProperties()
private void DrawShadingProperties(MaterialProperty inheritProperty, MaterialProperty colorProperty, MaterialProperty colorMapProperty, GUIContent inheritText, GUIContent colorText)
{
EditorGUI.indentLevel += 2;
editor.ShaderProperty(Properties.applyTo2ndShadingMapEnable, Styles.applyTo2ndShadingMapText);
editor.ShaderProperty(inheritProperty, inheritText);
EditorGUI.indentLevel -= 2;
if (Mathf.Approximately(Properties.applyTo2ndShadingMapEnable.floatValue, 1))
if (Mathf.Approximately(inheritProperty.floatValue, 1))
{
EditorGUI.indentLevel += 2;
editor.ColorProperty(Properties.secondShadingColor, Styles.secondShadingMapText.text);
editor.ShaderProperty(colorProperty, colorText);
EditorGUI.indentLevel -= 2;
}
else
{
editor.TexturePropertySingleLine(Styles.secondShadingMapText, Properties.secondShadingMap,
Properties.secondShadingColor);
editor.TexturePropertySingleLine(colorText, colorMapProperty, colorProperty);
}
}
private void DrawFirstShadingMapProperties()
protected override void LoadMaterialProperties()
{
EditorGUI.indentLevel += 2;
editor.ShaderProperty(Properties.applyTo1stShadingMapEnable, Styles.applyTo1stShadingMapText);
EditorGUI.indentLevel -= 2;
if (Mathf.Approximately(Properties.applyTo1stShadingMapEnable.floatValue, 1))
{
EditorGUI.indentLevel += 2;
editor.ColorProperty(Properties.firstShadingColor, Styles.firstShadingMapText.text);
EditorGUI.indentLevel -= 2;
}
else
{
editor.TexturePropertySingleLine(Styles.firstShadingMapText, Properties.firstShadingMap,
Properties.firstShadingColor);
}
}
Properties.shadingRampMapState = FindProperty("_Use_Shading_Ramp_Map");
private void DrawSDFProperties()
{
editor.TexturePropertySingleLine(Styles.sdfShadowMapText, Properties.sdfShadowMap);
editor.ShaderProperty(Properties.sdfShadowLevel, Styles.sdfShadowLevelText);
editor.ShaderProperty(Properties.sdfSmoothLevel, Styles.sdfSmoothLevelText);
editor.ShaderProperty(Properties.sdfHighlightStrength, Styles.sdfHighlightStrengthText);
editor.ShaderProperty(Properties.sdfHighlightSmoothLevel, Styles.sdfHighlightSmoothLevelText);
}
private void DrawShadingGradeProperties()
{
editor.TexturePropertySingleLine(Styles.shadingGradeMapText, Properties.shadingGradeMap);
editor.ShaderProperty(Properties.shadingIndex, Styles.shadingIndexText);
}
public override void LoadMaterialProperties()
{
Properties.baseColor = FindProperty("_BaseColor");
Properties.baseColorMap = FindProperty("_BaseColorMap");
Properties.applyTo1stShadingMapEnable = FindProperty("_UseBaseAs1st");
@@ -111,34 +98,62 @@ namespace Misaki.HdrpToon.Editor
Properties.secondShadingColor = FindProperty("_2ndShadeColor");
Properties.secondShadingMap = FindProperty("_2ndShadeColorMap");
Properties.sdfShadowMap = FindProperty("_SDFShadowMap");
Properties.sdfShadowLevel = FindProperty("_SDFShadowLevel");
Properties.sdfSmoothLevel = FindProperty("_SDFSmoothLevel");
Properties.sdfHighlightStrength = FindProperty("_SDFHighlightStrength");
Properties.sdfHighlightSmoothLevel = FindProperty("_SDFHighlightSmoothLevel");
Properties.firstShadeColorStep = FindProperty("_1stShadeColorStep");
Properties.firstShadeColorFeather = FindProperty("_1stShadeColorFeather");
Properties.secondShadeColorStep = FindProperty("_2ndShadeColorStep");
Properties.secondShadeColorFeather = FindProperty("_2ndShadeColorFeather");
Properties.shadingGradeMap = FindProperty("_ShadingGradeMap");
Properties.shadingRampMap = FindProperty("_ShadingRampMap");
Properties.shadingIndex = FindProperty("_ShadingIndex");
Properties.shadingRampMaskMap = FindProperty("_ShadingRampMaskMap");
Properties.shadingRampMask = FindProperty("_ShadingRampMask");
Properties.sdfShadingMap = FindProperty("_SDFShadingMap");
Properties.sdfShadowLevel = FindProperty("_SDFShadowLevel");
Properties.sdfSmoothLevel = FindProperty("_SDFShadowSmoothLevel");
Properties.sdfHighlightStrength = FindProperty("_SDFHighlightStrength");
Properties.hairBlendingFactor = FindProperty("_HairBlendingFactor");
}
protected override void DrawContent()
{
editor.TexturePropertySingleLine(Styles.baseMapText, Properties.baseColorMap, Properties.baseColor);
editor.ShaderProperty(Properties.shadingRampMapState, Styles.shadingRampMapStateText);
editor.TexturePropertySingleLine(Styles.baseColorText, Properties.baseColorMap, Properties.baseColor);
switch (SurfaceOptionsScope.GetShadingMode())
if (Properties.shadingRampMapState.GetBooleanValue())
{
case ShadingMode.ThreeColorStep:
DrawFirstShadingMapProperties();
DrawSecondShadingMapProperties();
break;
case ShadingMode.SDF:
DrawSDFProperties();
break;
case ShadingMode.Ramp:
DrawShadingGradeProperties();
break;
default:
break;
editor.TexturePropertySingleLine(Styles.shadingRampMapText, Properties.shadingRampMap, Properties.shadingIndex);
editor.KeywordTexturePropertySingleLine(Styles.shadingRampMaskMapText, Properties.shadingRampMaskMap, Properties.shadingRampMask, "_SHADING_RAMP_MASK_MAP");
}
else
{
DrawShadingProperties(Properties.applyTo1stShadingMapEnable, Properties.firstShadingColor, Properties.firstShadingMap, Styles.applyTo1stShadingMapText, Styles.firstShadingMapText);
if (materials.All(material => material.GetShadingMode() == ShadingMode.Standard))
{
DrawShadingProperties(Properties.applyTo2ndShadingMapEnable, Properties.secondShadingColor, Properties.secondShadingMap, Styles.applyTo2ndShadingMapText, Styles.secondShadingMapText);
EditorGUILayout.Space();
editor.ShaderProperty(Properties.firstShadeColorStep, Styles.firstShadeColorStepText);
editor.ShaderProperty(Properties.firstShadeColorFeather, Styles.firstShadeColorFeatherText);
editor.ShaderProperty(Properties.secondShadeColorStep, Styles.secondShadeColorStepText);
editor.ShaderProperty(Properties.secondShadeColorFeather, Styles.secondShadeColorFeatherText);
}
}
if (materials.All(material => material.GetShadingMode() == ShadingMode.SDF))
{
EditorGUILayout.Space();
editor.TexturePropertySingleLine(Styles.sdfShadingMapText, Properties.sdfShadingMap);
editor.ShaderProperty(Properties.sdfShadowLevel, Styles.sdfShadowLevelText);
editor.ShaderProperty(Properties.sdfSmoothLevel, Styles.sdfSmoothLevelText);
editor.ShaderProperty(Properties.sdfHighlightStrength, Styles.sdfHighlightStrengthText);
}
if (materials.All(material => material.GetMaterialType() == MaterialType.FrontHair))
{
EditorGUILayout.Space();
editor.ShaderProperty(Properties.hairBlendingFactor, Styles.hairBlendingFactorText);
}
EditorGUILayout.Space();

View File

@@ -1,23 +0,0 @@
using Misaki.ShaderGUI;
using UnityEditor;
using UnityEngine;
namespace Misaki.HdrpToon.Editor
{
public class ShadingGradeScope : MaterialUIScope<ShaderGUIExpandable>
{
protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.ShadingGrade;
protected override GUIContent Header => EditorGUIUtility.TrTextContent("Shading Grade Settings");
public override void LoadMaterialProperties()
{
throw new System.NotImplementedException();
}
protected override void DrawContent()
{
throw new System.NotImplementedException();
}
}
}

View File

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

View File

@@ -0,0 +1,57 @@
using Misaki.ShaderGUI;
using UnityEditor;
using UnityEngine;
namespace Misaki.HdrpToon.Editor
{
internal class ShadowScope : MaterialUIScope<ShaderGUIExpandable>
{
private static class Properties
{
public static MaterialProperty receiveLightShadow;
public static MaterialProperty receiveScreenSpaceShadow;
public static MaterialProperty receiveHairShadow;
public static MaterialProperty shadowDistanceBias;
public static MaterialProperty shadowNormalBias;
}
private static class Styles
{
public static readonly GUIContent receiveLightShadowText = new("Receive Light Shadow", "Enable to receive shadow from light.");
public static readonly GUIContent receiveHairShadowText = new("Receive Hair Shadow", "Enable to receive shadow from hair shadow caster");
public static readonly GUIContent receiveScreenSpaceShadowText = new("Receive Screen Space Shadow", "Enable to receive screen space shadow.");
public static readonly GUIContent lightShadowBiasText = new("Light Shadow Bias", "Specifies the bias of the light shadow.");
public static readonly GUIContent lightShadowNormalBiasText = new("Light Shadow Normal Bias", "Specifies the normal bias of the light shadow.");
}
protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.Shadow;
protected override GUIContent Header => EditorGUIUtility.TrTextContent("Shadow Settings");
protected override void LoadMaterialProperties()
{
Properties.receiveLightShadow = FindProperty("_Receive_Light_Shadow");
Properties.receiveScreenSpaceShadow = FindProperty("_Receive_Screen_Space_Shadow");
Properties.receiveHairShadow = FindProperty("_Receive_Hair_Shadow");
Properties.shadowDistanceBias = FindProperty("_ShadowDistanceBias");
Properties.shadowNormalBias = FindProperty("_ShadowNormalBias");
}
protected override void DrawContent()
{
editor.ShaderProperty(Properties.receiveLightShadow, Styles.receiveLightShadowText);
if (Properties.receiveLightShadow.GetBooleanValue())
{
editor.ShaderProperty(Properties.receiveScreenSpaceShadow, Styles.receiveScreenSpaceShadowText);
}
editor.ShaderProperty(Properties.receiveHairShadow, Styles.receiveHairShadowText);
EditorGUILayout.Space();
editor.ShaderProperty(Properties.shadowDistanceBias, Styles.lightShadowBiasText);
editor.ShaderProperty(Properties.shadowNormalBias, Styles.lightShadowNormalBiasText);
}
}
}

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,195 @@
using Misaki.ShaderGUI;
using System.Linq;
using UnityEditor;
using UnityEditor.Rendering;
using UnityEngine;
using static Misaki.HdrpToon.UTSPropertyName.SurfaceInputs;
namespace Misaki.HdrpToon.Editor
{
internal class SurfaceInputsScope : MaterialUIScope<ShaderGUIExpandable>
{
private static class Properties
{
public static MaterialProperty normalMap;
public static MaterialProperty normalMapScale;
public static MaterialProperty maskMap;
public static MaterialProperty metallic;
public static MaterialProperty metallicRemapMin;
public static MaterialProperty metallicRemapMax;
public static MaterialProperty aoRemapMin;
public static MaterialProperty aoRemapMax;
public static MaterialProperty smoothness;
public static MaterialProperty smoothnessRemapMin;
public static MaterialProperty smoothnessRemapMax;
public static MaterialProperty anisotropyMap;
public static MaterialProperty anisotropy;
public static MaterialProperty kkColor;
public static MaterialProperty bsdfContribution;
public static MaterialProperty specularColorMap;
public static MaterialProperty specularColor;
public static MaterialProperty specularFeather;
public static MaterialProperty specularStep;
public static MaterialProperty hairBlendingMap;
public static MaterialProperty emissiveColorLDR;
public static MaterialProperty emissiveColorMap;
public static MaterialProperty emissiveIntensity;
public static MaterialProperty albedoAffectEmissive;
public static MaterialProperty emissiveExposureWeight;
}
private static class Styles
{
public static readonly GUIContent normalMapText = new("Normal Map", "A texture that dictates the bumpiness of the material.");
public static readonly GUIContent maskMapText = new("Mask Map", "A texture that dictates the physical properties of the material. R channel for metallic, G channel for ambient occlusion, A channel for smoothness");
public static readonly GUIContent metallicText = new("Metallic", "Specifies the metallic value of the material.");
public static readonly GUIContent metallicRemap = new("Metallic Remap", "Remap the max and min value of metallic");
public static readonly GUIContent aoRemap = new("AO Remap", "Remap the max and min value of ambient occlusion");
public static readonly GUIContent smoothnessText = new("Smoothness", "Specifies the smoothness of the material.");
public static readonly GUIContent smoothnessRemapText = new("Smoothness Remap", "Remap the max and min value of smoothness");
public static readonly GUIContent anisotropyMapText = new("Anisotropy Map", "Specifies the anisotropy map of the material.");
public static readonly GUIContent kkColorText = new("KK specular Color", "Specifies the color of KK specular.");
public static readonly GUIContent bsdfContributionText = new("BSDF Contribution", "BSDF smoothness contribution, 1 means KK Hair smoothness will fully contribute bsdf calculation");
public static readonly GUIContent specularColorMapText = new("Specular Color Map", "Specifies the specular color map of the material.");
public static readonly GUIContent specRemap = new("Specular Remap", "Feather and step value of Toon Specular");
public static readonly GUIContent hairBlenderMapText = new("Hair Blending Map", "Specifies the hair blending map of the material.");
public static readonly GUIContent emissiveColorText = new("Emissive Color", "The color and color map to set for emissive effect.");
public static readonly GUIContent albedoAffectEmissiveText = new("Albedo Affect Emissive", "Enable to affect emissive color with base color");
public static readonly GUIContent emissiveIntensityText = new("Emissive Intensity", "Set the intensity of the emissive color,in Nits");
public static readonly GUIContent emissiveExposureWeightText = new("Exposure Weight", "Controls how the camera exposure influences the perceived intensity of the emissivity. A weight of 0 means that the emissive intensity is calculated ignoring the exposure; increasing this weight progressively increases the influence of exposure on the final emissive value.");
}
protected override ShaderGUIExpandable ExpandableBit => ShaderGUIExpandable.SurfaceInputs;
protected override GUIContent Header => new("Surface Inputs");
protected override void LoadMaterialProperties()
{
Properties.normalMap = FindProperty("_NormalMap");
Properties.normalMapScale = FindProperty("_NormalScale");
Properties.maskMap = FindProperty("_MaskMap");
Properties.metallic = FindProperty("_Metallic");
Properties.metallicRemapMin = FindProperty("_MetallicRemapMin");
Properties.metallicRemapMax = FindProperty("_MetallicRemapMax");
Properties.aoRemapMin = FindProperty("_AORemapMin");
Properties.aoRemapMax = FindProperty("_AORemapMax");
Properties.smoothnessRemapMin = FindProperty("_SmoothnessRemapMin");
Properties.smoothnessRemapMax = FindProperty("_SmoothnessRemapMax");
Properties.smoothness = FindProperty("_Smoothness");
Properties.anisotropyMap = FindProperty("_AnisotropyMap");
Properties.anisotropy = FindProperty("_Anisotropy");
Properties.kkColor = FindProperty("_KKColor");
Properties.bsdfContribution = FindProperty("_BSDFContribution");
Properties.specularColorMap = FindProperty("_SpecularColorMap");
Properties.specularColor = FindProperty("_SpecularColor");
Properties.specularFeather = FindProperty("_ToonSpecularFeather");
Properties.specularStep = FindProperty("_ToonSpecularStep");
Properties.hairBlendingMap = FindProperty("_HairBlendingMap");
Properties.emissiveColorLDR = FindProperty(EMISSIVE_COLOR_LDR);
Properties.emissiveColorMap = FindProperty(EMISSIVE_COLOR_MAP);
Properties.albedoAffectEmissive = FindProperty(ALBEDO_AFFECT_EMISSIVE);
Properties.emissiveIntensity = FindProperty(EMISSIVE_INTENSITY);
Properties.emissiveExposureWeight = FindProperty(EMISSIVE_EXPOSURE_WEIGHT);
}
protected override void DrawContent()
{
editor.KeywordTexturePropertySingleLine(Styles.normalMapText, Properties.normalMap, Properties.normalMapScale);
if (materials.All(mat => mat.GetPBRMode() != PBRMode.Off))
{
if (editor.KeywordTexturePropertySingleLine(Styles.maskMapText, Properties.maskMap))
{
editor.MinMaxShaderProperty(Properties.metallicRemapMin, Properties.metallicRemapMax, 0, 1, Styles.metallicRemap);
editor.MinMaxShaderProperty(Properties.aoRemapMin, Properties.aoRemapMax, 0, 1, Styles.aoRemap);
editor.MinMaxShaderProperty(Properties.smoothnessRemapMin, Properties.smoothnessRemapMax, 0, 1, Styles.smoothnessRemapText);
}
else
{
if (materials.All(mat =>
{
var pbrMode = mat.GetPBRMode();
return pbrMode != PBRMode.Hair && pbrMode != PBRMode.Toon;
}))
{
editor.ShaderProperty(Properties.metallic, Styles.metallicText);
}
editor.ShaderProperty(Properties.smoothness, Styles.smoothnessText);
}
}
if (materials.All(mat => mat.GetPBRMode() == PBRMode.Anisotropy || mat.GetPBRMode() == PBRMode.Hair))
{
EditorGUILayout.Space();
editor.KeywordTexturePropertySingleLine(Styles.anisotropyMapText, Properties.anisotropyMap, Properties.anisotropy);
if (materials.All(mat => mat.GetPBRMode() == PBRMode.Hair))
{
editor.ShaderProperty(Properties.kkColor, Styles.kkColorText);
editor.ShaderProperty(Properties.bsdfContribution, Styles.bsdfContributionText);
}
EditorGUILayout.Space();
EditorGUILayout.LabelField("Anisotropy Map only ST");
editor.TextureScaleOffsetProperty(Properties.anisotropyMap);
}
else if (materials.All(mat => mat.GetPBRMode() == PBRMode.Toon))
{
EditorGUILayout.Space();
editor.KeywordTexturePropertySingleLine(Styles.specularColorMapText, Properties.specularColorMap, Properties.specularColor);
editor.MinMaxShaderProperty(Properties.specularFeather, Properties.specularStep, 0, 1, Styles.specRemap);
}
if (materials.All(mat => mat.IsHairBlendingTarget()))
{
editor.TexturePropertySingleLine(Styles.hairBlenderMapText, Properties.hairBlendingMap);
}
EditorGUILayout.Space();
using (var EmissiveIntentLevel = new EditorGUI.IndentLevelScope(-1))
{
EditorGUILayout.LabelField("Emissive", EditorStyles.boldLabel);
}
EditorGUI.BeginChangeCheck();
editor.KeywordTexturePropertySingleLine(Styles.emissiveColorText, Properties.emissiveColorMap, Properties.emissiveColorLDR, "_EMISSIVE_COLOR_MAP");
editor.ShaderProperty(Properties.emissiveIntensity, Styles.emissiveIntensityText);
if (EditorGUI.EndChangeCheck())
{
foreach (var material in materials)
{
if (material.HasProperty(EMISSIVE_COLOR_LDR) && material.HasProperty(EMISSIVE_INTENSITY) && material.HasProperty(EMISSIVE_COLOR))
{
// Important: The color picker for kEmissiveColorLDR is LDR and in sRGB color space but Unity don't perform any color space conversion in the color
// picker BUT only when sending the color data to the shader... So as we are doing our own calculation here in C#, we must do the conversion ourselves.
var emissiveColorLDR = material.GetColor(EMISSIVE_COLOR_LDR);
var emissiveColorLDRLinear = new Color(Mathf.GammaToLinearSpace(emissiveColorLDR.r), Mathf.GammaToLinearSpace(emissiveColorLDR.g), Mathf.GammaToLinearSpace(emissiveColorLDR.b));
material.SetColor(EMISSIVE_COLOR, emissiveColorLDRLinear * material.GetFloat(EMISSIVE_INTENSITY));
}
}
}
EditorGUILayout.Space();
editor.ShaderProperty(Properties.albedoAffectEmissive, Styles.albedoAffectEmissiveText);
editor.ShaderProperty(Properties.emissiveExposureWeight, Styles.emissiveExposureWeightText);
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 184fb730617fcf24592d8e6c49e2029a

View File

@@ -2,40 +2,57 @@ 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;
public static MaterialProperty receiveHairShadow;
public static MaterialProperty hairBlendingTarget;
public static MaterialProperty surfaceFeatures;
}
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.");
public static readonly GUIContent receiveHairShadowText = new("Receive Hair Shadow", "Enable to receive shadow from hair shadow caster");
public static readonly GUIContent hairBlendingTargetText = new("Hair Blending Target", "Enable to be blended with hair");
public static readonly GUIContent surfaceFeaturesText = new("Surface Features", "Specifies the surface features.");
}
@@ -44,73 +61,69 @@ namespace Misaki.HdrpToon.Editor
protected override GUIContent Header => EditorGUIUtility.TrTextContent("Surface Options");
public static ShadingMode GetShadingMode()
protected override void LoadMaterialProperties()
{
return (ShadingMode)Properties.shadingMode.floatValue;
}
Properties.surfaceType = FindProperty(SURFACE_TYPE);
public static bool HasFeature(SurfaceFeatureFlags feature)
{
return ((SurfaceFeatureFlags)Properties.surfaceFeatures.floatValue & feature) != 0;
}
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);
public override void LoadMaterialProperties()
{
Properties.transparentMode = FindProperty("_TransparentEnabled");
Properties.alphaClipEnable = FindProperty(ALPHA_CLIP_ENABLE);
Properties.alphaClip = FindProperty(ALPHA_CUTOFF);
Properties.cullMode = FindProperty(CULL_MODE);
Properties.doubleSidedNormalMode = FindProperty(DOUBLE_SIDED_NORMAL_MODE);
Properties.alphaClipEnable = FindProperty("_AlphaCutoffEnable");
Properties.alphaClip = FindProperty("_AlphaCutoff");
Properties.shadingMode = FindProperty(SHADING_MODE);
Properties.materialType = FindProperty(MATERIAL_TYPE);
Properties.pbrMode = FindProperty(PBR_MODE);
Properties.cullMode = FindProperty("_CullMode");
Properties.shadingMode = FindProperty("_Shading_Mode");
Properties.materialType = FindProperty("_Material_Type");
Properties.pbrMode = FindProperty("_PBR_Mode");
Properties.receiveHairShadow = FindProperty("_Receive_Hair_Shadow");
Properties.hairBlendingTarget = FindProperty("_HairBlendingTarget");
Properties.surfaceFeatures = FindProperty("_SurfaceFeatures");
Properties.hairBlendingTarget = FindProperty(HAIR_BLENDING_TARGET);
Properties.surfaceFeatures = FindProperty(SURFACE_FEATURE);
}
protected override void DrawContent()
{
editor.ShaderProperty(Properties.transparentMode, Styles.transparentModeText);
editor.ShaderProperty(Properties.alphaClipEnable, Styles.alphaClipEnableText);
if (Properties.alphaClipEnable.floatValue == 1.0f)
editor.ShaderProperty(Properties.surfaceType, Styles.transparentModeText);
using (new EditorGUI.IndentLevelScope())
{
EditorGUI.indentLevel++;
editor.ShaderProperty(Properties.alphaClip, Styles.alphaClipText);
EditorGUI.indentLevel--;
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())
{
using var s = new EditorGUI.IndentLevelScope();
editor.ShaderProperty(Properties.alphaClip, Styles.alphaClipText);
}
editor.ShaderProperty(Properties.shadingMode, Styles.shadingModeText);
editor.ShaderProperty(Properties.materialType, Styles.materialTypeText);
editor.ShaderProperty(Properties.pbrMode, Styles.pbrModeText);
editor.ShaderProperty(Properties.receiveHairShadow, Styles.receiveHairShadowText);
EditorGUI.BeginChangeCheck();
editor.ShaderProperty(Properties.hairBlendingTarget, Styles.hairBlendingTargetText);
if (EditorGUI.EndChangeCheck())
{
foreach (var material in editor.GetMaterials())
{
material.SetShaderPassEnabled(UtsShaderPassName.HAIR_BLENDING_TARGET_PASS_NAME, Properties.hairBlendingTarget.floatValue == 1.0f);
}
}
var surfaceFeatures = (SurfaceFeatureFlags)Properties.surfaceFeatures.floatValue;
EditorGUI.BeginChangeCheck();
surfaceFeatures = (SurfaceFeatureFlags)EditorGUILayout.EnumFlagsField(Styles.surfaceFeaturesText, surfaceFeatures);
if (EditorGUI.EndChangeCheck())
{
Properties.surfaceFeatures.floatValue = (float)surfaceFeatures;
foreach (var material in editor.GetMaterials())
{
material.SetShaderPassEnabled(UtsShaderPassName.OUTLINE_PASS_NAME, HasFeature(SurfaceFeatureFlags.Outline));
}
}
editor.ShaderProperty(Properties.surfaceFeatures, Styles.surfaceFeaturesText);
}
}
}

View File

@@ -8,6 +8,13 @@ namespace Misaki.HdrpToon.Editor
{
private GUIStyle _headerStyle;
public override void ValidateMaterial(Material material)
{
UTSAPI.SetupPass(material);
UTSAPI.SetupKeywords(material);
UTSAPI.SetupProperties(material);
}
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
if (!initialized)
@@ -24,17 +31,32 @@ namespace Misaki.HdrpToon.Editor
private void OnInitialize(MaterialEditor materialEditor, MaterialProperty[] properties)
{
AddUIScope(new SurfaceOptionsScope());
AddUIScope(new ShadingColorScope());
AddUIScope(new PBRScope());
AddUIScope(new RimLightScope());
AddUIScope(new AngelRingScope());
AddUIScope(new OutlineScope());
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);
_headerStyle = new GUIStyle() { fontSize = 25, fontStyle = FontStyle.Bold, alignment = TextAnchor.MiddleCenter };
_headerStyle.normal.textColor = GUI.skin.label.normal.textColor;
_headerStyle = new GUIStyle()
{
fontSize = 25,
fontStyle = FontStyle.Bold,
alignment = TextAnchor.MiddleCenter,
normal =
{
textColor = GUI.skin.label.normal.textColor
}
};
}
}
}

View File

@@ -7,6 +7,7 @@
"Unity.RenderPipelines.Core.Editor",
"Unity.RenderPipelines.HighDefinition.Runtime",
"Unity.RenderPipelines.HighDefinition.Editor",
"Unity.Mathematics",
"Unity.Collections",
"Misaki.ShaderGUI"
],

View File

@@ -0,0 +1,162 @@
#pragma kernel SkinLut
#pragma kernel ShadowLut
#pragma multi_compile_local _ _PRODUCTION
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#define _PROFILE_WIDTH 8.166
float _ScatterRadius;
float _PositionShift;
float _Intensity;
int _SampleCount;
int _ApplyTonemap;
uint _TextureSize;
RWTexture2D<float4> _SSSLut;
static const float VARIANCE[6] =
{
0.0064,
0.0484,
0.1870,
0.5670,
1.9900,
7.4100
};
static const float3 WEIGHTS[6] =
{
float3(0.233, 0.455, 0.649),
float3(0.100, 0.336, 0.344),
float3(0.118, 0.198, 0.000),
float3(0.113, 0.007, 0.007),
float3(0.358, 0.004, 0.000),
float3(0.078, 0.000, 0.000)
};
float Gaussian(float v, float r)
{
return rcp(2.0 * PI * v) * exp((-r * r) / (2.0 * v));
}
float3 RadianceScatter(float r)
{
float3 result = 0.0;
for (int i = 0; i < 6; i++)
{
result += WEIGHTS[i] * Gaussian(VARIANCE[i], r);
}
return result;
}
float3 IntegrateDiffuseScattering_Ring(float theta, float r)
{
float3 totalScatter = 0;
float3 totalWeight = 0;
float increment = PI / _SampleCount;
float x = -HALF_PI;
while (x < HALF_PI)
{
float diffuse = saturate(cos(theta + x));
float distance = abs(2.0 * r * sin(x / 2.0));
float3 radiance = RadianceScatter(distance);
totalScatter += radiance * diffuse;
totalWeight += radiance;
x += increment;
}
return totalScatter / totalWeight;
}
float newPenumbra(float pos, float penumbraWidth)
{
return saturate((pos * penumbraWidth - _PROFILE_WIDTH) / (penumbraWidth - _PROFILE_WIDTH));
}
float3 IntegrateShadowScattering(float penumbraLocation, float penumbraWidth)
{
float3 totalScatter = 0;
float3 totalWeights = 0;
float increment = (_PROFILE_WIDTH * 2) / _SampleCount;
penumbraWidth = max(penumbraWidth, _PROFILE_WIDTH + 1e-5);
float x = -_PROFILE_WIDTH;
while (x <= _PROFILE_WIDTH)
{
float light = newPenumbra(penumbraLocation + x / penumbraWidth, penumbraWidth);
float distance = abs(x);
float3 weights = RadianceScatter(distance);
totalWeights += weights;
totalScatter += light * weights;
x += increment;
}
return totalScatter / totalWeights;
}
float3 FilmicTonemap(float3 color)
{
return (color * (6.2 * color + 0.5)) / (color * (6.2 * color + 1.7) + 0.06);
}
[numthreads(8,8,1)]
void SkinLut (uint3 id : SV_DispatchThreadID)
{
if (id.x > _TextureSize || id.y > _TextureSize)
{
return;
}
float2 uv = id.xy / float2(_TextureSize, _TextureSize);
#if UNITY_UV_STARTS_AT_TOP && _PRODUCTION
uv.y = 1.0 - uv.y;
#endif
float theta = acos((uv.x * 2.0 - 1.0)) + _PositionShift;
float r = rcp(max(uv.y, 0.001) * _ScatterRadius);
float3 scatter = IntegrateDiffuseScattering_Ring(theta, r) * _Intensity;
if (_ApplyTonemap == 1)
{
scatter = FilmicTonemap(scatter);
}
_SSSLut[id.xy] = float4(scatter, 1.0);
//_SSSLut[id.xy] = theta;
}
[numthreads(8, 8, 1)]
void ShadowLut(uint3 id : SV_DispatchThreadID)
{
if (id.x > _TextureSize || id.y > _TextureSize)
{
return;
}
float2 uv = id.xy / float2(_TextureSize, _TextureSize);
#if UNITY_UV_STARTS_AT_TOP && _PRODUCTION
uv.y = 1.0 - uv.y;
#endif
float penumbraLocation = uv.x + _PositionShift;
float penumbraWidth = rcp(max(uv.y, 0.001) * _ScatterRadius);
float3 scatter = IntegrateShadowScattering(penumbraLocation, penumbraWidth) * _Intensity;
if (_ApplyTonemap == 1)
{
scatter = FilmicTonemap(scatter);
}
_SSSLut[id.xy] = float4(scatter, 1.0);
}

View File

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

View File

@@ -0,0 +1,175 @@
using System.IO;
using UnityEditor;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;
using UnityEngine.UIElements;
namespace Misaki.HdrpToon.Editor
{
internal class SSSLutBakerView : UnityEditor.EditorWindow
{
public enum Quality
{
[InspectorName("64")]
UltraLow = 64,
[InspectorName("128")]
VeryLow = 128,
[InspectorName("256")]
Low = 256,
[InspectorName("512")]
Medium = 512,
[InspectorName("1024")]
High = 1024,
[InspectorName("2048")]
VeryHigh = 2048,
[InspectorName("4096")]
UltraHigh = 4096,
}
private const int _PREVIEW_SIZE = 128;
[SerializeField]
private VisualTreeAsset _visualAsset;
[SerializeField]
private ComputeShader _bakerShader;
private RenderTexture _previewTexture;
private RenderTextureDescriptor _previewDescriptor;
public bool isShadowLut;
public float scatterRadius = 1.0f;
public float positionShift = 0.0f;
public float intensity = 1.0f;
public Quality sampleCount = Quality.Low;
public bool applyTonemap = true;
public Quality outputResolution = Quality.Medium;
public int outputQuality = 100;
[MenuItem("Tools/UTS/SSS LUT Baker")]
private static void ShowWindow()
{
var window = GetWindow<SSSLutBakerView>(true, "SSS LUT Baker");
window.minSize = new Vector2(400, 650);
window.ShowUtility();
}
private void OnEnable()
{
_previewDescriptor = new RenderTextureDescriptor
{
width = _PREVIEW_SIZE,
height = _PREVIEW_SIZE,
volumeDepth = 1,
dimension = TextureDimension.Tex2D,
depthBufferBits = 0,
msaaSamples = 1,
graphicsFormat = GraphicsFormat.R8G8B8A8_UNorm,
enableRandomWrite = true,
sRGB = false,
useMipMap = false,
};
_previewTexture = RenderTexture.GetTemporary(_previewDescriptor);
}
private bool GenerateSSSLut(RenderTexture texture, int textureSize, bool production)
{
if (_bakerShader == null || !texture.enableRandomWrite)
{
return false;
}
var kernelIndex = isShadowLut ? 1 : 0;
_bakerShader.SetFloat("_ScatterRadius", scatterRadius);
_bakerShader.SetFloat("_PositionShift", positionShift);
_bakerShader.SetFloat("_Intensity", intensity);
_bakerShader.SetInt("_SampleCount", (int)sampleCount);
_bakerShader.SetInt("_ApplyTonemap", applyTonemap ? 1 : 0);
_bakerShader.SetInt("_TextureSize", textureSize);
_bakerShader.SetKeyword(new LocalKeyword(_bakerShader, "_PRODUCTION"), production);
_bakerShader.SetTexture(kernelIndex, "_SSSLut", texture);
const int groupSizeX = 8;
const int groupSizeY = 8;
var threadGroupX = (textureSize + (groupSizeX - 1)) / groupSizeX;
var threadGroupY = (textureSize + (groupSizeY - 1)) / groupSizeY;
_bakerShader.Dispatch(kernelIndex, threadGroupX, threadGroupY, 1);
return true;
}
private void BakePreview()
{
GenerateSSSLut(_previewTexture, _PREVIEW_SIZE, false);
}
private void Bake()
{
var outputPath = EditorUtility.SaveFilePanel("Export Texture", Application.dataPath, "SSS Lut", "jpg");
if (string.IsNullOrEmpty(outputPath))
{
return;
}
var outputDescriptor = _previewDescriptor;
outputDescriptor.width = (int)outputResolution;
outputDescriptor.height = (int)outputResolution;
var tempTexture = RenderTexture.GetTemporary(outputDescriptor);
var tempTexture2D = new Texture2D(outputDescriptor.width, outputDescriptor.height, TextureFormat.RGB24, false, true);
try
{
if (!GenerateSSSLut(tempTexture, (int)outputResolution, true))
{
return;
}
RenderTexture.active = tempTexture;
tempTexture2D.ReadPixels(new Rect(0, 0, outputDescriptor.width, outputDescriptor.height), 0, 0);
tempTexture2D.Apply();
RenderTexture.active = null;
File.WriteAllBytes(outputPath, tempTexture2D.EncodeToJPG(outputQuality));
AssetDatabase.Refresh();
}
finally
{
RenderTexture.ReleaseTemporary(tempTexture);
DestroyImmediate(tempTexture2D);
}
}
private void CreateGUI()
{
if (_visualAsset == null)
{
return;
}
var visualTree = _visualAsset.Instantiate();
visualTree.StretchToParentSize();
visualTree.dataSource = this;
var previewImage = visualTree.Q<Image>("preview-image");
previewImage.image = _previewTexture;
var previewButton = visualTree.Q<Button>("preview-button");
previewButton.clickable.clicked += BakePreview;
var bakeButton = visualTree.Q<Button>("bake-button");
bakeButton.clickable.clicked += Bake;
rootVisualElement.Add(visualTree);
}
private void OnDestroy()
{
RenderTexture.ReleaseTemporary(_previewTexture);
}
}
}

View File

@@ -1,11 +1,13 @@
fileFormatVersion: 2
guid: c2a5c3542255fad4b803f96cc141e84d
guid: 46ee5c2bb652c6942a58aa97f3a8473b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences:
- m_ViewDataDictionary: {instanceID: 0}
- IntegratorShader: {fileID: 7200000, guid: 0aa27def3e695d34d9e06b6015d57142, type: 3}
- _visualAsset: {fileID: 9197481963319205126, guid: 36e5f9eef212a0547b97e2643cd514de,
type: 3}
- _bakerShader: {fileID: 7200000, guid: 7bf3d5f03d1a012489a8f673afe8a6b3, type: 3}
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@@ -0,0 +1,54 @@
<engine:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:engine="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="True">
<engine:VisualElement data-source-type="Misaki.HdrpToon.Editor.SSSLutBakerView, Misaki.HdrpToon.Editor" style="flex-grow: 1; padding-top: 8px; padding-right: 8px; padding-bottom: 8px; padding-left: 8px;">
<engine:Label text="SSS Lut Baker" style="font-size: 18px; padding-top: 0; padding-right: 0; padding-bottom: 0; padding-left: 0; margin-top: 12px; margin-bottom: 8px; margin-left: 4px; margin-right: 6px; -unity-font-style: bold;" />
<engine:Label text="Parameters:" style="-unity-font-style: bold; margin-top: 12px; margin-bottom: 4px; margin-right: 2px; margin-left: 2px;" />
<engine:DropdownField label="Lut Type" choices="Skin,Shadow" index="0">
<Bindings>
<engine:DataBinding property="index" data-source-path="isShadowLut" binding-mode="TwoWay" />
</Bindings>
</engine:DropdownField>
<engine:FloatField label="Scatter Radius" value="1">
<Bindings>
<engine:DataBinding property="value" data-source-path="scatterRadius" binding-mode="TwoWay" />
</Bindings>
</engine:FloatField>
<engine:Slider label="Position Shift" value="0.0" low-value="-1" high-value="1" page-size="0.1" show-input-field="true">
<Bindings>
<engine:DataBinding property="value" data-source-path="positionShift" binding-mode="TwoWay" />
</Bindings>
</engine:Slider>
<engine:Slider label="Intensity" value="1" high-value="10" show-input-field="true" page-size="0.1">
<Bindings>
<engine:DataBinding property="value" data-source-path="intensity" binding-mode="TwoWay" />
</Bindings>
</engine:Slider>
<engine:EnumField label="Sample Count" value="Center" type="Misaki.HdrpToon.Editor.SSSLutBakerView+Quality, Misaki.HdrpToon.Editor">
<Bindings>
<engine:DataBinding property="value" binding-mode="TwoWay" data-source-path="sampleCount" />
</Bindings>
</engine:EnumField>
<engine:DropdownField label="Apply Tonemap" choices="Disable,Enable" index="0">
<Bindings>
<engine:DataBinding property="index" data-source-path="applyTonemap" binding-mode="TwoWay" />
</Bindings>
</engine:DropdownField>
<engine:EnumField label="Output Resolution" value="Center" type="Misaki.HdrpToon.Editor.SSSLutBakerView+Quality, Misaki.HdrpToon.Editor">
<Bindings>
<engine:DataBinding property="value" binding-mode="TwoWay" data-source-path="outputResolution" />
</Bindings>
</engine:EnumField>
<engine:SliderInt label="Output Quality" value="75" show-input-field="true" high-value="100" low-value="50">
<Bindings>
<engine:DataBinding property="value" data-source-path="outputQuality" binding-mode="TwoWay" />
</Bindings>
</engine:SliderInt>
<engine:Label text="Preview:" style="-unity-font-style: bold; margin-top: 12px; margin-bottom: 4px; margin-right: 2px; margin-left: 2px;" />
<engine:VisualElement style="flex-grow: 1; padding-top: 8px; padding-right: 8px; padding-bottom: 8px; padding-left: 8px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-top: 4px; margin-right: 4px; margin-bottom: 4px; margin-left: 4px;">
<engine:Image name="preview-image" style="flex-grow: 1;" />
</engine:VisualElement>
<engine:VisualElement style="flex-direction: row; margin-top: 4px;">
<engine:Button text="Preview" name="preview-button" style="flex-grow: 1; flex-basis: 0;" />
<engine:Button text="Bake" name="bake-button" style="flex-basis: 0; flex-grow: 1; background-color: rgb(70, 96, 124);" />
</engine:VisualElement>
</engine:VisualElement>
</engine:UXML>

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 36e5f9eef212a0547b97e2643cd514de
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}

View File

@@ -1,119 +0,0 @@
using UnityEditor;
using UnityEngine;
namespace EditorTools
{
public class SubsurfaceLookupTextureIntegratorWindow : EditorWindow
{
[MenuItem("Tools/Subsurface LUT Integrator", false, 1000)]
static void ShowIntegratorWindow()
{
GetWindow(typeof(SubsurfaceLookupTextureIntegratorWindow), false, "Subsurface LUT Integrator");
}
private Color FalloffColor = new Color(1.0f, 0.3f, 0.2f);
private float Radius = 4;
private bool KeepDirectBounce = false;
[SerializeField]
private ComputeShader IntegratorShader;
private RenderTexture IntegratedLUT = null;
private int resolution = 512;
private void OnEnable()
{
//IntegratorShader = AssetDatabase.LoadAssetAtPath<ComputeShader>("Assets/Scripts/Tools/Editor/SSS/SubsurfaceLookupTextureIntegrator.compute");
}
private void OnDestroy()
{
if (IntegratedLUT != null)
{
RenderTexture.ReleaseTemporary(IntegratedLUT);
}
}
void OnGUI()
{
GUILayout.Label("Base Settings", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
FalloffColor = EditorGUILayout.ColorField("Fallof Color", FalloffColor);
Radius = EditorGUILayout.Slider("Radius", Radius, 0, 20);
KeepDirectBounce = EditorGUILayout.Toggle("Keep Direct Bounce", KeepDirectBounce);
resolution = EditorGUILayout.IntField("Resolution", resolution);
if (EditorGUI.EndChangeCheck())
{
Bake();
}
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Bake") && IntegratorShader != null)
{
Bake();
}
if (GUILayout.Button("Save") && IntegratedLUT != null)
{
IntegratorShader.SetFloat("_Resoultion", (float)resolution);
RenderTexture rt = RenderTexture.GetTemporary(resolution, resolution, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
Graphics.Blit(IntegratedLUT, rt);
RenderTexture.active = rt;
Texture2D tex = new Texture2D(resolution, resolution, TextureFormat.ARGB32, false, true);
tex.ReadPixels(new Rect(0, 0, resolution, resolution), 0, 0);
RenderTexture.active = null;
RenderTexture.ReleaseTemporary(rt);
string path = EditorUtility.SaveFilePanel("Export Texture", Application.dataPath, "SSS_Lut", "png");
if (path == null) return;
System.IO.File.WriteAllBytes(path, tex.EncodeToPNG());
AssetDatabase.Refresh();
IntegratorShader.SetFloat("_Resoultion", (float)resolution);
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
float width = position.width - 100;
float height = position.height - 189;
float sacle = width > height ? height / resolution : width / resolution;
Rect rect = new Rect(50, 150, resolution * sacle, resolution * sacle);
if (IntegratedLUT != null)
{
EditorGUI.DrawPreviewTexture(rect, IntegratedLUT);
}
else
{
EditorGUI.DrawRect(rect, Color.black);
}
}
private void Bake()
{
if (IntegratedLUT != null)
{
RenderTexture.ReleaseTemporary(IntegratedLUT);
}
IntegratedLUT = RenderTexture.GetTemporary(resolution, resolution, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
IntegratedLUT.enableRandomWrite = true;
if (KeepDirectBounce)
{
IntegratorShader.EnableKeyword("KEEP_DIRECT_BOUNCE");
}
else
{
IntegratorShader.DisableKeyword("KEEP_DIRECT_BOUNCE");
}
IntegratorShader.SetTexture(0, "_IntegratedLUT", IntegratedLUT);
IntegratorShader.SetVector("_FalloffColor", FalloffColor);
IntegratorShader.SetFloat("_Radius", Radius);
IntegratorShader.SetFloat("_Resoultion", (float)resolution);
IntegratorShader.Dispatch(0, resolution / 8, resolution / 8, 1);
}
}
}

View File

@@ -38,11 +38,10 @@ The HDRP Toon Shader is designed to provide a high-quality toon shading effect f
3. Apply the material to your 3D models.
4. Adjust the shader parameters in the material inspector to achieve the desired look.
## Examples
## Example
Here are some examples of the HDRP Toon Shader in action:
![preview-01.png](https://s2.loli.net/2024/12/26/zHdfSXho4csURyx.png)
![preview-01.png](https://i.postimg.cc/nV3fT2PR/Screenshot-2025-05-13-212926.png)
## Contributing

View File

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

View File

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

View File

@@ -0,0 +1,148 @@
namespace Misaki.HdrpToon
{
internal static class UTSPropertyName
{
public static class InternalProperties
{
public const string SURFACE_TYPE = "_SurfaceType";
public const string DOUBLE_SIDED_CONSTANTS = "_DoubleSidedConstants";
public const string TRANSPARENT_DEPTH_PREPASS_ENABLE = "_TransparentDepthPrepassEnable";
public const string TRANSPARENT_BACKFACE_ENABLE = "_TransparentBackfaceEnable";
public const string TRANSPARENT_DEPTH_POSTPASS_ENABLE = "_TransparentDepthPostpassEnable";
public const string TRANSPARENT_CULL_MODE = "_TransparentCullMode";
public const string OPAQUE_CULL_MODE = "_OpaqueCullMode";
public const string SRC_BLEND = "_SrcBlend";
public const string DEST_BLEND = "_DstBlend";
public const string DEST_BLEND2 = "_DstBlend2";
public const string ALPHA_SRC_BLEND = "_AlphaSrcBlend";
public const string ALPHA_DEST_BLEND = "_AlphaDstBlend";
public const string CULL_MODE_FORWARD = "_CullModeForward";
public const string ZTEST_GBUFFER = "_ZTestGBuffer";
public const string ZTEST_DEPTH_EQUAL_FOR_OPAQUE = "_ZTestDepthEqualForOpaque";
public const string ZTEST_TRANSPARENT = "_ZTestTransparent";
public const string ZWRITE = "_ZWrite";
public const string STENCIL_REF = "_StencilRef";
public const string STENCIL_WRITE_MASK = "_StencilWriteMask";
public const string STENCIL_REF_DEPTH = "_StencilRefDepth";
public const string STENCIL_WRITE_MASK_DEPTH = "_StencilWriteMaskDepth";
public const string STENCIL_REF_G_BUFFER = "_StencilRefGBuffer";
public const string STENCIL_WRITE_MASK_G_BUFFER = "_StencilWriteMaskGBuffer";
public const string STENCIL_REF_MV = "_StencilRefMV";
public const string STENCIL_WRITE_MASK_MV = "_StencilWriteMaskMV";
public const string STENCIL_REF_DISTORTION_VEC = "_StencilRefDistortionVec";
public const string STENCIL_WRITE_MASK_DISTORTION_VEC = "_StencilWriteMaskDistortionVec";
}
public static class SurfaceOptions
{
public const string SURFACE_TYPE = "_SurfaceType";
public const string FOG_ON_TRANSPARENT = "_FogOnTransparent";
public const string TRANSPARENT_DEPTH_PREPASS_ENABLE = "_TransparentDepthPrepassEnable";
public const string TRANSPARENT_BACKFACE_ENABLE = "_TransparentBackfaceEnable";
public const string TRANSPARENT_DEPTH_POSTPASS_ENABLE = "_TransparentDepthPostpassEnable";
public const string TRANSPARENT_Z_WRITE = "_TransparentZWrite";
public const string RECEIVES_SSR_TRANSPARENT = "_ReceivesSSRTransparent";
public const string TRANSPARENT_WRITING_MOTION_VEC = "_TransparentWritingMotionVec";
public const string ALPHA_CLIP_ENABLE = "_AlphaCutoffEnable";
public const string ALPHA_CUTOFF = "_AlphaCutoff";
public const string CULL_MODE = "_CullMode";
public const string DOUBLE_SIDED_NORMAL_MODE = "_DoubleSidedNormalMode";
public const string SHADING_MODE = "_Shading_Mode";
public const string MATERIAL_TYPE = "_Material_Type";
public const string PBR_MODE = "_PBR_Mode";
public const string HAIR_BLENDING_TARGET = "_HairBlendingTarget";
public const string SURFACE_FEATURE = "_SurfaceFeatures";
}
public static class SurfaceInputs
{
public const string EMISSIVE_COLOR = "_EmissiveColor";
public const string EMISSIVE_COLOR_LDR = "_EmissiveColorLDR";
public const string EMISSIVE_COLOR_MAP = "_EmissiveColorMap";
public const string ALBEDO_AFFECT_EMISSIVE = "_AlbedoAffectEmissive";
public const string EMISSIVE_INTENSITY = "_EmissiveIntensity";
public const string EMISSIVE_EXPOSURE_WEIGHT = "_EmissiveExposureWeight";
}
public static class AngelRing
{
public const string ANGEL_RING_COLOR = "_AngelRingColor";
public const string ANGEL_RING_COLOR_MAP = "_AngelRingColorMap";
public const string ANGEL_RING_INTENSITY = "_AngelRingIntensity";
public const string ANGEL_RING_OFFSET_U = "_AngelRingOffsetU";
public const string ANGEL_RING_OFFSET_V = "_AngelRingOffsetV";
}
public static class RimLight
{
public const string RIM_LIGHT_COLOR = "_RimLightColor";
public const string RIM_LIGHT_INTENSITY = "_RimLightIntensity";
public const string ALBEDO_AFFECT_RIM_LIGHT = "_AlbedoAffectRimLight";
public const string SCREEN_SPACE_RIM_LIGHT = "_Screen_Space_Rim_Light";
public const string RIM_LIGHT_LEVEL = "_RimLightLevel";
public const string LIGHT_BASE_RIM_LIGHT = "_Light_Base_Rim_Light";
public const string LIGHT_DIRECTION_RIM_LIGHT_LEVEL = "_LightDirectionRimLightLevel";
public const string COLOR_BLENDING_MODE = "_Is_BlendAddToRimColor";
public const string RIM_LIGHT_CLIPPING = "_RimLightClipping";
public const string RIM_LIGHT_CLIPPING_LEVEL = "_RimLightClippingLevel";
public const string LIGHT_DIRECTION = "_LightDirection_MaskOn";
public const string INVERTED_DIRECTION_RIM_LIGHT = "_Add_Antipodean_RimLight";
public const string INVERTED_RIM_LIGHT_COLOR = "_Ap_RimLightColor";
public const string INVERSED_RIM_LIGHT_LEVEL = "_Ap_RimLight_Power";
public const string INVERTED_RIM_LIGHT_FEATHER_OFF = "_Ap_RimLight_FeatherOff";
public const string RIM_LIGHT_MASK_MAP = "_Set_RimLightMask";
public const string RIM_LIGHT_MASK_LEVEL = "_Tweak_RimLightMaskLevel";
}
public static class Stocking
{
public const string STOCKING_FRESNEL_WIDTH = "_StockingFresnelWidth";
public const string STOCKING_SPARKLE_SPACING = "_StockingSparkleSpacing";
public const string STOCKING_SPARKLE_AMOUNT = "_StockingSparkleAmount";
public const string STOCKING_SPARKLE_SIZE = "_StockingSparkleSize";
public const string STOCKING_SPARKLE_INTENSITY = "_StockingSparkleIntensity";
}
public static class Outline
{
public const string OUTLINE_STATE = "_OutlineState";
public const string OUTLINE_WIDTH = "_OutlineWidth";
public const string OUTLINE_WIDTH_MAP = "_OutlineWidthMap";
public const string OUTLINE_COLOR = "_OutlineColor";
public const string OUTLINE_COLOR_MAP = "_OutlineColorMap";
public const string ALBEDO_AFFECT_OUTLINE = "_AlbedoAffectOutline";
public const string SKY_COLOR_AFFECT_OUTLINE = "_SkyColorAffectOutline";
public const string SKY_COLOR_INTENSITY = "_SkyColorIntensity";
public const string OUTLINE_FADE_IN = "_OutlineFadeIn";
public const string OUTLINE_FADE_OUT = "_OutlineFadeOut";
public const string USE_SMOOTHED_NORMAL = "_UseSmoothedNormal";
}
public static class Advance
{
public const string MINIMAL_DIFFUSE_CONTRIBUTION = "_Minimal_Diffuse_Contribution";
public const string LIGHT_INTENSITY_MULTIPLIER = "_LightIntensityMultiplier";
public const string CLAMP_LIGHT_COLOR = "_ClampLightColor";
public const string LIGHT_LOOP_MODE = "_Light_Loop_Mode";
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,54 @@
namespace Misaki.HdrpToon
{
internal enum SurfaceType
{
Opaque,
Transparent
}
internal enum DoubleSidedMode
{
None,
Mirror,
Flip
}
internal enum ShadingMode
{
Standard,
SDF
}
internal enum MaterialType
{
Standard,
FrontHair,
Face,
Eye
}
internal enum PBRMode
{
Off,
Standard,
Anisotropy,
Hair,
Fabric,
Toon
}
internal enum IndirectDiffuseMode
{
Off,
IBL,
Matcap,
Ramp
}
internal enum IndirectSpecularMode
{
Off,
IBL,
Matcap
}
}

View File

@@ -1,8 +0,0 @@
namespace Misaki.HdrpToon
{
internal enum ShadingMode
{
Standard,
SDF,
}
}

View File

@@ -5,12 +5,11 @@ namespace Misaki.HdrpToon
{
[Flags]
[GenerateHLSL(PackingRules.Exact)]
public enum SurfaceFeatureFlags : uint
public enum SurfaceFeature
{
None = 0,
RimLight = 1 << 0,
Stocking = 1 << 1,
AngelRing = 1 << 2,
Outline = 1 << 3,
AngelRing = 1 << 0,
RimLight = 1 << 1,
Stocking = 1 << 2,
}
}

View File

@@ -0,0 +1,16 @@
//
// This file was automatically generated. Please don't edit by hand. Execute Editor command [ Edit > Rendering > Generate Shader Includes ] instead
//
#ifndef SURFACEFEATURE_CS_HLSL
#define SURFACEFEATURE_CS_HLSL
//
// Misaki.HdrpToon.SurfaceFeature: static fields
//
#define SURFACEFEATURE_NONE (0)
#define SURFACEFEATURE_ANGEL_RING (1)
#define SURFACEFEATURE_RIM_LIGHT (2)
#define SURFACEFEATURE_STOCKING (4)
#endif

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: ec297400b1508d647a7cdbad2c0edf40
guid: 1ae94e9055342d643a02bd5b4a9fa20b
ShaderIncludeImporter:
externalObjects: {}
userData:

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 598a7ef5d67c6334ca8f930f37ea989b

View File

@@ -1,17 +0,0 @@
//
// This file was automatically generated. Please don't edit by hand. Execute Editor command [ Edit > Rendering > Generate Shader Includes ] instead
//
#ifndef SURFACEFEATUREFLAGS_CS_HLSL
#define SURFACEFEATUREFLAGS_CS_HLSL
//
// Misaki.HdrpToon.SurfaceFeatureFlags: static fields
//
#define SURFACEFEATUREFLAGS_NONE (0)
#define SURFACEFEATUREFLAGS_RIM_LIGHT (1)
#define SURFACEFEATUREFLAGS_STOCKING (2)
#define SURFACEFEATUREFLAGS_ANGEL_RING (4)
#define SURFACEFEATUREFLAGS_OUTLINE (8)
#endif

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 737ea728a50a7664b90cba3dd3e21249

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -50,6 +50,56 @@ float3 UtsComputeDiffuseColor(float3 baseColor, float metallic)
return UtsComputeDiffuseColor(baseColor, metallic, 0.0);
}
float Random(float2 uv)
{
return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453);
}
inline float2 voronoi_noise_random_vector (float2 UV, float offset)
{
float2x2 m = float2x2(15.27, 47.63, 99.41, 89.98);
UV = frac(sin(mul(UV, m)) * 46839.32);
return float2(sin(UV.y*+offset)*0.5+0.5, cos(UV.x*offset)*0.5+0.5);
}
float Voronoi(float2 UV, float AngleOffset, float CellDensity)
{
float2 g = floor(UV * CellDensity);
float2 f = frac(UV * CellDensity);
float t = 8.0;
float res = 8.0;
for(int y=-1; y<=1; y++)
{
for(int x=-1; x<=1; x++)
{
float2 lattice = float2(x,y);
float2 offset = voronoi_noise_random_vector(lattice + g, AngleOffset);
float d = distance(lattice + offset, f);
if(d < res)
{
res = d;
}
}
}
return res;
}
float Dither(float In, float4 positionSS)
{
float2 uv = positionSS.xy;
float DITHER_THRESHOLDS[16] =
{
1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0,
13.0 / 17.0, 5.0 / 17.0, 15.0 / 17.0, 7.0 / 17.0,
4.0 / 17.0, 12.0 / 17.0, 2.0 / 17.0, 10.0 / 17.0,
16.0 / 17.0, 8.0 / 17.0, 14.0 / 17.0, 6.0 / 17.0
};
uint index = (uint(uv.x) % 4) * 4 + uint(uv.y) % 4;
return In - DITHER_THRESHOLDS[index];
}
#define SampleRampSignalLine(texture, u) (SAMPLE_TEXTURE2D_LOD(texture, s_linear_clamp_sampler, float2(u, 0.5), 0))
// Exposure

View File

@@ -1,20 +1,17 @@
//Unity Toon Shader/HDRP
//nobuyuki@unity3d.com
//toshiyuki@unity3d.com (Universal RP/HDRP)
#ifndef UCTS_HDRP_INCLUDED
#define UCTS_HDRP_INCLUDED
#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Common/UtsCommon.hlsl"
#define UTS_LAYER_VISIBILITY
#ifndef DIRECTIONAL
# define DIRECTIONAL
#endif
#define FP_BUFFER 1
#if _PBR_MODE_OFF
#undef _MASKMAP
#undef _ANISOTROPYMAP
#undef _SPECULARCOLORMAP
#endif
#if defined(UNITY_PASS_PREPASSBASE) || defined(UNITY_PASS_DEFERRED) || defined(UNITY_PASS_SHADOWCASTER)
#undef FOG_LINEAR
@@ -24,11 +21,6 @@
#define Uts_ColorSpaceDielectricSpec half4(0.04, 0.04, 0.04, 1.0 - 0.04)
#if 1
struct UTSData
{
};
struct UTSSurfaceData
{
@@ -82,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;
@@ -116,7 +126,7 @@ UTSSurfaceData GetUTSSurfaceData(FragInputs input, float3 V)
output.baseColor = mainTexture.rgb * _BaseColor.rgb;
output.alpha = mainTexture.a;
#if _USE_RAMP_COLOR_MAP_ON
#if _USE_SHADING_RAMP_MAP_ON
output.firstShadingColor = 0.0;
output.secondShadingColor = 0.0;
#else
@@ -131,12 +141,12 @@ UTSSurfaceData GetUTSSurfaceData(FragInputs input, float3 V)
#endif
float4 normalLocal = float4(0, 0, 1.0, 1.0);
#if _NORMAL_MAP
if (_Use_SSSLut)
{
normalLocal = SAMPLE_TEXTURE2D_LOD(_NormalMap, sampler_NormalMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap), _SSSIntensity);
}
else
#if _NORMALMAP
// if (_Use_SSSLut)
// {
// normalLocal = SAMPLE_TEXTURE2D_LOD(_NormalMap, sampler_NormalMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap), _SSSIntensity);
// }
// else
{
normalLocal = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap));
normalLocal.rgb = UnpackNormalScale(normalLocal, _NormalScale);
@@ -154,7 +164,7 @@ UTSSurfaceData GetUTSSurfaceData(FragInputs input, float3 V)
float3 specularColor = 1;
float anisotropy = 0;
#ifdef _MASK_MAP
#ifdef _MASKMAP
float4 _MaskMap_var = SAMPLE_TEXTURE2D(_MaskMap, sampler_MaskMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap));
metallic = _MaskMap_var.x;
metallic = lerp(_MetallicRemapMin, _MetallicRemapMax, metallic);
@@ -164,7 +174,7 @@ UTSSurfaceData GetUTSSurfaceData(FragInputs input, float3 V)
smoothness = lerp(_SmoothnessRemapMin, _SmoothnessRemapMax, smoothness);
#endif
#ifdef _ANISOTROPY_MAP
#ifdef _ANISOTROPYMAP
anisotropy = SAMPLE_TEXTURE2D(_AnisotropyMap, sampler_AnisotropyMap, TRANSFORM_TEX(input.texCoord0, _AnisotropyMap)).r;
#if _PBR_Mode_KK
anisotropy += _Anisotropy - 0.5;
@@ -181,11 +191,13 @@ UTSSurfaceData GetUTSSurfaceData(FragInputs input, float3 V)
smoothness *=_BSDFContribution;
#endif
#ifdef _PBR_Mode_TOON
#ifdef _SPECULAR_COLOR_MAP
specularColor = SAMPLE_TEXTURE2D(_SpecularColorMap, sampler_SpecularColorMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap)).rgb * _SpecularColor;
// TODO: Specular color is not handle correctly.
#ifdef _PBR_MODE_TOON
metallic = 0.0;
specularColor = _SpecularColor;
#ifdef _SPECULARCOLORMAP
specularColor *= SAMPLE_TEXTURE2D(_SpecularColorMap, sampler_SpecularColorMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap)).rgb;
#endif
specularColor = GetSpecularColor(_MainTex_var.rgb * _BaseColor.rgb, metallic);
#endif
output.metallic = metallic;
@@ -198,7 +210,8 @@ UTSSurfaceData GetUTSSurfaceData(FragInputs input, float3 V)
output.geomNormalWS = input.tangentToWorld[2];
output.tangentWS = Orthonormalize(input.tangentToWorld[0].rgb, normalWS);
output.subsurfaceColor = SAMPLE_TEXTURE2D(_SSSLutMap, sampler_MainTex, TRANSFORM_TEX(input.texCoord0, _BaseColorMap)) * _SSSIntensity;
// output.subsurfaceColor = SAMPLE_TEXTURE2D(_SSSLutMap, s_linear_clamp_sampler, TRANSFORM_TEX(input.texCoord0, _BaseColorMap)) * _SSSIntensity;
output.subsurfaceColor = 0.0;
output.anisotropy = anisotropy;
@@ -211,12 +224,19 @@ UtsBSDFData ConvertUTSSurfaceDataToUTSBSDFData(UTSSurfaceData surfaceData)
output.surfaceFeatures = surfaceData.surfaceFeatures;
output.diffuseColor = UtsComputeDiffuseColor(surfaceData.baseColor, surfaceData.metallic, 0.05);
output.firstShadingDiffuseColor = UtsComputeDiffuseColor(surfaceData.firstShadingColor, surfaceData.metallic, 0.05);
output.secondShadingDiffuseColor = UtsComputeDiffuseColor(surfaceData.secondShadingColor, surfaceData.metallic, 0.05);
#if _PBR_MODE_TOON
float m = Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b);
#else
float m = surfaceData.metallic;
#endif
output.diffuseColor = UtsComputeDiffuseColor(surfaceData.baseColor, m, _Minimal_Diffuse_Contribution);
output.firstShadingDiffuseColor = UtsComputeDiffuseColor(surfaceData.firstShadingColor, m, _Minimal_Diffuse_Contribution);
output.secondShadingDiffuseColor = UtsComputeDiffuseColor(surfaceData.secondShadingColor, m, _Minimal_Diffuse_Contribution);
#if _PBR_MODE_OFF
output.fresnel0 = surfaceData.baseColor;
output.fresnel0 = 0.22;
#elif _PBR_MODE_TOON
output.fresnel0 = surfaceData.specularColor;
#else
output.fresnel0 = ComputeFresnel0(surfaceData.baseColor, surfaceData.metallic, 0.22);
#endif
@@ -457,8 +477,6 @@ inline float3 LinearToGammaSpace(float3 linRGB)
#define UNITY_APPLY_FOG(coord,col) UNITY_APPLY_FOG_COLOR(coord,col,unity_FogColor)
#endif
#endif //#if false
#ifdef DIRECTIONAL
#define LIGHTING_COORDS(idx1,idx2) SHADOW_COORDS(idx1)
#define TRANSFER_VERTEX_TO_FRAGMENT(a) TRANSFER_SHADOW(a)

View File

@@ -0,0 +1,393 @@
#ifndef UTS_LIT_DATA
#define UTS_LIT_DATA
float UtsGetSurfaceData(FragInputs input, LayerTexCoord layerTexCoord, out SurfaceData surfaceData,
out float3 normalTS, out float3 bentNormalTS)
{
float3 detailNormalTS = float3(0.0, 0.0, 0.0);
float detailMask = 0.0;
#ifdef _DETAIL_MAP_IDX
detailMask = 1.0;
#ifdef _MASKMAP_IDX
detailMask = SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_MaskMap), SAMPLER_MASKMAP_IDX, ADD_IDX(layerTexCoord.base)).b;
#endif
float2 detailAlbedoAndSmoothness = SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_DetailMap), SAMPLER_DETAILMAP_IDX, ADD_IDX(layerTexCoord.details)).rb;
float detailAlbedo = detailAlbedoAndSmoothness.r * 2.0 - 1.0;
float detailSmoothness = detailAlbedoAndSmoothness.g * 2.0 - 1.0;
// Resample the detail map but this time for the normal map. This call should be optimize by the compiler
// We split both call due to trilinear mapping
detailNormalTS = SAMPLE_UVMAPPING_NORMALMAP_AG(ADD_IDX(_DetailMap), SAMPLER_DETAILMAP_IDX, ADD_IDX(layerTexCoord.details), ADD_IDX(_DetailNormalScale));
#endif
float4 color = SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_BaseColorMap), ADD_ZERO_IDX(sampler_BaseColorMap),
ADD_IDX(layerTexCoord.base)).rgba * ADD_IDX(_BaseColor).rgba;
surfaceData.baseColor = color.rgb;
float alpha = 1.0f;
#ifdef DEBUG_DISPLAY
if (_DebugMipMapMode == DEBUGMIPMAPMODE_NONE)
#endif
{
alpha = color.a;
alpha = lerp(ADD_IDX(_AlphaRemapMin), ADD_IDX(_AlphaRemapMax), alpha);
}
#ifdef _DETAIL_MAP_IDX
// Goal: we want the detail albedo map to be able to darken down to black and brighten up to white the surface albedo.
// The scale control the speed of the gradient. We simply remap detailAlbedo from [0..1] to [-1..1] then perform a lerp to black or white
// with a factor based on speed.
// For base color we interpolate in sRGB space (approximate here as square) as it get a nicer perceptual gradient
float albedoDetailSpeed = saturate(abs(detailAlbedo) * ADD_IDX(_DetailAlbedoScale));
float3 baseColorOverlay = lerp(sqrt(surfaceData.baseColor), (detailAlbedo < 0.0) ? float3(0.0, 0.0, 0.0) : float3(1.0, 1.0, 1.0), albedoDetailSpeed * albedoDetailSpeed);
baseColorOverlay *= baseColorOverlay;
// Lerp with details mask
surfaceData.baseColor = lerp(surfaceData.baseColor, saturate(baseColorOverlay), detailMask);
#endif
surfaceData.specularOcclusion = 1.0; // Will be setup outside of this function
surfaceData.normalWS = float3(0.0, 0.0, 0.0);
// Need to init this to keep quiet the compiler, but this is overriden later (0, 0, 0) so if we forget to override the compiler may comply.
surfaceData.geomNormalWS = float3(0.0, 0.0, 0.0); // Not used, just to keep compiler quiet.
normalTS = ADD_IDX(GetNormalTS)(input, layerTexCoord, detailNormalTS, detailMask);
bentNormalTS = ADD_IDX(GetBentNormalTS)(input, layerTexCoord, normalTS, detailNormalTS, detailMask);
#if _PBR_MODE_OFF
surfaceData.perceptualSmoothness = 0.0;
#else
#if defined(_MASKMAP_IDX)
surfaceData.perceptualSmoothness = SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_MaskMap), SAMPLER_MASKMAP_IDX, ADD_IDX(layerTexCoord.base)).a;
surfaceData.perceptualSmoothness = lerp(ADD_IDX(_SmoothnessRemapMin), ADD_IDX(_SmoothnessRemapMax), surfaceData.perceptualSmoothness);
#else
surfaceData.perceptualSmoothness = ADD_IDX(_Smoothness);
#endif
#endif
#ifdef _DETAIL_MAP_IDX
// See comment for baseColorOverlay
float smoothnessDetailSpeed = saturate(abs(detailSmoothness) * ADD_IDX(_DetailSmoothnessScale));
float smoothnessOverlay = lerp(surfaceData.perceptualSmoothness, (detailSmoothness < 0.0) ? 0.0 : 1.0, smoothnessDetailSpeed);
// Lerp with details mask
surfaceData.perceptualSmoothness = lerp(surfaceData.perceptualSmoothness, saturate(smoothnessOverlay), detailMask);
#endif
#if _PBR_MODE_OFF
surfaceData.metallic = 0.0;
surfaceData.ambientOcclusion = 1.0;
#else
// MaskMap is RGBA: Metallic, Ambient Occlusion (Optional), detail Mask (Optional), Smoothness
#ifdef _MASKMAP_IDX
surfaceData.metallic = SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_MaskMap), SAMPLER_MASKMAP_IDX, ADD_IDX(layerTexCoord.base)).r;
surfaceData.metallic = lerp(ADD_IDX(_MetallicRemapMin), ADD_IDX(_MetallicRemapMax), surfaceData.metallic);
surfaceData.ambientOcclusion = SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_MaskMap), SAMPLER_MASKMAP_IDX, ADD_IDX(layerTexCoord.base)).g;
surfaceData.ambientOcclusion = lerp(ADD_IDX(_AORemapMin), ADD_IDX(_AORemapMax), surfaceData.ambientOcclusion);
#else
surfaceData.metallic = ADD_IDX(_Metallic);
surfaceData.ambientOcclusion = 1.0;
#endif
#endif
surfaceData.diffusionProfileHash = asuint(ADD_IDX(_DiffusionProfileHash));
surfaceData.subsurfaceMask = ADD_IDX(_SubsurfaceMask);
surfaceData.transmissionMask = ADD_IDX(_TransmissionMask);
#ifdef _SUBSURFACE_MASK_MAP_IDX
surfaceData.subsurfaceMask *= SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_SubsurfaceMaskMap), SAMPLER_SUBSURFACE_MASK_MAP_IDX, ADD_IDX(layerTexCoord.base)).r;
#endif
#ifdef _TRANSMISSION_MASK_MAP_IDX
surfaceData.transmissionMask *= SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_TransmissionMaskMap), SAMPLER_TRANSMISSION_MASK_MAP_IDX, ADD_IDX(layerTexCoord.base)).r;
#endif
#ifdef _THICKNESSMAP_IDX
surfaceData.thickness = SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_ThicknessMap), SAMPLER_THICKNESSMAP_IDX, ADD_IDX(layerTexCoord.base)).r;
surfaceData.thickness = ADD_IDX(_ThicknessRemap).x + ADD_IDX(_ThicknessRemap).y * surfaceData.thickness;
#else
surfaceData.thickness = ADD_IDX(_Thickness);
#endif
// This part of the code is not used in case of layered shader but we keep the same macro system for simplicity
#if !defined(LAYERED_LIT_SHADER)
// These static material feature allow compile time optimization
surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;
#ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;
#endif
#ifdef _MATERIAL_FEATURE_TRANSMISSION
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;
#endif
#ifdef _MATERIAL_FEATURE_ANISOTROPY
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;
#endif
#ifdef _MATERIAL_FEATURE_CLEAR_COAT
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;
#endif
#ifdef _MATERIAL_FEATURE_IRIDESCENCE
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;
#endif
#ifdef _MATERIAL_FEATURE_SPECULAR_COLOR
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;
#endif
#ifdef _TANGENTMAP
#ifdef _NORMALMAP_TANGENT_SPACE_IDX // Normal and tangent use same space
// Tangent space vectors always use only 2 channels.
float3 tangentTS = UnpackNormalmapRGorAG(SAMPLE_UVMAPPING_TEXTURE2D(_TangentMap, sampler_TangentMap, layerTexCoord.base), 1.0);
surfaceData.tangentWS = TransformTangentToWorld(tangentTS, input.tangentToWorld);
#else // Object space
// Note: There is no such a thing like triplanar with object space normal, so we call directly 2D function
float3 tangentOS = UnpackNormalRGB(SAMPLE_TEXTURE2D(_TangentMapOS, sampler_TangentMapOS, layerTexCoord.base.uv), 1.0);
surfaceData.tangentWS = TransformObjectToWorldNormal(tangentOS);
#endif
#else
// Note we don't normalize tangentWS either with a tangentmap above or using the interpolated tangent from the TBN frame
// as it will be normalized later with a call to Orthonormalize():
surfaceData.tangentWS = input.tangentToWorld[0].xyz;
// The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT
#endif
#ifdef _ANISOTROPYMAP
surfaceData.anisotropy = SAMPLE_UVMAPPING_TEXTURE2D(_AnisotropyMap, sampler_AnisotropyMap, layerTexCoord.base).r;
#else
surfaceData.anisotropy = 1.0;
#endif
surfaceData.anisotropy *= ADD_IDX(_Anisotropy);
surfaceData.specularColor = _SpecularColor.rgb;
#ifdef _SPECULARCOLORMAP
surfaceData.specularColor *= SAMPLE_UVMAPPING_TEXTURE2D(_SpecularColorMap, sampler_SpecularColorMap, layerTexCoord.base).rgb;
#endif
#ifdef _MATERIAL_FEATURE_SPECULAR_COLOR
// Require to have setup baseColor
// Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it
surfaceData.baseColor *= _EnergyConservingSpecularColor > 0.0 ? (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b)) : 1.0;
#endif
#if HAS_REFRACTION
if (_EnableSSRefraction)
{
surfaceData.ior = _Ior;
surfaceData.transmittanceColor = _TransmittanceColor;
#ifdef _TRANSMITTANCECOLORMAP
surfaceData.transmittanceColor *= SAMPLE_UVMAPPING_TEXTURE2D(_TransmittanceColorMap, sampler_TransmittanceColorMap, ADD_IDX(layerTexCoord.base)).rgb;
#endif
surfaceData.atDistance = _ATDistance;
// Rough refraction don't use opacity. Instead we use opacity as a transmittance mask.
surfaceData.transmittanceMask = (1.0 - alpha);
alpha = 1.0;
}
else
{
surfaceData.ior = 1.0;
surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);
surfaceData.atDistance = 1.0;
surfaceData.transmittanceMask = 0.0;
alpha = 1.0;
}
#else
surfaceData.ior = 1.0;
surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);
surfaceData.atDistance = 1.0;
surfaceData.transmittanceMask = 0.0;
#endif
#ifdef _MATERIAL_FEATURE_CLEAR_COAT
surfaceData.coatMask = _CoatMask;
// To shader feature for keyword to limit the variant
surfaceData.coatMask *= SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_CoatMaskMap), ADD_ZERO_IDX(sampler_CoatMaskMap), ADD_IDX(layerTexCoord.base)).r;
#else
surfaceData.coatMask = 0.0;
#endif
#ifdef _MATERIAL_FEATURE_IRIDESCENCE
#ifdef _IRIDESCENCE_THICKNESSMAP
surfaceData.iridescenceThickness = SAMPLE_UVMAPPING_TEXTURE2D(_IridescenceThicknessMap, sampler_IridescenceThicknessMap, layerTexCoord.base).r;
surfaceData.iridescenceThickness = _IridescenceThicknessRemap.x + _IridescenceThicknessRemap.y * surfaceData.iridescenceThickness;
#else
surfaceData.iridescenceThickness = _IridescenceThickness;
#endif
surfaceData.iridescenceMask = _IridescenceMask;
surfaceData.iridescenceMask *= SAMPLE_UVMAPPING_TEXTURE2D(_IridescenceMaskMap, sampler_IridescenceMaskMap, layerTexCoord.base).r;
#else
surfaceData.iridescenceThickness = 0.0;
surfaceData.iridescenceMask = 0.0;
#endif
#else // #if !defined(LAYERED_LIT_SHADER)
// Mandatory to setup value to keep compiler quiet
// Layered shader material feature are define outside of this call
surfaceData.materialFeatures = 0;
// All these parameters are ignore as they are re-setup outside of the layers function
// Note: any parameters set here must also be set in GetSurfaceAndBuiltinData() layer version
surfaceData.tangentWS = float3(0.0, 0.0, 0.0);
surfaceData.anisotropy = 0.0;
surfaceData.specularColor = float3(0.0, 0.0, 0.0);
surfaceData.iridescenceThickness = 0.0;
surfaceData.iridescenceMask = 0.0;
surfaceData.coatMask = 0.0;
// Transparency
surfaceData.ior = 1.0;
surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);
surfaceData.atDistance = 1000000.0;
surfaceData.transmittanceMask = 0.0;
#endif // #if !defined(LAYERED_LIT_SHADER)
return alpha;
}
void UtsGetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData,
out BuiltinData builtinData RAY_TRACING_OPTIONAL_PARAMETERS)
{
// Fix case 1210058. With Lit.shader / LayeredLit.shader we always have UV1. But in the case of some SpeedTree mesh, there is no stream sent
// and UV1 is corrupt when we use surface gradient. In case UV1 aren't required we set them to 0, so we ensure there is no garbage.
// When using lightmaps, the uv1 is always valid but we don't update _UVMappingMask.y to 1
// So when we are using them, we just need to keep the UVs as is.
#if !defined(LIGHTMAP_ON) && defined(SURFACE_GRADIENT)
input.texCoord1 = (_UVMappingMask.y + _UVDetailsMappingMask.y + _UVMappingMaskEmissive.y) > 0 ? input.texCoord1 : 0;
#endif
// Don't dither if displaced tessellation (we're fading out the displacement instead to match the next LOD)
#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)
#ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group
LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);
#endif
#endif
float3 doubleSidedConstants = GetDoubleSidedConstants();
ApplyDoubleSidedFlipOrMirror(input, doubleSidedConstants); // Apply double sided flip on the vertex normal
LayerTexCoord layerTexCoord;
ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);
GetLayerTexCoord(input, layerTexCoord);
#if !defined(SHADER_STAGE_RAY_TRACING)
float depthOffset = ApplyPerPixelDisplacement(input, V, layerTexCoord);
#ifdef _DEPTHOFFSET_ON
ApplyDepthOffsetPositionInput(V, depthOffset, GetViewForwardDir(), GetWorldToHClipMatrix(), posInput);
#endif
#else
float depthOffset = 0.0;
#endif
#if defined(_ALPHATEST_ON)
float alphaTex = SAMPLE_UVMAPPING_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, layerTexCoord.base).a;
alphaTex = lerp(_AlphaRemapMin, _AlphaRemapMax, alphaTex);
float alphaValue = alphaTex * _BaseColor.a;
// Perform alha test very early to save performance (a killed pixel will not sample textures)
#if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS
float alphaCutoff = _AlphaCutoffPrepass;
#elif SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_POSTPASS
float alphaCutoff = _AlphaCutoffPostpass;
#elif (SHADERPASS == SHADERPASS_SHADOWS) || (SHADERPASS == SHADERPASS_RAYTRACING_VISIBILITY)
float alphaCutoff = _UseShadowThreshold ? _AlphaCutoffShadow : _AlphaCutoff;
#else
float alphaCutoff = _AlphaCutoff;
#endif
// clip(-0.1);
GENERIC_ALPHA_TEST(alphaValue, alphaCutoff);
#endif
// We perform the conversion to world of the normalTS outside of the GetSurfaceData
// so it allow us to correctly deal with detail normal map and optimize the code for the layered shaders
float3 normalTS;
float3 bentNormalTS;
float3 bentNormalWS;
float alpha = UtsGetSurfaceData(input, layerTexCoord, surfaceData, normalTS, bentNormalTS);
// This need to be init here to quiet the compiler in case of decal, but can be override later.
surfaceData.geomNormalWS = input.tangentToWorld[2];
surfaceData.specularOcclusion = 1.0;
#ifdef DECAL_NORMAL_BLENDING
if (_EnableDecals)
{
#ifndef SURFACE_GRADIENT
normalTS = SurfaceGradientFromTangentSpaceNormalAndFromTBN(normalTS,
input.tangentToWorld[0], input.tangentToWorld[1]);
#endif
DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, input, alpha);
ApplyDecalToSurfaceData(decalSurfaceData, input.tangentToWorld[2], surfaceData, normalTS);
}
GetNormalWS_SG(input, normalTS, surfaceData.normalWS, doubleSidedConstants);
#else
GetNormalWS(input, normalTS, surfaceData.normalWS, doubleSidedConstants);
#if HAVE_DECALS
if (_EnableDecals)
{
// Both uses and modifies 'surfaceData.normalWS'.
DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, input, alpha);
ApplyDecalToSurfaceData(decalSurfaceData, input.tangentToWorld[2], surfaceData);
}
#endif
#endif
// Use bent normal to sample GI if available
#ifdef _BENTNORMALMAP
GetNormalWS(input, bentNormalTS, bentNormalWS, doubleSidedConstants);
#else
bentNormalWS = surfaceData.normalWS;
#endif
#if defined(DEBUG_DISPLAY)
#if !defined(SHADER_STAGE_RAY_TRACING)
// Mipmap mode debugging isn't supported with ray tracing as it relies on derivatives
if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)
{
surfaceData.baseColor = GET_TEXTURE_STREAMING_DEBUG(posInput.positionSS, input.texCoord0);
surfaceData.metallic = 0;
}
#endif
// We need to call ApplyDebugToSurfaceData after filling the surfaceData and before filling builtinData
// as it can modify attribute use for static lighting
ApplyDebugToSurfaceData(input.tangentToWorld, surfaceData);
#endif
// By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.
// If user provide bent normal then we process a better term
#if defined(_SPECULAR_OCCLUSION_FROM_BENT_NORMAL_MAP)
// If we have bent normal and ambient occlusion, process a specular occlusion
surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));
// Don't do spec occ from Ambient if there is no mask mask
#elif defined(_MASKMAP) && !defined(_SPECULAR_OCCLUSION_NONE)
surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));
#endif
// This is use with anisotropic material
surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);
#if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)
// Specular AA
#ifdef PROJECTED_SPACE_NDF_FILTERING
surfaceData.perceptualSmoothness = ProjectedSpaceGeometricNormalFiltering(surfaceData.perceptualSmoothness, input.tangentToWorld[2], _SpecularAAScreenSpaceVariance, _SpecularAAThreshold);
#else
surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, input.tangentToWorld[2], _SpecularAAScreenSpaceVariance, _SpecularAAThreshold);
#endif
#endif
// Caution: surfaceData must be fully initialize before calling GetBuiltinData
GetBuiltinData(input, V, posInput, surfaceData, alpha, bentNormalWS, depthOffset, layerTexCoord.base, builtinData);
#ifdef _ALPHATEST_ON
// Used for sharpening by alpha to mask
builtinData.alphaClipTreshold = alphaCutoff;
#endif
RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS
}
#endif

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: be7208b19c2b4f53b717af959f293024
timeCreated: 1738569488

View File

@@ -1,258 +0,0 @@
#ifndef UTS_MATERIAL_EVALUATION
#define UTS_MATERIAL_EVALUATION
#define ColorSpaceDielectricSpec half4(0.22, 0.22, 0.22, 0.779)
struct UtsShadeMask
{
float baseShadeMask;
float firstShadeMask;
};
float RoughnessToBlinnPhongSpecularExponent(float roughness)
{
return clamp(2 * rcp(roughness * roughness) - 2, FLT_EPS, rcp(FLT_EPS));
}
float StepFeatherToon(float value,float step,float feather)
{
return saturate((value - step + feather) / feather);
}
float3 ComputeSpecularTerm(UtsBSDFData bsdfData, PreLightData preLightData, float3 V, float3 L)
{
#ifdef _PBR_MODE_OFF
return 0;
#else
float3 specTerm;
float3 N = bsdfData.normalWS;
float3 H = normalize(L + V);
float NdotL = dot(N, L);
float NdotH = saturate(dot(N, H));
float clampedNdotV = ClampNdotV(preLightData.NdotV);
float clampedNdotL = saturate(NdotL);
float partLambdaV;
float3 DV = 0;
#ifdef _PBR_MODE_STANDARD
partLambdaV = GetSmithJointGGXPartLambdaV(clampedNdotV, bsdfData.roughnessT);
// We use abs(NdotL) to handle the none case of double sided
DV = DV_SmithJointGGX(NdotH, abs(NdotL), clampedNdotV, bsdfData.roughnessT, partLambdaV);
#elif _PBR_MODE_ANISOTROPY
float TdotV = dot(bsdfData.tangentWS, V);
float BdotV = dot(bsdfData.bitangentWS, V);
ConvertAnisotropyToRoughness(bsdfData.perceptualRoughness, bsdfData.anisotropy, bsdfData.roughnessT, bsdfData.roughnessB);
partLambdaV = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, clampedNdotV, bsdfData.roughnessT, bsdfData.roughnessB);
// For anisotropy we must not saturate these values
float TdotH = dot(bsdfData.tangentWS, H);
float TdotL = dot(bsdfData.tangentWS, L);
float BdotH = dot(bsdfData.bitangentWS, H);
float BdotL = dot(bsdfData.bitangentWS, L);
// We use abs(NdotL) to handle the none case of double sided
DV = DV_SmithJointGGXAniso(TdotH, BdotH, NdotH, clampedNdotV, TdotL, BdotL, abs(NdotL), bsdfData.roughnessT, bsdfData.roughnessB, partLambdaV);
#elif _PBR_MODE_HAIR
float3 t = ShiftTangent(bsdfData.bitangentWS, N, bsdfData.anisotropy);
float specularExponent = RoughnessToBlinnPhongSpecularExponent(PerceptualRoughnessToRoughness(bsdfData.coatRoughness));
DV = D_KajiyaKay(t, H, specularExponent);
float normalizeSpec = DV * rcp(specularExponent + 2) * 2 * PI;
//DV *= StepFeatherToon(normalizeSpec,specularStep,specularFeather);
DV = DV * normalizeSpec * _KKColor.rgb;
#elif _PBR_MODE_TOON
float specularExponent = RoughnessToBlinnPhongSpecularExponent(PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness));
DV = pow(NdotH, 5.0 * specularExponent);
DV = StepFeatherToon(DV, _ToonSpecularStep, _ToonSpecularFeather);
//specTerm = pow(NdotH, 5.0 * specularExponent);
//specTerm = StepFeatherToon(specTerm, _ToonSpecularStep, _ToonSpecularFeather);
//return specTerm * ColorSpaceDielectricSpec.rgb * clampedNdotL;
#endif
specTerm = DV * preLightData.specularFGD;
specTerm = specTerm * clampedNdotL;
return specTerm;
#endif
}
half3 FitWithCurveApprox(half NdotL, half Curvature)
{
half curva = (1.0 / mad(Curvature, 0.5 - 0.0625, 0.0625) - 2.0) / (16.0 - 2.0);
half oneMinusCurva = 1.0 - curva;
half3 curve0;
{
half3 rangeMin = half3(0.0, 0.3, 0.3);
half3 rangeMax = half3(1.0, 0.7, 0.7);
half3 offset = half3(0.0, 0.06, 0.06);
half3 t = saturate(mad(NdotL, 1.0 / (rangeMax - rangeMin), (offset + rangeMin) / (rangeMin - rangeMax)));
half3 lowerLine = (t * t) * half3(0.65, 0.5, 0.9);
lowerLine.r += 0.045;
lowerLine.b *= t.b;
half3 m = half3(1.75, 2.0, 1.97);
half3 upperLine = mad(NdotL, m, half3(0.99, 0.99, 0.99) - m);
upperLine = saturate(upperLine);
half3 lerpMin = half3(0.0, 0.35, 0.35);
half3 lerpMax = half3(1.0, 0.7, 0.6);
half3 lerpT = saturate(mad(NdotL, 1.0 / (lerpMax - lerpMin), lerpMin / (lerpMin - lerpMax)));
curve0 = lerp(lowerLine, upperLine, lerpT * lerpT);
}
half3 curve1;
{
half3 m = half3(1.95, 2.0, 2.0);
half3 upperLine = mad(NdotL, m, half3(0.99, 0.99, 1.0) - m);
curve1 = saturate(upperLine);
}
float oneMinusCurva2 = oneMinusCurva * oneMinusCurva;
return lerp(curve0, curve1, mad(oneMinusCurva2, -1.0 * oneMinusCurva2, 1.0));
}
float3 SampleSDFTexture(float3 L, float2 uv, out float angle)
{
float2 right_uv = float2(1 - uv.x, uv.y);
float3 left_SDFTex = SAMPLE_TEXTURE2D(_SDFShadowMap, sampler_SDFShadowMap, uv).rgb;
float3 right_SDFTex = SAMPLE_TEXTURE2D(_SDFShadowMap, sampler_SDFShadowMap, right_uv).rgb;
float2 leftVector = normalize(mul(UNITY_MATRIX_M, float4(1.0, 0.0, 0.0, 0.0)).xz);
float2 forwardVector = normalize(mul(UNITY_MATRIX_M, float4(0.0, 0.0, 1.0, 0.0)).xz);
float2 lightDirection = normalize(L.xz);
angle = saturate(dot(forwardVector, lightDirection) * -1.0 + _SDFShadowLevel);
bool isRightSide = dot(lightDirection, leftVector) > 0;
return isRightSide ? right_SDFTex : left_SDFTex;
}
float GetHairShadow(PositionInputs posInput, float3 L)
{
float shadow = 1.0;
// Push the face fragment view space position towards the light for a little bit
float hairShadowOpacity = saturate(Remap(length(posInput.positionWS), float2(_HairShadowFadeOutDistance, _HairShadowFadeInDistance), float2(0, 1)));
if (hairShadowOpacity > 0.0)
{
float3 viewLightDir = TransformWorldToViewDir(L); // / posInput.deviceDepth; when linearDepth grows large, the movement amount should be lower since we are getting further from the face.
float3 cameraDirOS = normalize(TransformWorldToObject(GetCameraPositionWS()));
float shadowLengthY = _HairShadowDistance * 5.0 * max(0.5, posInput.linearDepth * _HairShadowDistanceScaleFactor) / posInput.linearDepth;
float2 shadowLength = float2(shadowLengthY * 2.0f, shadowLengthY);
float3 camDirOS = normalize(TransformWorldToObject(GetCameraPositionWS()));
float camDirFactor = 1 - smoothstep(0.1, 0.9, camDirOS.y);
shadowLength.y *= camDirFactor;
float2 samplingPoint = (posInput.positionSS + shadowLength * viewLightDir.xy * (_ScreenSize.xy / float2(1920.0f, 1080.0f))) * _ScreenSize.zw; // Use 1080p as the reference resolution to achieve consistent shadow lengths across various screen resolutions.
// Then sample the hair buffer, to see if the fragment lands in shadow.
float2 scaledUVs = samplingPoint * _HairShadowRTHandleScale.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 hairDepth = SAMPLE_TEXTURE2D(_HairShadowTex, s_trilinear_clamp_sampler, scaledUVs).r;
float shadowMask = posInput.deviceDepth <= hairDepth + _HairShadowDepthBias ? 1 : 0; // Hair < Face means Hair are closer to camera
// Note that we have LinearEyeDepth in the buffer. A comparison of depth is needed so that we don't project the shadow of hair behind the face.
shadow = lerp(1, 1.0 - hairShadowOpacity, shadowMask);
}
return shadow;
}
DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, PreLightData preLightData, SHADOW_TYPE shadow,
float3 lightColor, float3 V, float3 L, float2 uv,
float diffuseDimmer, float specularDimmer)
{
DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
if (Max3(lightColor.r, lightColor.g, lightColor.b) > 0.0)
{
shadow = smoothstep(0.4, 0.6, shadow);
#if _RECEIVE_HAIR_SHADOW_ON && ENABLE_UTS_HAIR_SHAOW
shadow *= GetHairShadow(posInput, L);
#endif
shadow = saturate(lerp(1.0, shadow, _Set_SystemShadowsToBase));
#if _SHADING_MODE_SDF
float angle;
float3 sdfTexture = SampleSDFTexture(L, uv, angle); // r: sdf shadow, g: sdf highlight, b: fixed shadow
float sdfShadowMask = smoothstep(angle - _SDFSmoothLevel, angle + _SDFSmoothLevel, sdfTexture.r);
float sdfHighlight = sdfTexture.g * _SDFHighlightStrength;
#endif
float3 diffuseTerm = 0.0;
float3 specularTerm = ComputeSpecularTerm(bsdfData, preLightData, V, L);
#if _USE_RAMP_COLOR_MAP_ON
#if _SHADING_MODE_STANDARD
float NdotL = dot(bsdfData.normalWS, L);
float halfLambert = 0.5 * NdotL + 0.5;
float3 rampColor = SAMPLE_TEXTURE2D_ARRAY_LOD(_ShadingRampMap, s_linear_clamp_sampler, float2(halfLambert * shadow.x, 0.0), _ShadingIndex, 0.0).rgb;
diffuseTerm = bsdfData.diffuseColor * rampColor;
specularTerm *= saturate(NdotL) * shadow;
#elif _SHADING_MODE_SDF
float3 rampColor = SAMPLE_TEXTURE2D_ARRAY_LOD(_ShadingRampMap, s_linear_clamp_sampler, float2(sdfShadowMask * shadow.x, 0.0), _ShadingIndex, 0.0).rgb;
diffuseTerm = bsdfData.diffuseColor * rampColor;
specularTerm = (specularTerm + sdfHighlight) * sdfShadowMask * shadow;
#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));
float baseShadeMask = saturate((halfLambert - (_1stShadeColorStep - firstColorFeatherForMask)) / (_1stShadeColorStep - (_1stShadeColorStep - firstColorFeatherForMask)));
baseShadeMask *= shadow;
float secondColorFeatherForMask = lerp(_2ndShadeColorFeather, 0.0, max(_SecondShadeOverridden, _ComposerMaskMode));
float firstShadeMask = saturate((halfLambert - (_2ndShadeColorStep - secondColorFeatherForMask)) / (_2ndShadeColorStep - (_2ndShadeColorStep - secondColorFeatherForMask)));
diffuseTerm = lerp(lerp(bsdfData.secondShadingDiffuseColor, bsdfData.firstShadingDiffuseColor, firstShadeMask), bsdfData.diffuseColor, baseShadeMask);
specularTerm *= baseShadeMask;
#elif _SHADING_MODE_SDF
float shadeMask = sdfShadowMask * sdfTexture.b * shadow;
diffuseTerm = lerp(bsdfData.firstShadingDiffuseColor, bsdfData.diffuseColor, shadeMask);
specularTerm = (specularTerm + sdfHighlight) * shadeMask;
#endif
#endif
lighting.diffuse += diffuseTerm * lightColor * diffuseDimmer;
lighting.specular += specularTerm * lightColor * specularDimmer;
}
return lighting;
}
DirectLighting UtsEvaluateAngelRing(FragInputs input, float3 normalWS, float3 V)
{
DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
// Should we scroll the angel ring texture on x?
float3 cameraRight = UNITY_MATRIX_V[0].xyz;
float3 cameraFront = UNITY_MATRIX_V[2].xyz;
float3 upVector = float3(0, 1, 0);
float3 rightAxis = cross(cameraFront, upVector);
float cameraRightMagnitude = sqrt(cameraRight.x * cameraRight.x + cameraRight.y * cameraRight.y + cameraRight.z * cameraRight.z);
float rightAxisMagnitude = sqrt(rightAxis.x * rightAxis.x + rightAxis.y * rightAxis.y + rightAxis.z * rightAxis.z);
float cameraRollCos = dot(rightAxis, cameraRight) / (rightAxisMagnitude * cameraRightMagnitude);
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;
arOffsetU = arOffsetU * 0.5 + 0.5;
float2 arvnRotate = RotateUV(arOffsetU, -(cameraDir * cameraRoll), 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));
lighting.specular += angelRingColor.r * angelRingColor.a * weight;
return lighting;
}
#endif

View File

@@ -0,0 +1,91 @@
#ifndef UTS_SURFACE_FEATURE_EVALUATION
#define UTS_SURFACE_FEATURE_EVALUATION
void UtsEvaluateLighting_Stocking(FragInputs input, PositionInputs posInput, PreLightData preLightData, float3 N, float3 V, inout AggregateLighting aggregateLighting)
{
float fresnel = pow(preLightData.NdotV, _StockingFresnelWidth);
#if _STOCKING_SPARKING_MAP
float viewAngleFactor = saturate(1.0 - preLightData.NdotV);
float2 shiftedNDC = posInput.positionNDC.xy + viewAngleFactor * 0.05;
float spacing = (1.0 - posInput.linearDepth) * _StockingSparkleSpacing;
// NOTE: Should we use sparkle texture instead of Voronoi?
float screenSparkle = smoothstep(1.0 - (0.5 * _StockingSparkleAmount), 1, 1.0 - Voronoi(shiftedNDC * _ScreenParams.xy / spacing, 5, 5.0));
float objectSparkle = smoothstep(1.0 - (0.5 * _StockingSparkleSize), 1, 1.0 - Voronoi(input.texCoord0, 5, 100.0));
float sparkle = objectSparkle * screenSparkle * _StockingSparkleIntensity * 5;
aggregateLighting.direct.specular += sparkle * aggregateLighting.direct.specular;
#endif
aggregateLighting.direct.diffuse *= fresnel;
}
DirectLighting UtsEvaluateLighting_RimLight(PositionInputs posInput, UtsBSDFData bsdfData, PreLightData preLightData
#if _LIGHT_BASE_RIM_LIGHT_ON
, float3 L, float3 lightColor
#endif
)
{
DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
float3 rimLightColor = _RimLightColor.rgb * _RimLightIntensity;
rimLightColor = lerp(rimLightColor, rimLightColor * bsdfData.diffuseColor.rgb, _AlbedoAffectRimLight * _RimLightColor.a);
#if _SCREEN_SPACE_RIM_LIGHT_ON
float3 normalVS = normalize(mul((float3x3)UNITY_MATRIX_V, bsdfData.geomNormalWS));
float2 depthUV = posInput.positionNDC.xy + normalVS.xy * (_RimLightLevel * 0.05 / posInput.linearDepth);
float offsetedDepth = SampleCameraDepth(depthUV);
float depthDiff = saturate(posInput.deviceDepth - offsetedDepth);
float rimLightMask = step(0.0025 / posInput.linearDepth, depthDiff);
#else
float clampNdotV = ClampNdotV(preLightData.NdotV);
float rimLightMask = pow(1.0 - clampNdotV, exp2(lerp(3.0, 0.0, _RimLightLevel)));
rimLightMask = lerp(rimLightMask, step(_RimLightClippingLevel, rimLightMask), _RimLightClipping);
#endif
#if _LIGHT_BASE_RIM_LIGHT_ON
float halfLambert = 0.5 * dot(bsdfData.normalWS, L) + 0.5;
float lightBaseMask = saturate(smoothstep(_LightDirectionRimLightLevel, 1.0, halfLambert));
rimLightMask *= lightBaseMask;
rimLightColor *= lightColor;
#endif
lighting.diffuse = rimLightMask * rimLightColor;
return lighting;
}
DirectLighting UtsEvaluateLighting_AngelRing(FragInputs input, float3 N, float3 V)
{
DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
// Should we scroll the angel ring texture on x?
float3 cameraRight = UNITY_MATRIX_V[0].xyz;
float3 cameraFront = UNITY_MATRIX_V[2].xyz;
float3 upVector = float3(0, 1, 0);
float3 rightAxis = cross(cameraFront, upVector);
float cameraRightMagnitude = sqrt(cameraRight.x * cameraRight.x + cameraRight.y * cameraRight.y + cameraRight.z * cameraRight.z);
float rightAxisMagnitude = sqrt(rightAxis.x * rightAxis.x + rightAxis.y * rightAxis.y + rightAxis.z * rightAxis.z);
float cameraRollCos = dot(rightAxis, cameraRight) / (rightAxisMagnitude * cameraRightMagnitude);
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(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(V, N));
lighting.specular = angelRingColor * angelRingColor.a * weight;
return lighting;
}
#endif

View File

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

View File

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

View File

@@ -679,8 +679,8 @@ void Frag(PackedVaryingsToPS packedInput,
lightDirection = lerp(lightDirection, customLightDirection, _Is_BLD);
float3 originalLightColor = customMainLight.lightColor.rgb;
originalLightColor = lerp(originalLightColor, clamp(originalLightColor, ConvertFromEV100(_ToonEvAdjustmentValueMin ), ConvertFromEV100(_ToonEvAdjustmentValueMax)), _ToonEvAdjustmentCurve) * _Light_Intensity_Multiplier;
float3 lightColor = lerp(max(defaultLightColor, originalLightColor), max(defaultLightColor, saturate(originalLightColor)), max(_Is_Filter_LightColor, _ToonLightHiCutFilter));
originalLightColor = lerp(originalLightColor, clamp(originalLightColor, ConvertFromEV100(_ToonEvAdjustmentValueMin ), ConvertFromEV100(_ToonEvAdjustmentValueMax)), _ToonEvAdjustmentCurve) * _LightIntensityMultiplier;
float3 lightColor = lerp(max(defaultLightColor, originalLightColor), max(defaultLightColor, saturate(originalLightColor)), max(_ClampLightColor, _ToonLightHiCutFilter));
float4 _1st_ShadeMap_var = lerp(SAMPLE_TEXTURE2D(_1st_ShadeMap, sampler_BaseColorMap,TRANSFORM_TEX(Set_UV0, _1st_ShadeMap)), _MainTex_var, _Use_BaseAs1st);
float3 _1st_Shade_var = lerp((_1st_ShadeMap_var.rgb * _1st_ShadeColor.rgb), ((_1st_ShadeMap_var.rgb * _1st_ShadeColor.rgb) * lightColor), _Is_LightColor_1st_Shade);

View File

@@ -75,7 +75,7 @@ void UTS_MainLight(LightLoopContext lightLoopContext, FragInputs input, UTSLight
float3 originalLightColor = mainLightColor.rgb;
originalLightColor = lerp(originalLightColor, clamp(originalLightColor, ConvertFromEV100(_ToonEvAdjustmentValueMin), ConvertFromEV100(_ToonEvAdjustmentValueMax)), _ToonEvAdjustmentCurve);
float3 lightColor = lerp(max(defaultLightColor, originalLightColor), max(defaultLightColor, saturate(originalLightColor)), max(_Is_Filter_LightColor, _ToonLightHiCutFilter)) * _Light_Intensity_Multiplier;
float3 lightColor = lerp(max(defaultLightColor, originalLightColor), max(defaultLightColor, saturate(originalLightColor)), max(_ClampLightColor, _ToonLightHiCutFilter)) * _LightIntensityMultiplier;
////// Lighting:
float3 halfDirection = normalize(utsData.viewDirection + lightDirection);

View File

@@ -11,13 +11,6 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
// We dont have to calculate lighting here if we are using sdf shadow
#ifndef _SDFShadow
#ifdef _IS_CLIPPING_MATTE
if (_ClippingMatteMode != 0)
{
return float3(0.0f, 0.0f, 0.0f);
}
#endif // _IS_CLIPPING_MATTE
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
// input.positionSS is SV_Position
@@ -32,7 +25,7 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
#endif
float3 lightDirection = utsLightData.lightDirection;
float3 additionalLightColor = utsLightData.lightColor * _Light_Intensity_Multiplier;
float3 additionalLightColor = utsLightData.lightColor * _LightIntensityMultiplier;
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);
@@ -70,7 +63,7 @@ void UTS_OtherLights(LightLoopContext lightLoopContext, FragInputs input, UTSLig
}
float pureIntensity = max(0.001, (0.299 * additionalLightColor.r + 0.587 * additionalLightColor.g + 0.114 * additionalLightColor.b));
float3 lightColor = max(float3(0.0, 0.0, 0.0), lerp(addPassLightColor, lerp(float3(0.0, 0.0, 0.0), min(addPassLightColor, addPassLightColor / pureIntensity), notDirectional), _Is_Filter_LightColor));
float3 lightColor = max(float3(0.0, 0.0, 0.0), lerp(addPassLightColor, lerp(float3(0.0, 0.0, 0.0), min(addPassLightColor, addPassLightColor / pureIntensity), notDirectional), _ClampLightColor));
float3 halfDirection = normalize(viewDirection + lightDirection); // has to be recalced here.
//v.2.0.5:
_1st_ShadeColor_Step = saturate(_1st_ShadeColor_Step + _StepOffset);

View File

@@ -9,6 +9,8 @@
#define SATURATE_BASE_COLOR_IF_SDR(x) saturate(x)
#endif
#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Lighting/UtsMaterialEvaluation.hlsl"
const float rateR = 0.299;
const float rateG = 0.587;
const float rateB = 0.114;
@@ -32,8 +34,9 @@ float GetColorAttenuation(float3 lightColor)
float3 GetLimitedLightColor(float3 lightColor)
{
lightColor = ApplyCurrentExposureMultiplier(lightColor);
float3 result = lerp(lightColor, saturate(lightColor), _Is_Filter_LightColor);
// In a hemisphere, The engery of full radiance is L * 2pi, and the engery of lambert is L * pi. We multiply by 0.5 here to apply the energy conservation.
lightColor = ApplyCurrentExposureMultiplier(lightColor) * 0.5;
float3 result = lerp(lightColor, normalize(lightColor), _ClampLightColor);
return result;
}
@@ -44,14 +47,19 @@ DirectLighting UtsEvaluateBSDF_Directional(LightLoopContext lightLoopContext, Po
ZERO_INITIALIZE(DirectLighting, lighting);
float3 L = -lightData.forward;
SHADOW_TYPE shadow = EvaluateShadow_Directional(lightLoopContext, posInput, lightData, builtinData, bsdfData.geomNormalWS);
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 * _Light_Intensity_Multiplier);
lightColor.rgb = GetLimitedLightColor(lightColor.rgb * lightColor.a * _LightIntensityMultiplier) * shadowColor;
UtsClampRoughness(preLightData, bsdfData, lightData.minRoughness);
@@ -70,17 +78,17 @@ DirectLighting UtsEvaluateBSDF_Punctual(LightLoopContext lightLoopContext, Posit
float4 distances; // {d, d^2, 1/d, d_proj}
GetPunctualLightVectors(posInput.positionWS, lightData, L, distances);
PositionInputs shadowPositionInputs = posInput;
shadowPositionInputs.positionWS = posInput.positionWS + L * _ShadowBias;
SHADOW_TYPE shadow = EvaluateShadow_Punctual(lightLoopContext, shadowPositionInputs, lightData, builtinData, bsdfData.geomNormalWS, L, distances);
SHADOW_TYPE shadow = 1.0;
#if _RECEIVE_LIGHT_SHADOW_ON
shadow = UtsEvaluateShadow_Punctual(lightLoopContext, posInput, lightData, builtinData, UtsGetShadowNormal(bsdfData), L, distances);
#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_Punctual(lightLoopContext, posInput, lightData, L, distances);
lightColor.rgb = GetLimitedLightColor(lightColor.rgb * lightColor.a * _Light_Intensity_Multiplier);
lightColor.rgb = GetLimitedLightColor(lightColor.rgb * lightColor.a * _LightIntensityMultiplier);
UtsClampRoughness(preLightData, bsdfData, lightData.minRoughness);
@@ -95,6 +103,8 @@ IndirectLighting UtsEvaluateBSDF_ScreenSpaceReflection(PositionInputs posInput,
IndirectLighting lighting;
ZERO_INITIALIZE(IndirectLighting, lighting);
if (_SSRWeight > 0.0)
{
// TODO: this texture is sparse (mostly black). Can we avoid reading every texel? How about using Hi-S?
float4 ssrLighting = LOAD_TEXTURE2D_X(_SsrLightingTexture, posInput.positionSS);
InversePreExposeSsrLighting(ssrLighting);
@@ -102,8 +112,9 @@ IndirectLighting UtsEvaluateBSDF_ScreenSpaceReflection(PositionInputs posInput,
// Apply the weight on the ssr contribution (if required)
ApplyScreenSpaceReflectionWeight(ssrLighting);
reflectionHierarchyWeight = ssrLighting.a;
lighting.specularReflected = ssrLighting.rgb * preLightData.specularFGD;
reflectionHierarchyWeight = ssrLighting.a * _SSRWeight;
lighting.specularReflected = lerp(lighting.specularReflected, ssrLighting.rgb * preLightData.specularFGD, _SSRWeight);
}
return lighting;
}
@@ -115,40 +126,39 @@ void UtsEvaluateBSDF_BakeDiffuse(PositionInputs posInput, PreLightData preLightD
lightInReflDir = float3(-1, -1, -1); // This variable is used with APV for reflection probe normalization - see code for LIGHTFEATUREFLAGS_ENV
#endif
#if !defined(_SURFACE_TYPE_TRANSPARENT) && !defined(SCREEN_SPACE_INDIRECT_DIFFUSE_DISABLED)
if (_IndirectDiffuseMode != INDIRECTDIFFUSEMODE_OFF)
{
builtinData.bakeDiffuseLighting = LOAD_TEXTURE2D_X(_IndirectDiffuseTexture, posInput.positionSS).xyz * GetInverseCurrentExposureMultiplier();
}
else
#if defined(_PBR_MODE_OFF) || defined(_PBR_MODE_TOON)
float3 normalWS = float3(0.0, 0.0, 1.0);
#else
float3 normalWS = bsdfData.normalWS;
#endif
{
float3 backNormalWS = -normalWS;
// Reflect normal to get lighting for reflection probe tinting
float3 R = reflect(-V, normalWS);
#if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)
if (_EnableProbeVolumes)
{
// Reflect normal to get lighting for reflection probe tinting
float3 R = reflect(-V, bsdfData.normalWS);
#if defined(_PBR_Mode_OFF) || defined(_PBR_Mode_TOON)
float3 normalWS = 0.0;
float3 backNormalWS = 0.0;
#else
float3 normalWS = bsdfData.normalWS;
float3 backNormalWS = -bsdfData.normalWS;
#endif
EvaluateAdaptiveProbeVolume(GetAbsolutePositionWS(posInput.positionWS),
bsdfData.normalWS, -bsdfData.normalWS,
normalWS, -backNormalWS,
R, V,
posInput.positionSS, builtinData.renderingLayers,
builtinData.bakeDiffuseLighting, builtinData.backBakeDiffuseLighting, lightInReflDir);
}
else // If probe volume is disabled we fallback on the ambient probes
{
builtinData.bakeDiffuseLighting = EvaluateAmbientProbe(bsdfData.normalWS);
builtinData.backBakeDiffuseLighting = EvaluateAmbientProbe(-bsdfData.normalWS);
builtinData.bakeDiffuseLighting = EvaluateAmbientProbe(normalWS);
builtinData.backBakeDiffuseLighting = EvaluateAmbientProbe(backNormalWS);
}
#endif
#if !defined(_SURFACE_TYPE_TRANSPARENT) && !defined(SCREEN_SPACE_INDIRECT_DIFFUSE_DISABLED)
if (_IndirectDiffuseMode != INDIRECTDIFFUSEMODE_OFF)
{
float3 ssgiLighting = LOAD_TEXTURE2D_X(_IndirectDiffuseTexture, posInput.positionSS).xyz * GetInverseCurrentExposureMultiplier();
builtinData.bakeDiffuseLighting = lerp(builtinData.bakeDiffuseLighting, ssgiLighting.rgb, _SSGIWeight);
}
#endif
}
void UtsEvaluateBSDF_MatCapDiffuse(float3 positionWS, float3 normalWS, inout BuiltinData builtinData)
@@ -161,7 +171,8 @@ void UtsEvaluateBSDF_MatCapDiffuse(float3 positionWS, float3 normalWS, inout Bui
uv.x *= -1;
uv = uv * 0.5 + 0.5;
builtinData.bakeDiffuseLighting = SAMPLE_TEXTURE2D_LOD(_MatCapMap, s_linear_clamp_sampler, uv, UNITY_SPECCUBE_LOD_STEPS).rgb * GetInverseCurrentExposureMultiplier();
float lod = clamp(UNITY_SPECCUBE_LOD_STEPS + _IndirectDiffuseMatCapLod, 0.0, 10.0);
builtinData.bakeDiffuseLighting = SAMPLE_TEXTURE2D_LOD(_IndirectDiffuseMatCapMap, s_trilinear_clamp_sampler, uv, lod).rgb * GetInverseCurrentExposureMultiplier();
}
IndirectLighting UtsEvaluateBSDF_MatCapSpecular(float3 positionWS, UtsBSDFData bsdfData, PreLightData preLightData)
@@ -177,15 +188,17 @@ IndirectLighting UtsEvaluateBSDF_MatCapSpecular(float3 positionWS, UtsBSDFData b
uv.x *= -1;
uv = uv * 0.5 + 0.5;
lighting.specularReflected = SAMPLE_TEXTURE2D_LOD(_MatCapMap, s_linear_clamp_sampler, uv, PerceptualRoughnessToMipmapLevel(bsdfData.perceptualRoughness)).rgb;
float lod = clamp(PerceptualRoughnessToMipmapLevel(bsdfData.perceptualRoughness) + _IndirectSpecularMatCapLod, 0.0, 10.0);
lighting.specularReflected = SAMPLE_TEXTURE2D_LOD(_IndirectSpecularMatCapMap, s_trilinear_clamp_sampler, uv, lod).rgb;
lighting.specularReflected *= preLightData.specularFGD * GetInverseCurrentExposureMultiplier();
return lighting;
}
void UtsEvaluateBSDF_Ramp(PositionInputs posInput, UtsBSDFData bsdfData, float3 L, inout BuiltinData builtinData)
void UtsEvaluateBSDF_Ramp(PositionInputs posInput, UtsBSDFData bsdfData, inout BuiltinData builtinData)
{
// TODO
float3 lighting = SAMPLE_TEXTURE2D_ARRAY(_IndirectDiffuseRampMap, s_trilinear_clamp_sampler, float2(_IndirectDiffuseRampPosition, 0.0), _IndirectDiffuseRampIndex).rgb;
builtinData.bakeDiffuseLighting = lighting * GetInverseCurrentExposureMultiplier();
}
IndirectLighting UtsEvaluateBSDF_Env(LightLoopContext lightLoopContext, PositionInputs posInput, PreLightData preLightData, EnvLightData lightData, UtsBSDFData bsdfData, int influenceShapeType, int GPUImageBasedLightingType, inout float hierarchyWeight)
@@ -193,11 +206,6 @@ IndirectLighting UtsEvaluateBSDF_Env(LightLoopContext lightLoopContext, Position
IndirectLighting lighting;
ZERO_INITIALIZE(IndirectLighting, lighting);
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
{
return lighting;
}
float3 envLighting;
float3 positionWS = posInput.positionWS;
float weight = 1.0;
@@ -238,27 +246,37 @@ IndirectLighting UtsEvaluateBSDF_Env(LightLoopContext lightLoopContext, Position
return lighting;
}
void ApplyAmbientOcclusion(AmbientOcclusionFactor aoFactor, UtsBSDFData bsdfData, inout BuiltinData builtinData, inout AggregateLighting lighting)
{
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);
}
void AdjustIndirectLighting(PreLightData preLightData, UtsBSDFData bsdfData, inout BuiltinData builtinData, inout AggregateLighting lighting)
{
builtinData.emissiveColor *= GetCurrentExposureMultiplier();
builtinData.bakeDiffuseLighting = ApplyCurrentExposureMultiplier(builtinData.bakeDiffuseLighting * bsdfData.diffuseColor * preLightData.diffuseFGD * _IndirectDiffuseIntensity);
lighting.indirect.specularReflected = ApplyCurrentExposureMultiplier(lighting.indirect.specularReflected * bsdfData.fresnel0 * _IndirectSpecularIntensity);
}
void UtsPostEvaluateBSDF(PositionInputs posInput, PreLightData preLightData, UtsBSDFData bsdfData, BuiltinData builtinData, AggregateLighting lighting, out LightLoopOutput lightLoopOutput)
{
#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);
builtinData.bakeDiffuseLighting = APPLY_WEIGHT(builtinData.bakeDiffuseLighting, aoFactor.indirectAmbientOcclusion, _AO_Factor);
lighting.indirect.specularReflected = APPLY_WEIGHT(lighting.indirect.specularReflected, aoFactor.indirectSpecularOcclusion, _AO_Factor);
lighting.direct.diffuse = APPLY_WEIGHT(lighting.direct.diffuse, aoFactor.directAmbientOcclusion, _AO_Factor);
lighting.direct.specular = APPLY_WEIGHT(lighting.direct.specular, aoFactor.directSpecularOcclusion, _AO_Factor);
ApplyAmbientOcclusion(aoFactor, bsdfData, builtinData, lighting);
#endif
AdjustIndirectLighting(preLightData, bsdfData, builtinData, lighting);
builtinData.bakeDiffuseLighting = ApplyCurrentExposureMultiplier(builtinData.bakeDiffuseLighting * bsdfData.diffuseColor * preLightData.diffuseFGD * _ID_Intensity);
lighting.indirect.specularReflected = ApplyCurrentExposureMultiplier(lighting.indirect.specularReflected * bsdfData.fresnel0 * _IR_Intensity);
lightLoopOutput.diffuseLighting = lighting.direct.diffuse + builtinData.bakeDiffuseLighting;
// In regular pbr, we need to multiple diffuse color here with direct diffuse lighting. However, in UTS, we have already multiplied it when evaluating the direct diffuse since we need to apply the shading color.
lightLoopOutput.diffuseLighting = lighting.direct.diffuse + builtinData.bakeDiffuseLighting + builtinData.emissiveColor;
lightLoopOutput.specularLighting = lighting.direct.specular + lighting.indirect.specularReflected;
// Rescale the GGX to account for the multiple scattering.
lightLoopOutput.specularLighting *= 1.0 + bsdfData.fresnel0 * preLightData.energyCompensation;
ApplyExposureAdjustment(lightLoopOutput.diffuseLighting);
ApplyExposureAdjustment(lightLoopOutput.specularLighting);
lightLoopOutput.diffuseLighting += builtinData.emissiveColor;
}
#endif

View File

@@ -3,9 +3,10 @@
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/PhysicalCamera.hlsl"
#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Common/UtsMaterialEvaluation.hlsl"
#include "Packages/com.misaki.hdrp-toon/Runtime/Models/SurfaceFeature.cs.hlsl"
#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Common/UtsSurfaceFeatureEvaluation.hlsl"
#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Lighting/UtsLightEvaluation.hlsl"
#include "Packages/com.misaki.hdrp-toon/Runtime/Models/SurfaceFeatureFlags.cs.hlsl"
// Channel mask enum.
// this must be same to UI cs code
@@ -18,51 +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
}
int GetUtsMainLightIndex(BuiltinData builtinData)
{
int mainLightIndex = -1;
float3 lightColor = float3(0.0f, 0.0f, 0.0f);
float lightAttenuation = 0.0f;
uint i = 0; // Declare once to avoid the D3D11 compiler warning.
for (i = 0; i < _DirectionalLightCount; ++i)
{
if (IsMatchingLightLayer(_DirectionalLightDatas[i].lightLayers, builtinData.renderingLayers))
{
float3 currentLightColor = _DirectionalLightDatas[i].color;
float currentLightAttenuation = GetColorAttenuation(currentLightColor);
if (mainLightIndex == -1 || (currentLightAttenuation > lightAttenuation))
{
mainLightIndex = i;
lightAttenuation = currentLightAttenuation;
lightColor = currentLightColor;
}
}
}
return mainLightIndex;
}
bool UtsUseScreenSpaceShadow(DirectionalLightData light, float3 normalWS)
{
#if defined(RAY_TRACED_SCREEN_SPACE_SHADOW_FLAG)
@@ -92,6 +48,7 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
// Initialize the contactShadow and contactShadowFade fields
InitContactShadow(posInput, context);
#if _RECEIVE_LIGHT_SHADOW_ON
// First of all we compute the shadow value of the directional light to reduce the VGPR pressure
if (featureFlags & LIGHTFEATUREFLAGS_DIRECTIONAL)
{
@@ -100,8 +57,8 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
{
DirectionalLightData light = _DirectionalLightDatas[_DirectionalShadowIndex];
#if defined(SCREEN_SPACE_SHADOWS_ON) && !defined(_SURFACE_TYPE_TRANSPARENT)
if (UseScreenSpaceShadow(light, bsdfData.normalWS))
#if defined(SCREEN_SPACE_SHADOWS_ON) && !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_RECEIVE_SCREEN_SPACE_SHADOW_ON)
if (UtsUseScreenSpaceShadow(light, bsdfData.normalWS))
{
context.shadowValue = GetScreenSpaceColorShadow(posInput, light.screenSpaceShadowIndex).SHADOW_TYPE_SWIZZLE;
}
@@ -111,16 +68,17 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
float3 L = -light.forward;
// Is it worth sampling the shadow map?
if ((light.lightDimmer > 0) && (light.shadowDimmer > 0) && // Note: Volumetric can have different dimmer, thus why we test it here
dot(bsdfData.normalWS, L) > 0.0)
// Should we skip it if NdotL is negative? (i.e. transmission)
if ((light.lightDimmer > 0) && (light.shadowDimmer > 0) && IsNonZeroBSDF(L, bsdfData))
{
context.shadowValue = GetDirectionalShadowAttenuation(context.shadowContext,
posInput.positionSS, posInput.positionWS + L * _ShadowBias, bsdfData.normalWS,
posInput.positionSS, posInput.positionWS + L * UtsGetShadowSlopeBias(bsdfData.normalWS, L), UtsGetShadowNormal(bsdfData),
light.shadowIndex, L);
}
}
}
}
#endif
PreLightData preLightData = GetPreLightData_UTS(V, posInput, bsdfData);
@@ -134,7 +92,7 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
#ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
GetCountAndStart(posInput, LIGHTCATEGORY_PUNCTUAL, lightStart, lightCount);
#else // LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
#else
lightCount = _PunctualLightCount;
lightStart = 0;
#endif
@@ -238,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);
@@ -246,9 +204,9 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
#endif
float3 lightInReflDir = 0.0;
#ifdef _INDIRECT_DIFFUSE_OFF
#ifdef _INDIRECT_DIFFUSE_MODE_OFF
#elif _INDIRECT_DIFFUSE_IBL
#elif _INDIRECT_DIFFUSE_MODE_IBL
bool replaceBakeDiffuseLighting = false;
#if !defined(_SURFACE_TYPE_TRANSPARENT) // No SSGI/RTGI/Mixed effect on transparent
if (_IndirectDiffuseMode != INDIRECTDIFFUSEMODE_OFF)
@@ -272,18 +230,17 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
{
UtsEvaluateBSDF_BakeDiffuse(posInput, preLightData, bsdfData, V, builtinData, lightInReflDir);
}
#elif _INDIRECT_DIFFUSE_MATCAP
//builtinData.bakeDiffuseLighting = UtsEvaluateColor_MatCap(posInput.positionWS, bsdfData.normalWS, 0.0);
#elif _INDIRECT_DIFFUSE_MODE_MATCAP
UtsEvaluateBSDF_MatCapDiffuse(posInput.positionWS, bsdfData.normalWS, builtinData);
#elif _INDIRECT_DIFFUSE_RAMP
#elif _INDIRECT_DIFFUSE_MODE_RAMP
UtsEvaluateBSDF_Ramp(posInput, bsdfData, builtinData);
#endif
if (featureFlags & LIGHTFEATUREFLAGS_ENV)
{
#if _INDIRECT_SPECULAR_OFF
#if _INDIRECT_SPECULAR_MODE_OFF
#elif _INDIRECT_SPECULAR_IBL
#elif _INDIRECT_SPECULAR_MODE_IBL
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
#if SCALARIZE_LIGHT_LOOP
@@ -342,16 +299,15 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
AccumulateIndirectLighting(lighting, aggregateLighting);
}
}
}
}
#elif _INDIRECT_SPECULAR_MATCAP
#elif _INDIRECT_SPECULAR_MODE_MATCAP
IndirectLighting lighting = UtsEvaluateBSDF_MatCapSpecular(posInput.positionWS, bsdfData, preLightData);
AccumulateIndirectLighting(lighting, aggregateLighting);
#endif
}
#if _INDIRECT_SPECULAR_IBL
#if _INDIRECT_SPECULAR_MODE_IBL
// Only apply the sky IBL if the sky texture is available
if ((featureFlags & LIGHTFEATUREFLAGS_SKY) && _EnvLightSkyEnabled)
{
@@ -371,12 +327,25 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
#endif
}
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATUREFLAGS_ANGEL_RING))
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_ANGEL_RING))
{
DirectLighting lighting = UtsEvaluateAngelRing(fragInputs, bsdfData.normalWS, V);
DirectLighting lighting = UtsEvaluateLighting_AngelRing(fragInputs, bsdfData.normalWS, V);
AccumulateDirectLighting(lighting, aggregateLighting);
}
#ifndef _LIGHT_BASE_RIM_LIGHT_ON
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_RIM_LIGHT))
{
DirectLighting lighting = UtsEvaluateLighting_RimLight(posInput, bsdfData, preLightData);
AccumulateDirectLighting(lighting, aggregateLighting);
}
#endif
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_STOCKING))
{
UtsEvaluateLighting_Stocking(fragInputs, posInput, preLightData, bsdfData.normalWS, V, aggregateLighting);
}
UtsPostEvaluateBSDF(posInput, preLightData, bsdfData, builtinData, aggregateLighting, lightLoopOutput);
}
@@ -454,29 +423,4 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
// return mainPunctualLight;
// }
// Todo: calculate the acutal main lighboth dorectional and punctual)t based on the light attenuation, rather than using the main directional light
UTSLightData GetCustomMainLightData(BuiltinData builtinData, UTSLightData mainPunctualLight)
{
UTSLightData utsLightData;
int mainLightIndex;
mainLightIndex = GetUtsMainLightIndex(builtinData);
if (mainLightIndex == -1 || length(_DirectionalLightDatas[mainLightIndex].color) < length(mainPunctualLight.lightColor))
{
utsLightData = mainPunctualLight;
}
else
{
utsLightData.lightColor = ApplyCurrentExposureMultiplier(_DirectionalLightDatas[mainLightIndex].color);
utsLightData.lightDirection = -_DirectionalLightDatas[mainLightIndex].forward;
utsLightData.diffuseDimmer = _DirectionalLightDatas[mainLightIndex].diffuseDimmer;
utsLightData.specularDimmer = _DirectionalLightDatas[mainLightIndex].specularDimmer;
utsLightData.shadowTint = _DirectionalLightDatas[mainLightIndex].shadowTint;
utsLightData.penumbraTint = _DirectionalLightDatas[mainLightIndex].penumbraTint;
}
return utsLightData;
}
#endif

View File

@@ -0,0 +1,196 @@
#ifndef UTS_MATERIAL_EVALUATION
#define UTS_MATERIAL_EVALUATION
#define ColorSpaceDielectricSpec half4(0.22, 0.22, 0.22, 0.779)
#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Lighting/UtsShadowEvaluation.hlsl"
float RoughnessToBlinnPhongSpecularExponent(float roughness)
{
return clamp(2 * rcp(roughness * roughness) - 2, FLT_EPS, rcp(FLT_EPS));
}
float StepFeatherToon(float value,float step,float feather)
{
return saturate((value - step + feather) / feather);
}
float3 ComputeSpecularTerm(UtsBSDFData bsdfData, PreLightData preLightData, float3 V, float3 L)
{
#ifdef _PBR_MODE_OFF
return 0;
#else
float3 specTerm;
float3 N = bsdfData.normalWS;
float3 H = normalize(L + V);
float NdotL = dot(N, L);
float NdotH = saturate(dot(N, H));
float clampedNdotV = ClampNdotV(preLightData.NdotV);
float clampedNdotL = saturate(NdotL);
float partLambdaV;
float3 DV = 0;
#ifdef _PBR_MODE_STANDARD
partLambdaV = GetSmithJointGGXPartLambdaV(clampedNdotV, bsdfData.roughnessT);
// We use abs(NdotL) to handle the none case of double sided
DV = DV_SmithJointGGX(NdotH, abs(NdotL), clampedNdotV, bsdfData.roughnessT, partLambdaV);
#elif _PBR_MODE_ANISOTROPY
float TdotV = dot(bsdfData.tangentWS, V);
float BdotV = dot(bsdfData.bitangentWS, V);
ConvertAnisotropyToRoughness(bsdfData.perceptualRoughness, bsdfData.anisotropy, bsdfData.roughnessT, bsdfData.roughnessB);
partLambdaV = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, clampedNdotV, bsdfData.roughnessT, bsdfData.roughnessB);
// For anisotropy we must not saturate these values
float TdotH = dot(bsdfData.tangentWS, H);
float TdotL = dot(bsdfData.tangentWS, L);
float BdotH = dot(bsdfData.bitangentWS, H);
float BdotL = dot(bsdfData.bitangentWS, L);
// We use abs(NdotL) to handle the none case of double sided
DV = DV_SmithJointGGXAniso(TdotH, BdotH, NdotH, clampedNdotV, TdotL, BdotL, abs(NdotL), bsdfData.roughnessT, bsdfData.roughnessB, partLambdaV);
#elif _PBR_MODE_HAIR
// TODO: Double layer anisotropic specular.
float3 t = ShiftTangent(bsdfData.bitangentWS, N, bsdfData.anisotropy);
float specularExponent = RoughnessToBlinnPhongSpecularExponent(PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness));
DV = D_KajiyaKay(t, H, specularExponent);
float normalizeSpec = DV * rcp(specularExponent + 2.0) * TWO_PI;
DV = DV * normalizeSpec * _KKColor.rgb;
#elif _PBR_MODE_FABRIC
float D = D_Charlie(NdotH, bsdfData.roughnessT);
// V_Charlie is expensive, use approx with V_Ashikhmin instead
// float V = V_Charlie(NdotL, clampedNdotV, bsdfData.roughness);
float Vis = V_Ashikhmin(NdotL, clampedNdotV);
DV = D * Vis;
#elif _PBR_MODE_TOON
float specularExponent = RoughnessToBlinnPhongSpecularExponent(PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness));
DV = pow(NdotH, 5.0 * specularExponent);
DV = StepFeatherToon(DV, _ToonSpecularStep, _ToonSpecularFeather);
#endif
// We use specularFGD here to approximate F.
specTerm = DV * preLightData.specularFGD * clampedNdotL;
return specTerm;
#endif
}
half3 FitWithCurveApprox(half NdotL, half Curvature)
{
half curva = (1.0 / mad(Curvature, 0.5 - 0.0625, 0.0625) - 2.0) / (16.0 - 2.0);
half oneMinusCurva = 1.0 - curva;
half3 curve0;
{
half3 rangeMin = half3(0.0, 0.3, 0.3);
half3 rangeMax = half3(1.0, 0.7, 0.7);
half3 offset = half3(0.0, 0.06, 0.06);
half3 t = saturate(mad(NdotL, 1.0 / (rangeMax - rangeMin), (offset + rangeMin) / (rangeMin - rangeMax)));
half3 lowerLine = (t * t) * half3(0.65, 0.5, 0.9);
lowerLine.r += 0.045;
lowerLine.b *= t.b;
half3 m = half3(1.75, 2.0, 1.97);
half3 upperLine = mad(NdotL, m, half3(0.99, 0.99, 0.99) - m);
upperLine = saturate(upperLine);
half3 lerpMin = half3(0.0, 0.35, 0.35);
half3 lerpMax = half3(1.0, 0.7, 0.6);
half3 lerpT = saturate(mad(NdotL, 1.0 / (lerpMax - lerpMin), lerpMin / (lerpMin - lerpMax)));
curve0 = lerp(lowerLine, upperLine, lerpT * lerpT);
}
half3 curve1;
{
half3 m = half3(1.95, 2.0, 2.0);
half3 upperLine = mad(NdotL, m, half3(0.99, 0.99, 1.0) - m);
curve1 = saturate(upperLine);
}
float oneMinusCurva2 = oneMinusCurva * oneMinusCurva;
return lerp(curve0, curve1, mad(oneMinusCurva2, -1.0 * oneMinusCurva2, 1.0));
}
DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, PreLightData preLightData, SHADOW_TYPE shadow,
float3 lightColor, float3 V, float3 L, float2 uv,
float diffuseDimmer, float specularDimmer)
{
DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
if (Max3(lightColor.r, lightColor.g, lightColor.b) > 0.0)
{
SHADOW_TYPE sharpShadow = smoothstep(0.4, 0.6, shadow);
#if _RECEIVE_HAIR_SHADOW_ON && ENABLE_UTS_HAIR_SHAOW
sharpShadow *= GetHairShadow(posInput, L, bsdfData.normalWS);
#endif
#if _SHADING_MODE_SDF
float angle;
float3 sdfTexture = SampleSDFTexture(L, uv, angle); // r: sdf shadow, g: sdf highlight, b: halfshadow
float shadowSmoothLevel = _SDFShadowSmoothLevel / 10.0;
float sdfShadowMask = smoothstep(angle - shadowSmoothLevel, angle + shadowSmoothLevel, sdfTexture.r);
float sdfHighlight = sdfTexture.g * _SDFHighlightStrength;
#endif
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
rampMask *= SAMPLE_TEXTURE2D(_ShadingRampMaskMap, s_linear_clamp_sampler, uv).r;
#endif
#if _SHADING_MODE_STANDARD
float halfLambert = 0.5 * NdotL + 0.5;
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_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 halfLambert = 0.5 * NdotL + 0.5;
// float firstColorFeatherForMask = lerp(_1stShadeColorFeather, 0.0, max(_ComposerMaskMode, _FirstShadeOverridden));
float baseShadeMask = saturate((halfLambert - (_1stShadeColorStep - _1stShadeColorFeather)) / (_1stShadeColorStep - (_1stShadeColorStep - _1stShadeColorFeather)));
baseShadeMask *= sharpShadow.x;
// float secondColorFeatherForMask = lerp(_2ndShadeColorFeather, 0.0, max(_SecondShadeOverridden, _ComposerMaskMode));
float firstShadeMask = saturate((halfLambert - (_2ndShadeColorStep - _2ndShadeColorFeather)) / (_2ndShadeColorStep - (_2ndShadeColorStep - _2ndShadeColorFeather)));
diffuseTerm = lerp(lerp(bsdfData.secondShadingDiffuseColor, bsdfData.firstShadingDiffuseColor, firstShadeMask), bsdfData.diffuseColor, baseShadeMask) * INV_PI;
specularTerm *= baseShadeMask;
#elif _SHADING_MODE_SDF
float shadeMask = sdfShadowMask * sdfTexture.b * sharpShadow.x;
diffuseTerm = lerp(bsdfData.firstShadingDiffuseColor, bsdfData.diffuseColor, shadeMask) * INV_PI;
specularTerm = (specularTerm + sdfHighlight) * shadeMask;
#endif
#endif
lighting.diffuse += diffuseTerm * lightColor * diffuseDimmer;
lighting.specular += specularTerm * lightColor * specularDimmer;
#if _LIGHT_BASE_RIM_LIGHT_ON
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_RIM_LIGHT))
{
DirectLighting rimLightLighting = UtsEvaluateLighting_RimLight(posInput, bsdfData, preLightData, L, lightColor);
lighting.diffuse += rimLightLighting.diffuse;
lighting.specular += rimLightLighting.specular;
}
#endif
}
return lighting;
}
#endif

View File

@@ -0,0 +1,133 @@
#ifndef UTS_SHADOW_EVALUATION
#define UTS_SHADOW_EVALUATION
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.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)
{
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;
float2 leftVector = normalize(mul(UNITY_MATRIX_M, float4(1.0, 0.0, 0.0, 0.0)).xz);
float2 forwardVector = normalize(mul(UNITY_MATRIX_M, float4(0.0, 0.0, 1.0, 0.0)).xz);
float2 lightDirection = normalize(L.xz);
angle = saturate(dot(forwardVector, lightDirection) * -1.0 + _SDFShadowLevel);
bool isRightSide = dot(lightDirection, leftVector) > 0;
return isRightSide ? right_SDFTex : left_SDFTex;
}
float GetHairShadow(PositionInputs posInput, float3 L, float N)
{
float shadow = 1.0;
// Push the face fragment view space position towards the light for a little bit
float hairShadowOpacity = saturate(Remap(length(posInput.positionWS), float2(_HairShadowFadeOutDistance, _HairShadowFadeInDistance), float2(0, 1)));
if (hairShadowOpacity > 0.0)
{
float3 viewLightDir = TransformWorldToViewDir(L);
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;
#if UNITY_UV_STARTS_AT_TOP
samplingPointSS.y = 1.0 - samplingPointSS.y;
#endif
float NdotL = saturate(dot(N, L));
float slopeBias = (1.0 - NdotL) * _HairShadowDepthBias;
float2 scaledUVs = samplingPointSS * _RTHandleScale.xy; // We have to including the scaling factor for our shadow map since we are not going to allocate new texture if the rendering resolution changed.
float hairShadow = SAMPLE_TEXTURE2D_SHADOW(_HairShadowTex, s_linear_clamp_compare_sampler, float3(scaledUVs, posInput.deviceDepth + slopeBias)).r;
shadow = lerp(1.0 - hairShadowOpacity, 1.0, hairShadow);
}
return shadow;
}
// distances = {d, d^2, 1/d, d_proj}, where d_proj = dot(lightToSample, light.forward).
SHADOW_TYPE UtsEvaluateShadow_Punctual(LightLoopContext lightLoopContext, PositionInputs posInput, LightData light, BuiltinData builtinData, float3 N, float3 L, float4 distances)
{
#ifndef LIGHT_EVALUATION_NO_SHADOWS
float shadow = 1.0;
float shadowMask = 1.0;
float NdotL = dot(N, L); // Disable contact shadow and shadow mask when facing away from light (i.e transmission)
#ifdef SHADOWS_SHADOWMASK
// shadowMaskSelector.x is -1 if there is no shadow mask
// Note that we override shadow value (in case we don't have any dynamic shadow)
shadow = shadowMask = (light.shadowMaskSelector.x >= 0.0 && NdotL > 0.0) ? dot(BUILTIN_DATA_SHADOW_MASK, light.shadowMaskSelector) : 1.0;
#endif
#if defined(SCREEN_SPACE_SHADOWS_ON) && !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_RECEIVE_SCREEN_SPACE_SHADOW_ON)
if ((light.screenSpaceShadowIndex & SCREEN_SPACE_SHADOW_INDEX_MASK) != INVALID_SCREEN_SPACE_SHADOW)
{
shadow = GetScreenSpaceShadow(posInput, light.screenSpaceShadowIndex);
shadow = lerp(shadowMask, shadow, light.shadowDimmer);
}
else
#endif
if ((light.shadowIndex >= 0) && (light.shadowDimmer > 0) && IsNonZeroBSDF(L, N))
{
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)
// and ShadowMask_Distance (ShadowMask contain static objects shadow and ShadowMap contain everything and is blend with ShadowMask based on distance (Global distance setup in QualitySettigns)).
// HDRenderPipeline change this behavior. Only ShadowMask mode is supported but we support both blend with distance AND minimun of both value. Distance is control by light.
// The following code do this.
// The min handle the case of having only dynamic objects in the ShadowMap
// The second case for blend with distance is handled with ShadowDimmer. ShadowDimmer is define manually and by shadowDistance by light.
// With distance, ShadowDimmer become one and only the ShadowMask appear, we get the blend with distance behavior.
shadow = light.nonLightMappedOnly ? min(shadowMask, shadow) : shadow;
#endif
shadow = lerp(shadowMask, shadow, light.shadowDimmer);
}
// Transparents have no contact shadow information
#if !defined(_SURFACE_TYPE_TRANSPARENT) && !defined(LIGHT_EVALUATION_NO_CONTACT_SHADOWS)
{
// In certain cases (like hair) we allow to force the contact shadow sample.
#ifdef LIGHT_EVALUATION_CONTACT_SHADOW_DISABLE_NDOTL
const bool allowContactShadow = true;
#else
const bool allowContactShadow = NdotL > 0.0;
#endif
shadow = min(shadow, allowContactShadow ? GetContactShadow(lightLoopContext, light.contactShadowMask, light.isRayTracedContactShadow) : 1.0);
}
#endif
#ifdef DEBUG_DISPLAY
if (_DebugShadowMapMode == SHADOWMAPDEBUGMODE_SINGLE_SHADOW && light.shadowIndex == _DebugSingleShadowIndex)
g_DebugShadowAttenuation = shadow;
#endif
return shadow;
#else // LIGHT_EVALUATION_NO_SHADOWS
return 1.0;
#endif
}
#endif

View File

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

View File

@@ -0,0 +1,59 @@
#ifndef UTS_SINGLE_LIGHT_LOOP
#define UTS_SINGLE_LIGHT_LOOP
#include "Packages/com.misaki.hdrp-toon/Runtime/Models/SurfaceFeature.cs.hlsl"
#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Common/UtsSurfaceFeatureEvaluation.hlsl"
#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Lighting/UtsLightEvaluation.hlsl"
struct UtsSingleMainLight
{
GPULightType lightType;
uint lightIndex;
};
int GetMainLightIndex(BuiltinData builtinData)
{
int mainLightIndex = -1;
if (featureFlags & LIGHTFEATUREFLAGS_DIRECTIONAL)
{
DirectionalLightData light = _DirectionalLightDatas[_DirectionalShadowIndex];
if ((light.lightDimmer > 0) && (light.shadowDimmer > 0) && IsMatchingLightLayer(light.lightLayers, builtinData.renderingLayers))
{
SHADOW_TYPE shadowValue = GetDirectionalShadowAttenuation(context.shadowContext,
posInput.positionSS, _ObjectCenterPositionWS + L * _ShadowDistanceBias, UtsGetShadowNormal(bsdfData),
light.shadowIndex, L);
if (length(shadowValue) > 0.0)
{
mainLightIndex = _DirectionalShadowIndex;
}
}
}
return mainLightIndex;
}
// TODO: The process of finding main light index should be move to vertex stage
void UtsSingleLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bsdfData, BuiltinData builtinData,
float3 V, uint featureFlags, out LightLoopOutput lightLoopOutput)
{
PreLightData preLightData = GetPreLightData_UTS(V, posInput, bsdfData);
AggregateLighting aggregateLighting;
ZERO_INITIALIZE(AggregateLighting, aggregateLighting);
#if _USER_LIGHT_SOURCE_LOOP_ON
#else
int mainLightIndex = GetMainLightIndex(builtinData);
if (mainLightIndex != -1 && featureFlags & LIGHTFEATUREFLAGS_PUNCTUAL)
{
}
#endif
}
#endif

View File

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

View File

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

View File

@@ -1,23 +1,56 @@
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
// Shading Color
TEXTURE2D(_BaseColorMap);
SAMPLER(sampler_BaseColorMap);
TEXTURE2D(_1stShadeColorMap);
TEXTURE2D(_2ndShadeColorMap);
TEXTURE2D(_SDFShadowMap);
SAMPLER(sampler_SDFShadowMap);
TEXTURE2D_ARRAY(_ShadingRampMap);
TEXTURE2D(_ShadingRampMaskMap);
TEXTURE2D(_MatCapMap);
// Shadow
TEXTURE2D(_SDFShadingMap);
SAMPLER(sampler_SDFShadingMap);
// Surface Inputs
TEXTURE2D(_MaskMap);
SAMPLER(sampler_MaskMap);
TEXTURE2D(_NormalMap);
SAMPLER(sampler_NormalMap);
TEXTURE2D(_AnisotropyMap);
SAMPLER(sampler_AnisotropyMap);
TEXTURE2D(_SpecularColorMap);
SAMPLER(sampler_SpecularColorMap);
TEXTURE2D(_SSSLutMap);
TEXTURE2D(_HairBlendingMap);
SAMPLER(sampler_HairBlendingMap);
TEXTURE2D(_EmissiveColorMap);
SAMPLER(sampler_EmissiveColorMap);
// Stocking
TEXTURE2D(_StockingSparkingMap);
SAMPLER(sampler_StockingSparkingMap);
// Global
TEXTURE2D(_HairShadowTex);
TEXTURE2D_X(_HairBlendingTex);
TEXTURE2D(_IndirectDiffuseMatCapMap);
TEXTURE2D(_IndirectSpecularMatCapMap);
TEXTURE2D_ARRAY(_IndirectDiffuseRampMap);
sampler _Set_1st_ShadePosition;
sampler _Set_2nd_ShadePosition;
sampler _HighColor_Tex;
sampler _Set_HighColorMask;
sampler _Set_RimLightMask;
sampler _NormalMapForMatCap;
sampler _Set_MatcapMask;
TEXTURE2D(_ClippingMask);
TEXTURE2D(_AngelRingColorMap);
@@ -28,6 +61,3 @@ SAMPLER(sampler_OutlineWidthMap);
TEXTURE2D(_OutlineColorMap);
SAMPLER(sampler_OutlineColorMap);
TEXTURE2D(_BakedNormalMap);
SAMPLER(sampler_BakedNormalMap);

View File

@@ -1,3 +1,9 @@
// Surface Option
float _SurfaceFeatures;
half _AlphaCutoffEnable;
float _AlphaCutoff;
half _BlendMode;
float4 _DoubleSidedConstants;
// Shading Color
float4 _BaseColor;
@@ -5,176 +11,134 @@ float4 _BaseColorMap_ST;
float4 _BaseColorMap_TexelSize;
float4 _BaseColorMap_MipInfo;
float _ShadingIndex;
int _ShadingIndex;
float _ShadingRampMask;
float4 _1stShadeColor;
float4 _2ndShadeColor;
fixed _UseBaseAs1st;
fixed _Use1stAs2nd;
float _SDFShadowLevel;
float _SDFSmoothLevel;
float _SDFHighlightStrength;
half _UseBaseAs1st;
half _Use1stAs2nd;
float _1stShadeColorStep;
float _1stShadeColorFeather;
float _2ndShadeColorStep;
float _2ndShadeColorFeather;
float _SDFShadowLevel;
float _SDFShadowSmoothLevel;
float _SDFHighlightStrength;
float _utsTechnique;
float4 _Color;
fixed _Set_SystemShadowsToBase;
// Shadow
float _ShadowDistanceBias;
float _ShadowNormalBias;
float _SurfaceFeatures;
// Surface Inputs
float _AlphaRemapMin;
float _AlphaRemapMax;
float _Tweak_SystemShadowsLevel;
float _ShadowBias;
float _NormalScale;
float _EyeParallaxAmount;
float _HairBlendingFactor;
float _Metallic;
float _MetallicRemapMin;
float _MetallicRemapMax;
float _Smoothness;
float _SmoothnessRemapMin;
float _SmoothnessRemapMax;
float _Roughness;
float _RoughnessRemapMin;
float _RoughnessRemapMax;
float _BaseColor_Step;
float _BaseShade_Feather;
float4 _Set_1st_ShadePosition_ST;
float _AORemapMin;
float _AORemapMax;
float _ShadeColor_Step;
float _1st2nd_Shades_Feather;
float4 _Set_2nd_ShadePosition_ST;
float4 _ShadingGradeMap_ST;
float _Anisotropy;
float4 _AnisotropyMap_ST;
float _Tweak_ShadingGradeMapLevel;
fixed _BlurLevelSGM;
//
float4 _KKColor;
float4 _HighColor;
float4 _HighColor_Tex_ST;
fixed _Is_LightColor_HighColor;
float4 _SpecularColor;
float _ToonSpecularStep;
float _ToonSpecularFeather;
float _BSDFContribution;
float _EnergyConservingSpecularColor;
fixed _Is_NormalMapToHighColor;
float _HighColor_Power;
fixed _Is_SpecularToHighColor;
fixed _Is_BlendAddToHiColor;
fixed _Is_BlendAddToRimColor;
fixed _Is_UseTweakHighColorOnShadow;
float _TweakHighColorOnShadow;
float4 _Set_HighColorMask_ST;
float _Tweak_HighColorMaskLevel;
fixed _RimLight;
float4 _RimLightColor;
float _RimLight_Strength;
fixed _Is_LightColor_RimLight;
fixed _Is_NormalMapToRimLight;
float _RimLight_Power;
float _RimLight_InsideMask;
fixed _RimLight_FeatherOff;
fixed _LightDirection_MaskOn;
float _Tweak_LightDirection_MaskLevel;
fixed _Add_Antipodean_RimLight;
float4 _Ap_RimLightColor;
fixed _Is_LightColor_Ap_RimLight;
float _Ap_RimLight_Power;
fixed _Ap_RimLight_FeatherOff;
float4 _Set_RimLightMask_ST;
float _Tweak_RimLightMaskLevel;
fixed _MatCap;
float4 _MatCap_Sampler_ST;
float4 _MatCapColor;
fixed _Is_LightColor_MatCap;
fixed _Is_BlendAddToMatCap;
float _Tweak_MatCapUV;
float _Rotate_MatCapUV;
fixed _Is_NormalMapForMatCap;
float4 _NormalMapForMatCap_ST;
float _Rotate_NormalMapForMatCapUV;
fixed _Is_UseTweakMatCapOnShadow;
float _TweakMatCapOnShadow;
float4 _Set_MatcapMask_ST;
float _Tweak_MatcapMaskLevel;
fixed _Is_Ortho;
float _CameraRolling_Stabilizer;
fixed _BlurLevelMatcap;
fixed _Inverse_MatcapMask;
float _BumpScale;
float _BumpScaleMatcap;
float4 _Emissive_Tex_ST;
float4 _Emissive_Color;
// float _SSSIntensity;
// int _Use_SSSLut;
fixed _Is_ViewCoord_Scroll;
float _Rotate_EmissiveUV;
float _Base_Speed;
float _Scroll_EmissiveU;
float _Scroll_EmissiveV;
fixed _Is_PingPong_Base;
float4 _ColorShift;
float4 _ViewShift;
float _ColorShift_Speed;
fixed _Is_ColorShift;
fixed _Is_ViewShift;
float3 emissive;
//
float _Unlit_Intensity;
float3 _EmissiveColor;
half _AlbedoAffectEmissive;
half _EmissiveExposureWeight;
float4 _EmissiveColorMap_ST;
half _TexWorldScaleEmissive;
fixed _Is_Filter_HiCutPointLightColor;
fixed _Is_Filter_LightColor;
float _ObjectSpaceUVMappingEmissive;
float _StepOffset;
fixed _Is_BLD;
float _Offset_X_Axis_BLD;
float _Offset_Y_Axis_BLD;
fixed _Inverse_Z_Axis_BLD;
// Ambient
float _IndirectDiffuseMatCapLod;
float4 _ClippingMask_ST;
int _IndirectDiffuseRampIndex;
float _IndirectDiffuseRampPosition;
fixed _IsBaseMapAlphaAsClippingMask;
float _Clipping_Level;
fixed _Inverse_Clipping;
float _Tweak_transparency;
fixed _AngelRing;
float _IndirectDiffuseIntensity;
float _SSAOWeight;
float _SSGIWeight;
float _BaseColorVisible;
float _BaseColorOverridden;
float4 _BaseColorMaskColor;
float _FirstShadeVisible;
float _FirstShadeOverridden;
float4 _FirstShadeMaskColor;
float _SecondShadeVisible;
float _SecondShadeOverridden;
float4 _SecondShadeMaskColor;
float _HighlightVisible;
float _HighlightOverridden;
float4 _HighlightMaskColor;
float _AngelRingVisible;
float _AngelRingOverridden;
float4 _AngelRingMaskColor;
float _RimLightVisible;
float _RimLightOverridden;
float4 _RimLightMaskColor;
float _ComposerMaskMode;
int _ClippingMatteMode;
float _GI_Intensity;
float _Light_Intensity_Multiplier;
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;
half _AlbedoAffectRimLight;
float _RimLightLevel;
half _RimLightClipping;
float _RimLightClippingLevel;
float _LightDirectionRimLightLevel;
// Stocking
float _StockingFresnelWidth;
float _StockingSparkleSpacing;
float _StockingSparkleAmount;
float _StockingSparkleSize;
float _StockingSparkleIntensity;
// Outline
float _OutlineWidth;
float4 _OutlineColor;
fixed _AlbedoAffectOutline;
half _AlbedoAffectOutline;
half _SkyColorAffectOutline;
float _SkyColorIntensity;
float _OutlineFadeIn;
float _OutlineFadeOut;
fixed _UseSmoothedNormal;
half _UseSmoothedNormal;
float _Tweak_SystemShadowsLevel;
float _EyeParallaxAmount;
float _HairBlendingFactor;
// Advance
half _ClampLightColor;
float _LightIntensityMultiplier;
float _Minimal_Diffuse_Contribution;
// Light Loop
float3 _ObjectCenterPositionWS;
float _UseShadowThreshold;
float _AlphaCutoffShadow;
float _ComposerMaskMode;
#if defined(_UTS_TOON_EV_PER_MODEL)
// not in materials
@@ -184,9 +148,4 @@ float _ToonEvAdjustmentValueArray[128];
float _ToonEvAdjustmentValueMin;
float _ToonEvAdjustmentValueMax;
float _ToonEvAdjustmentCompensation;
#endif //#if !defined(_UTS_TOON_EV_PER_MODEL)
float _BlendMode;
float3 _ObjectCenterPositionWS;
#endif

View File

@@ -68,13 +68,11 @@ void Frag(PackedVaryingsToPS packedInput,
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput);
FragInputs input = UnpackVaryingsMeshToFragInputs(packedInput.vmesh);
_Color = _BaseColor;
float4 objPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1));
float4 Set_UV0 = input.texCoord0;
// The following temporary definition of unity_AmbientEquator is for HDRP only.
//float4 unity_AmbientEquator = float4(0.05, 0.05, 0.05, 1.0); //Todo.
//v.2.0.9
//float3 envLightSource_GradientEquator = unity_AmbientEquator.rgb > 0.05 ? unity_AmbientEquator.rgb : half3(0.05, 0.05, 0.05);
float3 envLightSource_GradientEquator = ShadeSH9(float4(0, 1, 0, 0));
float3 envLightSource_SkyboxIntensity = max(
@@ -84,8 +82,8 @@ void Frag(PackedVaryingsToPS packedInput,
float3 ambientSkyColor = envLightSource_SkyboxIntensity.rgb > 0.0 ? envLightSource_SkyboxIntensity : envLightSource_GradientEquator;
ambientSkyColor *= GetCurrentExposureMultiplier();
float4 _BlendingTex_var = SAMPLE_TEXTURE2D(_HairBlendingMap, sampler_HairBlendingMap, TRANSFORM_TEX(Set_UV0, _BaseColorMap));
outColor = float4(_BlendingTex_var.rgb * ambientSkyColor, _BlendingTex_var.a);
float4 blendingTex = SAMPLE_TEXTURE2D(_HairBlendingMap, sampler_HairBlendingMap, TRANSFORM_TEX(Set_UV0, _BaseColorMap));
outColor = float4(blendingTex.rgb + ambientSkyColor, blendingTex.a);
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.deviceDepth;

View File

@@ -26,22 +26,6 @@ float4 _LightColor0; // not referenced in c# code ??
return MotionVectorVS(varyingsType, inputMesh, inputPass);
}
#ifdef TESSELLATION_ON
PackedVaryingsToPS VertTesselation(VaryingsToDS input)
{
VaryingsToPS output;
output.vmesh = VertMeshTesselation(input.vmesh);
MotionVectorPositionZBias(output);
output.vpass.positionCS = input.vpass.positionCS;
output.vpass.previousPositionCS = input.vpass.previousPositionCS;
return PackVaryingsToPS(output);
}
#endif // TESSELLATION_ON
#else // _WRITE_TRANSPARENT_MOTION_VECTOR
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl"
@@ -55,30 +39,8 @@ float4 _LightColor0; // not referenced in c# code ??
return PackVaryingsType(varyingsType);
}
#ifdef TESSELLATION_ON
PackedVaryingsToPS VertTesselation(VaryingsToDS input)
{
VaryingsToPS output;
output.vmesh = VertMeshTesselation(input.vmesh);
return PackVaryingsToPS(output);
}
#endif // TESSELLATION_ON
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
#ifdef TESSELLATION_ON
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/TessellationShare.hlsl"
#endif
#ifdef UNITY_VIRTUAL_TEXTURING
#define VT_BUFFER_TARGET SV_Target1
#define EXTRA_BUFFER_TARGET SV_Target2
@@ -86,8 +48,6 @@ float4 _LightColor0; // not referenced in c# code ??
#define EXTRA_BUFFER_TARGET SV_Target1
#endif
void Frag(PackedVaryingsToPS packedInput,
#ifdef OUTPUT_SPLIT_LIGHTING
out float4 outColor : SV_Target0, // outSpecularLighting
@@ -119,47 +79,45 @@ void Frag(PackedVaryingsToPS packedInput,
discard;
}
#endif
#ifdef _IS_CLIPPING_MATTE
if (_ClippingMatteMode != 0)
{
discard;
}
#endif // _IS_CLIPPING_MATTE
#if defined(UTS_DEBUG_SHADOWMAP_NO_OUTLINE)
discard;
#endif
float4 objPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1));
float4 objPos = mul(UNITY_MATRIX_M, float4(0, 0, 0, 1));
float4 uv0 = input.texCoord0;
// The following temporary definition of unity_AmbientEquator is for HDRP only.
//float4 unity_AmbientEquator = float4(0.05, 0.05, 0.05, 1.0); //Todo.
//v.2.0.9
//float3 envLightSource_GradientEquator = unity_AmbientEquator.rgb > 0.05 ? unity_AmbientEquator.rgb : half3(0.05, 0.05, 0.05);
float3 envLightSource_GradientEquator = ShadeSH9(float4(0, 1, 0, 0));
float3 envLightSource_SkyboxIntensity = max(
SampleBakedGI_UTS_OutLine(objPos.xyz, float3(0.0, 0.0, 0.0), input.texCoord1.xy, input.texCoord2.xy),
SampleBakedGI_UTS_OutLine(objPos.xyz, float3(0.0, -1.0, 0.0), input.texCoord1.xy, input.texCoord2.xy)
).rgb;
float3 ambientSkyColor = envLightSource_SkyboxIntensity.rgb > 0.0 ? envLightSource_SkyboxIntensity : envLightSource_GradientEquator;
ambientSkyColor *= GetCurrentExposureMultiplier() * 5.0f;
float3 baseColor = SAMPLE_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, TRANSFORM_TEX(uv0, _BaseColorMap)).rgb;
baseColor *= _BaseColor.rgb;
float4 outlineColor = _OutlineColor;
#if _OUTLINE_COLOR_MAP
#if _OUTLINECOLORMAP
outlineColor *= SAMPLE_TEXTURE2D(_OutlineColorMap, sampler_OutlineColorMap, TRANSFORM_TEX(uv0, _BaseColorMap)).rgb;
#endif
outlineColor.rgb = lerp(outlineColor.rgb * ambientSkyColor, outlineColor.rgb * ambientSkyColor * 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;
@@ -171,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

@@ -146,7 +146,7 @@ void Frag(PackedVaryingsToPS packedInput,
ENCODE_INTO_SSSBUFFER(surfaceData, posInput.positionSS, outSSSBuffer);
#endif
float4 Set_UV0 = input.texCoord0;
float4 _MainTex_var = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, TRANSFORM_TEX(Set_UV0, _MainTex));
float4 _MainTex_var = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, TRANSFORM_TEX(Set_UV0, _BaseColorMap));
surfaceData.baseColor = _MainTex_var.xyz;

View File

@@ -1,6 +1,4 @@
//Unity Toon Shader/HDRP
//nobuyuki@unity3d.com
//toshiyuki@unity3d.com (Universal RP/HDRP)
#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Common/UtsLitData.hlsl"
#define APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
@@ -81,29 +79,13 @@ 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
float4 UV0 = input.texCoord0;
UTSData utsData;
FragInputs input = UnpackVaryingsToFragInputs(packedInput);
// We need to readapt the SS position as our screen space positions are for a low res buffer, but we try to access a full res buffer.
input.positionSS.xy = _OffScreenRendering > 0 ? (input.positionSS.xy * _OffScreenDownsampleFactor) : input.positionSS.xy;
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
// input.positionSS is SV_Position
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);
#ifdef VARYINGS_NEED_POSITION_WS
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
@@ -112,7 +94,7 @@ void Frag(PackedVaryingsToPS packedInput,
float2 viewT = TransformObjectToTangent(V, input.tangentToWorld);
float2 parallaxOffset = viewT;
parallaxOffset.y = -parallaxOffset.y;
UV0.xy = clamp(UV0.xy -_EyeParallaxAmount * parallaxOffset, 0, 1);
input.texCoord0.xy = clamp(input.texCoord0.xy -_EyeParallaxAmount * parallaxOffset, 0, 1);
#endif
#else
@@ -127,7 +109,11 @@ void Frag(PackedVaryingsToPS packedInput,
SurfaceData tempSurfaceData;
BuiltinData builtinData;
GetSurfaceAndBuiltinData(input, V, posInput, tempSurfaceData, builtinData);
UtsGetSurfaceAndBuiltinData(input, V, posInput, tempSurfaceData, builtinData);
float3 doubleSidedConstants = GetDoubleSidedConstants();
ApplyDoubleSidedFlipOrMirror(input, doubleSidedConstants);
UTSSurfaceData surfaceData = GetUTSSurfaceData(input, V);
UtsBSDFData bsdfData = ConvertUTSSurfaceDataToUTSBSDFData(surfaceData);
@@ -138,9 +124,7 @@ void Frag(PackedVaryingsToPS packedInput,
context.shadowContext = InitShadowContext();
context.shadowValue = 1;
context.sampleReflection = 0.0;
#if UNITY_VERSION >= 202120 && UNITY_VERSION < 202320
context.splineVisibility = -1;
#endif
#ifdef APPLY_FOG_ON_SKY_REFLECTIONS
context.positionWS = posInput.positionWS;
#endif
@@ -152,140 +136,21 @@ void Frag(PackedVaryingsToPS packedInput,
// Initialize the contactShadow and contactShadowFade fields
InitContactShadow(posInput, context);
float channelAlpha = 0.0f;
LightLoopOutput lightLoopOutput;
ZERO_INITIALIZE(LightLoopOutput, lightLoopOutput);
UtsLightLoop(input, posInput, bsdfData, builtinData, V, featureFlags, lightLoopOutput);
/*
#ifdef _EMISSIVE_SIMPLE
float4 _Emissive_Tex_var = tex2D(_Emissive_Tex, TRANSFORM_TEX(UV0, _Emissive_Tex));
float emissiveMask = _Emissive_Tex_var.a;
emissive = _Emissive_Tex_var.rgb * _Emissive_Color.rgb * emissiveMask;
#elif _EMISSIVE_ANIMATION
//v.2.0.7 Calculation View Coord UV for Scroll
float3 viewNormal_Emissive = (mul(UNITY_MATRIX_V, float4(i_normalDir, 0))).xyz;
float3 NormalBlend_Emissive_Detail = viewNormal_Emissive * float3(-1, -1, 1);
float3 NormalBlend_Emissive_Base = (mul(UNITY_MATRIX_V, float4(utsData.viewDirection, 0)).xyz * float3(-1, -1, 1)) + float3(0, 0, 1);
float3 noSknewViewNormal_Emissive = NormalBlend_Emissive_Base * dot(NormalBlend_Emissive_Base, NormalBlend_Emissive_Detail) / NormalBlend_Emissive_Base.z - NormalBlend_Emissive_Detail;
float2 _ViewNormalAsEmissiveUV = noSknewViewNormal_Emissive.xy * 0.5 + 0.5;
float2 _ViewCoord_UV = RotateUV(_ViewNormalAsEmissiveUV, -(utsData.cameraDir * utsData.cameraRoll), float2(0.5, 0.5), 1.0);
//Invert if it's "inside the mirror".
if (utsData.signMirror < 0) {
_ViewCoord_UV.x = 1 - _ViewCoord_UV.x;
}
else {
_ViewCoord_UV = _ViewCoord_UV;
}
float2 emissive_uv = lerp(UV0, _ViewCoord_UV, _Is_ViewCoord_Scroll);
//
float4 _time_var = _Time;
float _base_Speed_var = (_time_var.g * _Base_Speed);
float _Is_PingPong_Base_var = lerp(_base_Speed_var, sin(_base_Speed_var), _Is_PingPong_Base);
float2 scrolledUV = emissive_uv + float2(_Scroll_EmissiveU, _Scroll_EmissiveV) * _Is_PingPong_Base_var;
float rotateVelocity = _Rotate_EmissiveUV * 3.141592654;
float2 _rotate_EmissiveUV_var = RotateUV(scrolledUV, rotateVelocity, float2(0.5, 0.5), _Is_PingPong_Base_var);
float4 _Emissive_Tex_var = tex2D(_Emissive_Tex, TRANSFORM_TEX(UV0, _Emissive_Tex));
float emissiveMask = _Emissive_Tex_var.a;
_Emissive_Tex_var = tex2D(_Emissive_Tex, TRANSFORM_TEX(_rotate_EmissiveUV_var, _Emissive_Tex));
float _colorShift_Speed_var = 1.0 - cos(_time_var.g * _ColorShift_Speed);
float viewShift_var = smoothstep(0.0, 1.0, max(0, dot(utsData.normalDirection, utsData.viewDirection)));
float4 colorShift_Color = lerp(_Emissive_Color, lerp(_Emissive_Color, _ColorShift, _colorShift_Speed_var), _Is_ColorShift);
float4 viewShift_Color = lerp(_ViewShift, colorShift_Color, viewShift_var);
float4 emissive_Color = lerp(colorShift_Color, viewShift_Color, _Is_ViewShift);
emissive = emissive_Color.rgb * _Emissive_Tex_var.rgb * emissiveMask;
//
//v.2.0.6: GI_Intensity with Intensity Multiplier Filter
#endif
*/
// We directly calculate custome main light during the light loop in upper code to avoid extra calculation
//customMainLight = GetCustomMainLightData(builtinData, mainPunctualLight);
/*
#if _SHADOW_MODE_SDF || (_RECEIVE_HAIR_SHADOW_ON && ENABLE_UTS_HAIR_SHAOW)
float3 defaultLightDirection = normalize(UNITY_MATRIX_V[2].xyz + UNITY_MATRIX_V[1].xyz);
float3 defaultLightColor = saturate(max(float3(0.05, 0.05, 0.05) * _Unlit_Intensity, max(ShadeSH9(float4(0.0, 0.0, 0.0, 1.0)), ShadeSH9(float4(0.0, -1.0, 0.0, 1.0)).rgb) * _Unlit_Intensity));
float3 customLightDirection = normalize(mul(UNITY_MATRIX_M, float4(((float3(1.0, 0.0, 0.0) * _Offset_X_Axis_BLD * 10) + (float3(0.0, 1.0, 0.0) * _Offset_Y_Axis_BLD * 10) + (float3(0.0, 0.0, -1.0) * lerp(-1.0, 1.0, _Inverse_Z_Axis_BLD))), 0)).xyz);
float3 lightDirection = normalize(lerp(defaultLightDirection, customMainLight.lightDirection.xyz, any(customMainLight.lightDirection.xyz)));
lightDirection = lerp(lightDirection, customLightDirection, _Is_BLD);
float3 originalLightColor = customMainLight.lightColor.rgb;
originalLightColor = lerp(originalLightColor, clamp(originalLightColor, ConvertFromEV100(_ToonEvAdjustmentValueMin ), ConvertFromEV100(_ToonEvAdjustmentValueMax)), _ToonEvAdjustmentCurve) * _Light_Intensity_Multiplier;
float3 lightColor = lerp(max(defaultLightColor, originalLightColor), max(defaultLightColor, saturate(originalLightColor)), max(_Is_Filter_LightColor, _ToonLightHiCutFilter));
float4 _1st_ShadeMap_var = lerp(SAMPLE_TEXTURE2D(_1st_ShadeMap, sampler_BaseColorMap,TRANSFORM_TEX(UV0, _1st_ShadeMap)), _MainTex_var, _Use_BaseAs1st);
float3 _1st_Shade_var = lerp((_1st_ShadeMap_var.rgb * _1st_ShadeColor.rgb), ((_1st_ShadeMap_var.rgb * _1st_ShadeColor.rgb) * lightColor), _Is_LightColor_1st_Shade);
float systemShadowValue = lerp(1.0f, saturate(customMainLight.shadowValue * 2.0f), _Set_SystemShadowsToBase);
#endif
#if _SHADOW_MODE_SDF
// modified by Suomi @ 20230902 - SDFResult is used to sample SDF texture on the correct side
float angle;
bool rightside;
float2 SDF_UV = TRANSFORM_TEX(UV0, _BaseColorMap);
float4 sdfRes = SDFResult(rightside, angle, customMainLight.lightDirection, SDF_UV);
float sdfShadowValue = 1.0f - SDFMask(angle, sdfRes.r);
utsAggregateLighting.directDiffuse = lerp(_1st_Shade_var, bsdfData.diffuseColor * _BaseColor.rgb * lightColor, sdfShadowValue * systemShadowValue);
utsAggregateLighting.directSpecular = lerp(0, utsAggregateLighting.directSpecular, sdfShadowValue * systemShadowValue);
utsAggregateLighting.directSpecular += _SDFNoseHighlightCoef * SDFNoseHighlight(angle, sdfRes.g, rightside, SDF_UV) * lightColor;
#endif
#if _RECEIVE_HAIR_SHADOW_ON && ENABLE_UTS_HAIR_SHAOW
// Push the face fragment view space position towards the light for a little bit
float hairShadowOpacity = saturate(Remap(length(posInput.positionWS), float2(_HairShadowFadeOutDistance, _HairShadowFadeInDistance), float2(0, 1)));
float3 viewLightDir = TransformWorldToViewDir(customMainLight.lightDirection); // / posInput.deviceDepth; when linearDepth grows large, the movement amount should be lower since we are getting further from the face.
float3 cameraDirOS = normalize(TransformWorldToObject(GetCameraPositionWS()));
float shadowLengthY = _HairShadowDistance * 5.0 * max(0.5, posInput.linearDepth * _HairShadowDistanceScaleFactor) / posInput.linearDepth;
float2 shadowLength = float2(shadowLengthY * 2.0f, shadowLengthY);
float3 camDirOS = normalize(TransformWorldToObject(GetCameraPositionWS()));
float camDirFactor = 1 - smoothstep(0.1, 0.9, camDirOS.y);
shadowLength.y *= camDirFactor;
float2 samplingPoint = (input.positionSS.xy + shadowLength * viewLightDir.xy * (_ScreenSize.xy / float2 (1920.0f, 1080.0f))) * _ScreenSize.zw; // Use 1080p as the reference resolution to achieve consistent shadow lengths across various screen resolutions.
// Then sample the hair buffer, to see if the fragment lands in shadow.
float2 scaledUVs = samplingPoint * _HairShadowRTHandleScale; // We have to including the scaling factor for our shadow map since we are not going to allocate new texture if the rendering resolution changed.
float hairDepth = SAMPLE_TEXTURE2D(_HairShadowTex, s_trilinear_clamp_sampler, scaledUVs).r;
float depthCorrect = posInput.deviceDepth <= hairDepth + _HairShadowDepthBias ? 1 : 0; // Hair < Face means Hair are closer to camera
// Note that we have LinearEyeDepth in the buffer. A comparison of depth is needed so that we don't project the shadow of hair behind the face.
float hairShadow = lerp(0,hairShadowOpacity,depthCorrect);
utsAggregateLighting.directDiffuse = lerp(utsAggregateLighting.directDiffuse, _1st_Shade_var, hairShadow * systemShadowValue);
utsAggregateLighting.directSpecular = lerp(utsAggregateLighting.directSpecular, 0, hairShadow * systemShadowValue);
#endif
*/
//outColor.rgb = lightLoopOutput.diffuseLighting + lightLoopOutput.specularLighting;
//outColor.a = 1.0;
//return;
float3 finalColor = lightLoopOutput.diffuseLighting + lightLoopOutput.specularLighting;
#ifdef _IS_TRANSCLIPPING_OFF
outColor = float4(finalColor, 1 * ApplyChannelAlpha(channelAlpha));
#elif _IS_TRANSCLIPPING_ON
float Set_Opacity = saturate((inverseClipping + _Tweak_transparency));
outColor = EvaluateAtmosphericScattering(posInput, V, float4(finalColor, 1));
outColor = float4(outColor.rgb, Set_Opacity * ApplyChannelAlpha(channelAlpha));
#endif
outColor = ApplyBlendMode(lightLoopOutput.diffuseLighting, lightLoopOutput.specularLighting, builtinData.opacity);
#if _MATERIAL_TYPE_FRONTHAIR && ENABLE_UTS_HAIR_BLENDING
float2 screenUV = posInput.positionNDC * _HairBlendingRTHandleScale.xy;
float4 hairBlendingMap = SAMPLE_TEXTURE2D(_HairBlendingTex, s_trilinear_clamp_sampler, screenUV);
outColor.rgb = lerp(outColor.rgb, hairBlendingMap.rgb, hairBlendingMap.a * _HairBlendingFactor);
float2 screenUV = posInput.positionSS; // * _HairBlendingRTHandleScale.xy; // Why we don't need to scale? Does unity handle it internally?
float4 hairBlendingTex = LOAD_TEXTURE2D_X(_HairBlendingTex, screenUV);
outColor.rgb = lerp(outColor.rgb, hairBlendingTex.rgb, hairBlendingTex.a * _HairBlendingFactor);
#endif
#if _ENABLE_FOG_ON_TRANSPARENT && _SURFACE_TYPE_TRANSPARENT
outColor = EvaluateAtmosphericScattering(posInput, V, outColor);
#endif
#if UTS_DEBUG_SHADOWMAP || UTS_DEBUG_SELFSHADOW
@@ -311,4 +176,5 @@ void Frag(PackedVaryingsToPS packedInput,
outVTFeedback = builtinData.vtPackedFeedback;
#endif
//outColor.rgb = input.isFrontFace;
}

Some files were not shown because too many files have changed in this diff Show More