diff options
| -rw-r--r-- | Editor/tooner.cs | 63 | ||||
| -rw-r--r-- | Third_Party/gen_sdf | 50 | ||||
| -rw-r--r-- | feature_macros.cginc | 28 | ||||
| -rw-r--r-- | globals.cginc | 112 | ||||
| -rw-r--r-- | macros.cginc | 11 | ||||
| -rw-r--r-- | tooner.shader | 156 | ||||
| -rw-r--r-- | tooner_lighting.cginc | 344 |
7 files changed, 618 insertions, 146 deletions
diff --git a/Editor/tooner.cs b/Editor/tooner.cs index c92f35d..865934d 100644 --- a/Editor/tooner.cs +++ b/Editor/tooner.cs @@ -519,10 +519,18 @@ public class ToonerGUI : ShaderGUI { show_ui.RemoveAt(show_ui.Count - 1); } + enum TilingMode { + Clamp, + Repeat, + } + enum BaseColorMode { + Color, + SDF, + } void DoDecal() { show_ui.Add(AddCollapsibleMenu("Decals", "_Decal")); EditorGUI.indentLevel += 1; - for (int i = 0; i < 4; i++) { + for (int i = 0; i < 10; i++) { show_ui.Add(AddCollapsibleMenu($"Decal {i}", $"_Decal{i}")); EditorGUI.indentLevel += 1; @@ -535,12 +543,27 @@ public class ToonerGUI : ShaderGUI { SetKeyword($"_DECAL{i}", enabled); if (enabled) { - bc = FindProperty($"_Decal{i}_BaseColor"); - TexturePropertySingleLine( - MakeLabel(bc, "Base color (RGBA)"), - bc); - if (bc.textureValue) { - TextureScaleOffsetProperty(bc); + MaterialProperty bct; + bc = FindProperty($"_Decal{i}_Color"); + bct = FindProperty($"_Decal{i}_BaseColor"); + TexturePropertySingleLine(MakeLabel(bct, "Base color (RGBA)"), bct, bc); + // Unconditionally drive scale + offset because it affects all textures. + TextureScaleOffsetProperty(bct); + + bc = FindProperty($"_Decal{i}_BaseColor_Mode"); + BaseColorMode base_color_mode = (BaseColorMode) Math.Round(bc.floatValue); + base_color_mode = (BaseColorMode) EnumPopup(MakeLabel("Base color mode"), base_color_mode); + bc.floatValue = (int) base_color_mode; + + if (base_color_mode == BaseColorMode.SDF) { + bc = FindProperty($"_Decal{i}_SDF_Threshold"); + RangeProperty(bc, "SDF threshold"); + + bc = FindProperty($"_Decal{i}_SDF_Softness"); + RangeProperty(bc, "SDF softness"); + + bc = FindProperty($"_Decal{i}_SDF_Px_Range"); + FloatProperty(bc, "SDF px range"); } bc = FindProperty($"_Decal{i}_Roughness"); @@ -564,6 +587,30 @@ public class ToonerGUI : ShaderGUI { bc, "Angle"); + bc = FindProperty($"_Decal{i}_Alpha_Multiplier"); + RangeProperty(bc, "Alpha multiplier"); + + bc = FindProperty($"_Decal{i}_Round_Alpha_Multiplier"); + + bct = FindProperty($"_Decal{i}_Mask"); + TexturePropertySingleLine(MakeLabel(bct, "Mask"), bct); + SetKeyword($"_DECAL{i}_MASK", bct.textureValue); + + if (bct.textureValue) { + bc = FindProperty($"_Decal{i}_Mask_Invert"); + enabled = bc.floatValue > 1E-6; + EditorGUI.BeginChangeCheck(); + enabled = Toggle("Invert mask", enabled); + EditorGUI.EndChangeCheck(); + bc.floatValue = enabled ? 1.0f : 0.0f; + } + + bc = FindProperty($"_Decal{i}_Tiling_Mode"); + TilingMode tiling_mode = (TilingMode) Math.Round(bc.floatValue); + tiling_mode = (TilingMode) EnumPopup( + MakeLabel("Tiling mode"), tiling_mode); + bc.floatValue = (int) tiling_mode; + bc = FindProperty($"_Decal{i}_UV_Select"); RangeProperty( bc, @@ -688,7 +735,7 @@ public class ToonerGUI : ShaderGUI { if (bc.textureValue) { EditorGUI.indentLevel += 1; - bc = FindProperty($"_Matcap{i}_Mask2_Invert"); + bc = FindProperty($"_Matcap{i}_Mask2_Invert_Colors"); enabled = bc.floatValue > 1E-6; EditorGUI.BeginChangeCheck(); enabled = Toggle("Invert mask colors", enabled); diff --git a/Third_Party/gen_sdf b/Third_Party/gen_sdf new file mode 100644 index 0000000..84677c2 --- /dev/null +++ b/Third_Party/gen_sdf @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 + +import numpy as np +import cv2 +import argparse +import os + +def compute_sdf(img, scale_factor): + # Convert to binary image if not already + _, binary = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) + + # Compute distance transform for both foreground and background + dist_transform_fg = cv2.distanceTransform(binary, cv2.DIST_L2, 5) + dist_transform_bg = cv2.distanceTransform(255 - binary, cv2.DIST_L2, 5) + + # Combine the distance fields and scale by factor + sdf = (dist_transform_fg - dist_transform_bg) / scale_factor + + # Clamp values to [0, 255] range + sdf = np.clip(sdf + 128, 0, 255) + + return sdf.astype(np.uint8) + +def main(): + parser = argparse.ArgumentParser(description='Generate SDF from black and white image') + parser.add_argument('input_image', help='Path to input image') + parser.add_argument('--scale', type=float, default=1.0, + help='Scale factor for distance (in texels)') + args = parser.parse_args() + + # Get input and output paths + input_path = args.input_image + filename, ext = os.path.splitext(input_path) + output_path = f"{filename}-sdf{ext}" + + # Read input image + img = cv2.imread(input_path, cv2.IMREAD_GRAYSCALE) + if img is None: + print(f"Error: Could not read image {input_path}") + return + + # Compute SDF with scale factor + sdf = compute_sdf(img, args.scale) + + # Save result + cv2.imwrite(output_path, sdf) + print(f"SDF generated and saved to {output_path}") + +if __name__ == "__main__": + main() diff --git a/feature_macros.cginc b/feature_macros.cginc index a002525..e57117e 100644 --- a/feature_macros.cginc +++ b/feature_macros.cginc @@ -177,15 +177,43 @@ #pragma shader_feature_local _ _DECAL0 #pragma shader_feature_local _ _DECAL0_ROUGHNESS #pragma shader_feature_local _ _DECAL0_METALLIC +#pragma shader_feature_local _ _DECAL0_MASK #pragma shader_feature_local _ _DECAL1 #pragma shader_feature_local _ _DECAL1_ROUGHNESS #pragma shader_feature_local _ _DECAL1_METALLIC +#pragma shader_feature_local _ _DECAL1_MASK #pragma shader_feature_local _ _DECAL2 #pragma shader_feature_local _ _DECAL2_ROUGHNESS #pragma shader_feature_local _ _DECAL2_METALLIC +#pragma shader_feature_local _ _DECAL2_MASK #pragma shader_feature_local _ _DECAL3 #pragma shader_feature_local _ _DECAL3_ROUGHNESS #pragma shader_feature_local _ _DECAL3_METALLIC +#pragma shader_feature_local _ _DECAL3_MASK +#pragma shader_feature_local _ _DECAL4 +#pragma shader_feature_local _ _DECAL4_ROUGHNESS +#pragma shader_feature_local _ _DECAL4_METALLIC +#pragma shader_feature_local _ _DECAL4_MASK +#pragma shader_feature_local _ _DECAL5 +#pragma shader_feature_local _ _DECAL5_ROUGHNESS +#pragma shader_feature_local _ _DECAL5_METALLIC +#pragma shader_feature_local _ _DECAL5_MASK +#pragma shader_feature_local _ _DECAL6 +#pragma shader_feature_local _ _DECAL6_ROUGHNESS +#pragma shader_feature_local _ _DECAL6_METALLIC +#pragma shader_feature_local _ _DECAL6_MASK +#pragma shader_feature_local _ _DECAL7 +#pragma shader_feature_local _ _DECAL7_ROUGHNESS +#pragma shader_feature_local _ _DECAL7_METALLIC +#pragma shader_feature_local _ _DECAL7_MASK +#pragma shader_feature_local _ _DECAL8 +#pragma shader_feature_local _ _DECAL8_ROUGHNESS +#pragma shader_feature_local _ _DECAL8_METALLIC +#pragma shader_feature_local _ _DECAL8_MASK +#pragma shader_feature_local _ _DECAL9 +#pragma shader_feature_local _ _DECAL9_ROUGHNESS +#pragma shader_feature_local _ _DECAL9_METALLIC +#pragma shader_feature_local _ _DECAL9_MASK #pragma shader_feature_local _ _LTCGI #pragma shader_feature_local _ _TESSELLATION #pragma shader_feature_local _ _MATCAP0_DISTORTION0 diff --git a/globals.cginc b/globals.cginc index 31e012d..71147fb 100644 --- a/globals.cginc +++ b/globals.cginc @@ -1,4 +1,5 @@ #include "AutoLight.cginc" +#include "macros.cginc" #ifndef __GLOBALS_INC #define __GLOBALS_INC @@ -257,41 +258,96 @@ float _PBR_Overlay3_Mip_Bias; float _PBR_Overlay3_Mask_Glitter; #endif +#define DECAL_PROPERTIES(n) \ +float4 MERGE(_Decal,n,_Color); \ +texture2D MERGE(_Decal,n,_BaseColor); \ +float4 MERGE(_Decal,n,_BaseColor_TexelSize); \ +float4 MERGE(_Decal,n,_BaseColor_ST); \ +float MERGE(_Decal,n,_BaseColor_Mode); \ +texture2D MERGE(_Decal,n,_Roughness); \ +texture2D MERGE(_Decal,n,_Metallic); \ +float MERGE(_Decal,n,_Emission_Strength); \ +float MERGE(_Decal,n,_Angle); \ +float MERGE(_Decal,n,_Alpha_Multiplier); \ +float MERGE(_Decal,n,_Round_Alpha_Multiplier); \ +float MERGE(_Decal,n,_SDF_Threshold); \ +float MERGE(_Decal,n,_SDF_Softness); \ +float MERGE(_Decal,n,_SDF_Px_Range); \ +float MERGE(_Decal,n,_Tiling_Mode); \ +float MERGE(_Decal,n,_UV_Select); + +#define DECAL_MASK_PROPERTIES(n) \ +texture2D MERGE(_Decal,n,_Mask); \ +float MERGE(_Decal,n,_Mask_Invert); + #if defined(_DECAL0) -texture2D _Decal0_BaseColor; -float4 _Decal0_BaseColor_ST; -texture2D _Decal0_Roughness; -texture2D _Decal0_Metallic; -float _Decal0_Emission_Strength; -float _Decal0_Angle; -float _Decal0_UV_Select; +DECAL_PROPERTIES(0) +#if defined(_DECAL0_MASK) +DECAL_MASK_PROPERTIES(0) +#endif + #endif #if defined(_DECAL1) -texture2D _Decal1_BaseColor; -float4 _Decal1_BaseColor_ST; -texture2D _Decal1_Roughness; -texture2D _Decal1_Metallic; -float _Decal1_Emission_Strength; -float _Decal1_Angle; -float _Decal1_UV_Select; +DECAL_PROPERTIES(1) +#if defined(_DECAL1_MASK) +DECAL_MASK_PROPERTIES(1) +#endif #endif + #if defined(_DECAL2) -texture2D _Decal2_BaseColor; -float4 _Decal2_BaseColor_ST; -texture2D _Decal2_Roughness; -texture2D _Decal2_Metallic; -float _Decal2_Emission_Strength; -float _Decal2_Angle; -float _Decal2_UV_Select; +DECAL_PROPERTIES(2) +#if defined(_DECAL2_MASK) +DECAL_MASK_PROPERTIES(2) +#endif #endif + #if defined(_DECAL3) -texture2D _Decal3_BaseColor; -float4 _Decal3_BaseColor_ST; -texture2D _Decal3_Roughness; -texture2D _Decal3_Metallic; -float _Decal3_Emission_Strength; -float _Decal3_Angle; -float _Decal3_UV_Select; +DECAL_PROPERTIES(3) +#if defined(_DECAL3_MASK) +DECAL_MASK_PROPERTIES(3) +#endif +#endif + +#if defined(_DECAL4) +DECAL_PROPERTIES(4) +#if defined(_DECAL4_MASK) +DECAL_MASK_PROPERTIES(4) +#endif +#endif + +#if defined(_DECAL5) +DECAL_PROPERTIES(5) +#if defined(_DECAL5_MASK) +DECAL_MASK_PROPERTIES(5) +#endif +#endif + +#if defined(_DECAL6) +DECAL_PROPERTIES(6) +#if defined(_DECAL6_MASK) +DECAL_MASK_PROPERTIES(6) +#endif +#endif + +#if defined(_DECAL7) +DECAL_PROPERTIES(7) +#if defined(_DECAL7_MASK) +DECAL_MASK_PROPERTIES(7) +#endif +#endif + +#if defined(_DECAL8) +DECAL_PROPERTIES(8) +#if defined(_DECAL8_MASK) +DECAL_MASK_PROPERTIES(8) +#endif +#endif + +#if defined(_DECAL9) +DECAL_PROPERTIES(9) +#if defined(_DECAL9_MASK) +DECAL_MASK_PROPERTIES(9) +#endif #endif #if defined(_EMISSION) diff --git a/macros.cginc b/macros.cginc new file mode 100644 index 0000000..9c5e5fc --- /dev/null +++ b/macros.cginc @@ -0,0 +1,11 @@ +#ifndef __MACROS_INC +#define __MACROS_INC + +// https://isocpp.org/wiki/faq/misc-technical-issues#macros-with-token-pasting +#define _MERGE_IMPL(a,b) a##b +#define MERGE(a,b) _MERGE_IMPL(a,b) + +#define _MERGE_IMPL(a,b,c) a##b##c +#define MERGE(a,b,c) _MERGE_IMPL(a,b,c) + +#endif
\ No newline at end of file diff --git a/tooner.shader b/tooner.shader index 1f37a78..e2c757e 100644 --- a/tooner.shader +++ b/tooner.shader @@ -130,37 +130,185 @@ Shader "yum_food/tooner" _PBR_Overlay3_Mask_Glitter("Mask glitter", Float) = 0.0 _Decal0_Enable("Enable decal", Float) = 0.0 + _Decal0_Color("Base color", Color) = (1, 1, 1, 1) _Decal0_BaseColor("Base color", 2D) = "white" {} + _Decal0_BaseColor_Mode("Base color mode", Float) = 0 + _Decal0_SDF_Threshold("SDF threshold", Range(0, 1)) = 0.5 + _Decal0_SDF_Softness("SDF softness", Range(0, 1)) = 0.01 + _Decal0_SDF_Px_Range("SDF px range", Float) = 2 _Decal0_Roughness("Roughness", 2D) = "white" {} _Decal0_Metallic("Metallic", 2D) = "black" {} _Decal0_Emission_Strength("Emission strength", Float) = 0 _Decal0_Angle("Emission strength", Range(0,1)) = 0 + _Decal0_Alpha_Multiplier("Alpha multiplier", Range(0, 1)) = 1 + _Decal0_Round_Alpha_Multiplier("Round alpha multiplier", Float) = 0 + _Decal0_Mask("Mask", 2D) = "white" {} + _Decal0_Mask_Invert("Mask invert", Float) = 0.0 + _Decal0_Tiling_Mode("Tiling mode", Range(0,1)) = 0 _Decal0_UV_Select("UV channel", Range(0,7)) = 0 _Decal1_Enable("Enable decal", Float) = 0.0 + _Decal1_Color("Base color", Color) = (1, 1, 1, 1) _Decal1_BaseColor("Base color", 2D) = "white" {} + _Decal1_BaseColor_Mode("Base color mode", Float) = 0 + _Decal1_SDF_Threshold("SDF threshold", Range(0, 1)) = 0.5 + _Decal1_SDF_Softness("SDF softness", Range(0, 1)) = 0.01 + _Decal1_SDF_Px_Range("SDF px range", Float) = 2 _Decal1_Roughness("Roughness", 2D) = "white" {} _Decal1_Metallic("Metallic", 2D) = "black" {} _Decal1_Emission_Strength("Emission strength", Float) = 0 _Decal1_Angle("Emission strength", Range(0,1)) = 0 + _Decal1_Alpha_Multiplier("Alpha multiplier", Range(0, 1)) = 1 + _Decal1_Round_Alpha_Multiplier("Round alpha multiplier", Float) = 0 + _Decal1_Mask("Mask", 2D) = "white" {} + _Decal1_Mask_Invert("Mask invert", Float) = 0.0 + _Decal1_Tiling_Mode("Tiling mode", Range(0,1)) = 0 _Decal1_UV_Select("UV channel", Range(0,7)) = 0 _Decal2_Enable("Enable decal", Float) = 0.0 + _Decal2_Color("Base color", Color) = (1, 1, 1, 1) _Decal2_BaseColor("Base color", 2D) = "white" {} + _Decal2_BaseColor_Mode("Base color mode", Float) = 0 + _Decal2_SDF_Threshold("SDF threshold", Range(0, 1)) = 0.5 + _Decal2_SDF_Softness("SDF softness", Range(0, 1)) = 0.01 + _Decal2_SDF_Px_Range("SDF px range", Float) = 2 _Decal2_Roughness("Roughness", 2D) = "white" {} _Decal2_Metallic("Metallic", 2D) = "black" {} _Decal2_Emission_Strength("Emission strength", Float) = 0 _Decal2_Angle("Emission strength", Range(0,1)) = 0 + _Decal2_Alpha_Multiplier("Alpha multiplier", Range(0, 1)) = 1 + _Decal2_Round_Alpha_Multiplier("Round alpha multiplier", Float) = 0 + _Decal2_Mask("Mask", 2D) = "white" {} + _Decal2_Mask_Invert("Mask invert", Float) = 0.0 + _Decal2_Tiling_Mode("Tiling mode", Range(0,1)) = 0 _Decal2_UV_Select("UV channel", Range(0,7)) = 0 _Decal3_Enable("Enable decal", Float) = 0.0 + _Decal3_Color("Base color", Color) = (1, 1, 1, 1) _Decal3_BaseColor("Base color", 2D) = "white" {} + _Decal3_BaseColor_Mode("Base color mode", Float) = 0 + _Decal3_SDF_Threshold("SDF threshold", Range(0, 1)) = 0.5 + _Decal3_SDF_Softness("SDF softness", Range(0, 1)) = 0.01 + _Decal3_SDF_Px_Range("SDF px range", Float) = 2 _Decal3_Roughness("Roughness", 2D) = "white" {} _Decal3_Metallic("Metallic", 2D) = "black" {} _Decal3_Emission_Strength("Emission strength", Float) = 0 _Decal3_Angle("Emission strength", Range(0,1)) = 0 + _Decal3_Alpha_Multiplier("Alpha multiplier", Range(0, 1)) = 1 + _Decal3_Round_Alpha_Multiplier("Round alpha multiplier", Float) = 0 + _Decal3_Mask("Mask", 2D) = "white" {} + _Decal3_Mask_Invert("Mask invert", Float) = 0.0 + _Decal3_Tiling_Mode("Tiling mode", Range(0,1)) = 0 _Decal3_UV_Select("UV channel", Range(0,7)) = 0 + _Decal4_Enable("Enable decal", Float) = 0.0 + _Decal4_Color("Base color", Color) = (1, 1, 1, 1) + _Decal4_BaseColor("Base color", 2D) = "white" {} + _Decal4_BaseColor_Mode("Base color mode", Float) = 0 + _Decal4_SDF_Threshold("SDF threshold", Range(0, 1)) = 0.5 + _Decal4_SDF_Softness("SDF softness", Range(0, 1)) = 0.01 + _Decal4_SDF_Px_Range("SDF px range", Float) = 2 + _Decal4_Roughness("Roughness", 2D) = "white" {} + _Decal4_Metallic("Metallic", 2D) = "black" {} + _Decal4_Emission_Strength("Emission strength", Float) = 0 + _Decal4_Angle("Emission strength", Range(0,1)) = 0 + _Decal4_Alpha_Multiplier("Alpha multiplier", Range(0, 1)) = 1 + _Decal4_Round_Alpha_Multiplier("Round alpha multiplier", Float) = 0 + _Decal4_Mask("Mask", 2D) = "white" {} + _Decal4_Mask_Invert("Mask invert", Float) = 0.0 + _Decal4_Tiling_Mode("Tiling mode", Range(0,1)) = 0 + _Decal4_UV_Select("UV channel", Range(0,7)) = 0 + + _Decal5_Enable("Enable decal", Float) = 0.0 + _Decal5_Color("Base color", Color) = (1, 1, 1, 1) + _Decal5_BaseColor("Base color", 2D) = "white" {} + _Decal5_BaseColor_Mode("Base color mode", Float) = 0 + _Decal5_SDF_Threshold("SDF threshold", Range(0, 1)) = 0.5 + _Decal5_SDF_Softness("SDF softness", Range(0, 1)) = 0.01 + _Decal5_SDF_Px_Range("SDF px range", Float) = 2 + _Decal5_Roughness("Roughness", 2D) = "white" {} + _Decal5_Metallic("Metallic", 2D) = "black" {} + _Decal5_Emission_Strength("Emission strength", Float) = 0 + _Decal5_Angle("Emission strength", Range(0,1)) = 0 + _Decal5_Alpha_Multiplier("Alpha multiplier", Range(0, 1)) = 1 + _Decal5_Round_Alpha_Multiplier("Round alpha multiplier", Float) = 0 + _Decal5_Mask("Mask", 2D) = "white" {} + _Decal5_Mask_Invert("Mask invert", Float) = 0.0 + _Decal5_Tiling_Mode("Tiling mode", Range(0,1)) = 0 + _Decal5_UV_Select("UV channel", Range(0,7)) = 0 + + _Decal6_Enable("Enable decal", Float) = 0.0 + _Decal6_Color("Base color", Color) = (1, 1, 1, 1) + _Decal6_BaseColor("Base color", 2D) = "white" {} + _Decal6_BaseColor_Mode("Base color mode", Float) = 0 + _Decal6_SDF_Threshold("SDF threshold", Range(0, 1)) = 0.5 + _Decal6_SDF_Softness("SDF softness", Range(0, 1)) = 0.01 + _Decal6_SDF_Px_Range("SDF px range", Float) = 2 + _Decal6_Roughness("Roughness", 2D) = "white" {} + _Decal6_Metallic("Metallic", 2D) = "black" {} + _Decal6_Emission_Strength("Emission strength", Float) = 0 + _Decal6_Angle("Emission strength", Range(0,1)) = 0 + _Decal6_Alpha_Multiplier("Alpha multiplier", Range(0, 1)) = 1 + _Decal6_Round_Alpha_Multiplier("Round alpha multiplier", Float) = 0 + _Decal6_Mask("Mask", 2D) = "white" {} + _Decal6_Mask_Invert("Mask invert", Float) = 0.0 + _Decal6_Tiling_Mode("Tiling mode", Range(0,1)) = 0 + _Decal6_UV_Select("UV channel", Range(0,7)) = 0 + + _Decal7_Enable("Enable decal", Float) = 0.0 + _Decal7_Color("Base color", Color) = (1, 1, 1, 1) + _Decal7_BaseColor("Base color", 2D) = "white" {} + _Decal7_BaseColor_Mode("Base color mode", Float) = 0 + _Decal7_SDF_Threshold("SDF threshold", Range(0, 1)) = 0.5 + _Decal7_SDF_Softness("SDF softness", Range(0, 1)) = 0.01 + _Decal7_SDF_Px_Range("SDF px range", Float) = 2 + _Decal7_Roughness("Roughness", 2D) = "white" {} + _Decal7_Metallic("Metallic", 2D) = "black" {} + _Decal7_Emission_Strength("Emission strength", Float) = 0 + _Decal7_Angle("Emission strength", Range(0,1)) = 0 + _Decal7_Alpha_Multiplier("Alpha multiplier", Range(0, 1)) = 1 + _Decal7_Round_Alpha_Multiplier("Round alpha multiplier", Float) = 0 + _Decal7_Mask("Mask", 2D) = "white" {} + _Decal7_Mask_Invert("Mask invert", Float) = 0.0 + _Decal7_Tiling_Mode("Tiling mode", Range(0,1)) = 0 + _Decal7_UV_Select("UV channel", Range(0,7)) = 0 + + _Decal8_Enable("Enable decal", Float) = 0.0 + _Decal8_Color("Base color", Color) = (1, 1, 1, 1) + _Decal8_BaseColor("Base color", 2D) = "white" {} + _Decal8_BaseColor_Mode("Base color mode", Float) = 0 + _Decal8_SDF_Threshold("SDF threshold", Range(0, 1)) = 0.5 + _Decal8_SDF_Softness("SDF softness", Range(0, 1)) = 0.01 + _Decal8_SDF_Px_Range("SDF px range", Float) = 2 + _Decal8_Roughness("Roughness", 2D) = "white" {} + _Decal8_Metallic("Metallic", 2D) = "black" {} + _Decal8_Emission_Strength("Emission strength", Float) = 0 + _Decal8_Angle("Emission strength", Range(0,1)) = 0 + _Decal8_Alpha_Multiplier("Alpha multiplier", Range(0, 1)) = 1 + _Decal8_Round_Alpha_Multiplier("Round alpha multiplier", Float) = 0 + _Decal8_Mask("Mask", 2D) = "white" {} + _Decal8_Mask_Invert("Mask invert", Float) = 0.0 + _Decal8_Tiling_Mode("Tiling mode", Range(0,1)) = 0 + _Decal8_UV_Select("UV channel", Range(0,7)) = 0 + + _Decal9_Enable("Enable decal", Float) = 0.0 + _Decal9_Color("Base color", Color) = (1, 1, 1, 1) + _Decal9_BaseColor("Base color", 2D) = "white" {} + _Decal9_BaseColor_Mode("Base color mode", Float) = 0 + _Decal9_SDF_Threshold("SDF threshold", Range(0, 1)) = 0.5 + _Decal9_SDF_Softness("SDF softness", Range(0, 1)) = 0.01 + _Decal9_SDF_Px_Range("SDF px range", Float) = 2 + _Decal9_Roughness("Roughness", 2D) = "white" {} + _Decal9_Metallic("Metallic", 2D) = "black" {} + _Decal9_Emission_Strength("Emission strength", Float) = 0 + _Decal9_Angle("Emission strength", Range(0,1)) = 0 + _Decal9_Alpha_Multiplier("Alpha multiplier", Range(0, 1)) = 1 + _Decal9_Round_Alpha_Multiplier("Round alpha multiplier", Float) = 0 + _Decal9_Mask("Mask", 2D) = "white" {} + _Decal9_Mask_Invert("Mask invert", Float) = 0.0 + _Decal9_Tiling_Mode("Tiling mode", Range(0,1)) = 0 + _Decal9_UV_Select("UV channel", Range(0,7)) = 0 + [NoScaleOffset] _EmissionMap("Emission map", 2D) = "black" {} _EmissionColor("Emission color", Color) = (0, 0, 0) @@ -670,6 +818,12 @@ Shader "yum_food/tooner" _Decal1_UI_Show("UI show", Float) = 0 _Decal2_UI_Show("UI show", Float) = 0 _Decal3_UI_Show("UI show", Float) = 0 + _Decal4_UI_Show("UI show", Float) = 0 + _Decal5_UI_Show("UI show", Float) = 0 + _Decal6_UI_Show("UI show", Float) = 0 + _Decal7_UI_Show("UI show", Float) = 0 + _Decal8_UI_Show("UI show", Float) = 0 + _Decal9_UI_Show("UI show", Float) = 0 _Lighting_UI_Show("UI show", Float) = 0 _Emission_UI_Show("UI show", Float) = 0 _Shading_UI_Show("UI show", Float) = 0 @@ -804,6 +958,7 @@ Shader "yum_food/tooner" #include "tooner_lighting.cginc" ENDCG } + /* Pass { Tags { "RenderType"="Opaque" @@ -884,6 +1039,7 @@ Shader "yum_food/tooner" #include "mochie_shadow_caster.cginc" ENDCG } + */ } CustomEditor "ToonerGUI" } diff --git a/tooner_lighting.cginc b/tooner_lighting.cginc index 430d8a5..6c46085 100644 --- a/tooner_lighting.cginc +++ b/tooner_lighting.cginc @@ -14,6 +14,7 @@ #include "halos.cginc" #include "interpolators.cginc" #include "iq_sdf.cginc" +#include "macros.cginc" #include "math.cginc" #include "motion.cginc" #include "oklab.cginc" @@ -954,57 +955,136 @@ void getOverlayAlbedoRoughnessMetallic(inout PbrOverlay ov, #endif // _PBR_OVERLAY3 } +struct DecalParams { + float4 color; + texture2D tex; + float4 tex_texelsize; + float4 tex_st; + texture2D roughness_tex; + texture2D metallic_tex; + float emission_strength; + float angle; + bool do_roughness; + bool do_metallic; + float alpha_multiplier; + float round_alpha_multiplier; + float mask; + float uv_select; + float tiling_mode; + float base_color_mode; + float sdf_threshold; + float sdf_softness; + float sdf_px_range; +}; + void applyDecalImpl( inout float4 albedo, inout float3 decal_emission, inout float roughness, inout float metallic, v2f i, - texture2D tex, - float4 tex_st, - texture2D roughness_tex, - texture2D metallic_tex, - float emission_strength, - float angle, - bool do_roughness, - bool do_metallic, - float which_uv) + DecalParams p) { - float2 d0_uv = ((get_uv_by_channel(i, which_uv) - 0.5) - tex_st.zw) * tex_st.xy + 0.5; + float2 d0_uv = + ((get_uv_by_channel(i, p.uv_select) - 0.5) - p.tex_st.zw) * p.tex_st.xy + 0.5; - if (abs(angle) > 1E-6) { - float theta = angle * 2.0 * 3.14159265; + if (abs(p.angle) > 1E-6) { + float theta = p.angle * 2.0 * 3.14159265; float2x2 rot = float2x2( cos(theta), -sin(theta), sin(theta), cos(theta)); d0_uv = mul(rot, d0_uv - 0.5) + 0.5; } + d0_uv = (p.tiling_mode == 0) ? saturate(d0_uv) : d0_uv; + + float4 d0_c = 0; + if (p.base_color_mode == 0) { + d0_c = p.tex.SampleBias( + linear_repeat_s, + d0_uv, _Global_Sample_Bias); + } else if (p.base_color_mode == 1) { + float sd = p.tex.SampleLevel(linear_repeat_s, d0_uv, 0); + + float2 screen_tex_size = 1 / fwidth(d0_uv); + float2 cell_size_texels = p.tex_texelsize.zw; + float2 unit_range = p.sdf_px_range / cell_size_texels; + float screen_px_range = max(0.5 * dot(unit_range, screen_tex_size), p.sdf_px_range); + + float screen_px_distance = screen_px_range * (sd - p.sdf_threshold); + float2 grid_res = p.tex_st.xy; + float smooth_range = (sqrt(2) / sqrt(screen_px_range)) * p.sdf_softness; + float op = smoothstep(-smooth_range, smooth_range, screen_px_distance); + d0_c = saturate(op); + // TODO mip-like filtering? + } - float4 d0_c = tex.SampleBias(linear_clamp_s, saturate(d0_uv), _Global_Sample_Bias); - + d0_c *= p.color; + d0_c.a *= p.round_alpha_multiplier ? round(p.alpha_multiplier) : p.alpha_multiplier; + // Manually apply tiling/clamping correction. float d0_in_range = 1; d0_in_range *= d0_uv.x > 0; d0_in_range *= d0_uv.x < 1; d0_in_range *= d0_uv.y > 0; d0_in_range *= d0_uv.y < 1; + d0_in_range = (p.tiling_mode == 0) ? d0_in_range : 1; d0_c *= d0_in_range; + d0_c *= p.mask; albedo.rgb = lerp(albedo.rgb, d0_c.rgb, d0_c.a); albedo.a = max(albedo.a, d0_c.a); - decal_emission += d0_c.rgb * emission_strength; + decal_emission += d0_c.rgb * p.emission_strength * d0_c.a; - if (do_roughness) { - float4 d0_r = roughness_tex.SampleBias(linear_clamp_s, saturate(d0_uv), _Global_Sample_Bias); + if (p.do_roughness) { + float4 d0_r = p.roughness_tex.SampleBias(linear_clamp_s, saturate(d0_uv), _Global_Sample_Bias); d0_r *= d0_in_range; roughness = lerp(roughness, d0_r, d0_r.a); } - if (do_metallic) { - float4 d0_m = metallic_tex.SampleBias(linear_clamp_s, saturate(d0_uv), _Global_Sample_Bias); + if (p.do_metallic) { + float4 d0_m = p.metallic_tex.SampleBias(linear_clamp_s, saturate(d0_uv), _Global_Sample_Bias); d0_m *= d0_in_range; metallic = lerp(metallic, d0_m, d0_m.a); } } +#define DECAL_PARAMS(n) \ + MERGE(d,n,_params).do_roughness = false; \ + MERGE(d,n,_params).do_metallic = false; \ + MERGE(d,n,_params).mask = 1; \ + MERGE(d,n,_params).color = MERGE(_Decal, n,_Color); \ + MERGE(d,n,_params).tex = MERGE(_Decal, n,_BaseColor); \ + MERGE(d,n,_params).tex_texelsize = MERGE(_Decal, n,_BaseColor_TexelSize); \ + MERGE(d,n,_params).tex_st = MERGE(_Decal, n,_BaseColor_ST); \ + MERGE(d,n,_params).roughness_tex = MERGE(_Decal, n,_Roughness); \ + MERGE(d,n,_params).metallic_tex = MERGE(_Decal, n,_Metallic); \ + MERGE(d,n,_params).emission_strength = MERGE(_Decal, n,_Emission_Strength); \ + MERGE(d,n,_params).angle = MERGE(_Decal, n,_Angle); \ + MERGE(d,n,_params).alpha_multiplier = MERGE(_Decal, n,_Alpha_Multiplier); \ + MERGE(d,n,_params).round_alpha_multiplier = MERGE(_Decal, n,_Round_Alpha_Multiplier); \ + MERGE(d,n,_params).uv_select = MERGE(_Decal, n,_UV_Select); \ + MERGE(d,n,_params).tiling_mode = MERGE(_Decal, n,_Tiling_Mode); \ + MERGE(d,n,_params).base_color_mode = MERGE(_Decal, n,_BaseColor_Mode); \ + MERGE(d,n,_params).sdf_threshold = MERGE(_Decal, n,_SDF_Threshold); \ + MERGE(d,n,_params).sdf_softness = MERGE(_Decal, n,_SDF_Softness); \ + MERGE(d,n,_params).sdf_px_range = MERGE(_Decal, n,_SDF_Px_Range); + +#define SETUP_DECAL_BASE(n) \ + DecalParams MERGE(d,n,_params); \ + DECAL_PARAMS(n) + +#define SETUP_DECAL_ROUGHNESS(n) \ + MERGE(d,n,_params).do_roughness = true; + +#define SETUP_DECAL_METALLIC(n) \ + MERGE(d,n,_params).do_metallic = true; + +#define SETUP_DECAL_MASK(n) \ + MERGE(d,n,_params).mask = MERGE(_Decal, n,_Mask).SampleLevel(linear_repeat_s, \ + get_uv_by_channel(i, MERGE(_Decal, n,_UV_Select)), 0); \ + MERGE(d,n,_params).mask = MERGE(_Decal, n,_Mask_Invert) ? 1.0 - MERGE(d,n,_params).mask : MERGE(d,n,_params).mask; + +#define SETUP_DECAL_FINISH(n) \ + applyDecalImpl(albedo, decal_emission, roughness, metallic, i, MERGE(d,n,_params)); + void applyDecal(inout float4 albedo, inout float roughness, inout float metallic, @@ -1012,93 +1092,144 @@ void applyDecal(inout float4 albedo, v2f i) { #if defined(_DECAL0) -#if defined(_DECAL0_ROUGHNESS) - bool d0_do_roughness = true; -#else - bool d0_do_roughness = false; + SETUP_DECAL_BASE(0) + #if defined(_DECAL0_ROUGHNESS) + SETUP_DECAL_ROUGHNESS(0) + #endif + #if defined(_DECAL0_METALLIC) + SETUP_DECAL_METALLIC(0) + #endif + #if defined(_DECAL0_MASK) + SETUP_DECAL_MASK(0) + #endif + SETUP_DECAL_FINISH(0) #endif -#if defined(_DECAL0_METALLIC) - bool d0_do_metallic = true; -#else - bool d0_do_metallic = false; -#endif - applyDecalImpl(albedo, decal_emission, roughness, metallic, i, - _Decal0_BaseColor, - _Decal0_BaseColor_ST, - _Decal0_Roughness, - _Decal0_Metallic, - _Decal0_Emission_Strength, - _Decal0_Angle, - d0_do_roughness, - d0_do_metallic, - _Decal0_UV_Select); -#endif // _DECAL0 + #if defined(_DECAL1) -#if defined(_DECAL1_ROUGHNESS) - bool d1_do_roughness = true; -#else - bool d1_do_roughness = false; + SETUP_DECAL_BASE(1) + #if defined(_DECAL1_ROUGHNESS) + SETUP_DECAL_ROUGHNESS(1) + #endif + #if defined(_DECAL1_METALLIC) + SETUP_DECAL_METALLIC(1) + #endif + #if defined(_DECAL1_MASK) + SETUP_DECAL_MASK(1) + #endif + SETUP_DECAL_FINISH(1) #endif -#if defined(_DECAL1_METALLIC) - bool d1_do_metallic = true; -#else - bool d1_do_metallic = false; -#endif - applyDecalImpl(albedo, decal_emission, roughness, metallic, i, - _Decal1_BaseColor, - _Decal1_BaseColor_ST, - _Decal1_Roughness, - _Decal1_Metallic, - _Decal1_Emission_Strength, - _Decal1_Angle, - d1_do_roughness, - d1_do_metallic, - _Decal1_UV_Select); -#endif // _DECAL1 + #if defined(_DECAL2) -#if defined(_DECAL2_ROUGHNESS) - bool d2_do_roughness = true; -#else - bool d2_do_roughness = false; + SETUP_DECAL_BASE(2) + #if defined(_DECAL2_ROUGHNESS) + SETUP_DECAL_ROUGHNESS(2) + #endif + #if defined(_DECAL2_METALLIC) + SETUP_DECAL_METALLIC(2) + #endif + #if defined(_DECAL2_MASK) + SETUP_DECAL_MASK(2) + #endif + SETUP_DECAL_FINISH(2) #endif -#if defined(_DECAL2_METALLIC) - bool d2_do_metallic = true; -#else - bool d2_do_metallic = false; -#endif - applyDecalImpl(albedo, decal_emission, roughness, metallic, i, - _Decal2_BaseColor, - _Decal2_BaseColor_ST, - _Decal2_Roughness, - _Decal2_Metallic, - _Decal2_Emission_Strength, - _Decal2_Angle, - d2_do_roughness, - d2_do_metallic, - _Decal2_UV_Select); -#endif // _DECAL2 + #if defined(_DECAL3) -#if defined(_DECAL3_ROUGHNESS) - bool d3_do_roughness = true; -#else - bool d3_do_roughness = false; + SETUP_DECAL_BASE(3) + #if defined(_DECAL3_ROUGHNESS) + SETUP_DECAL_ROUGHNESS(3) + #endif + #if defined(_DECAL3_METALLIC) + SETUP_DECAL_METALLIC(3) + #endif + #if defined(_DECAL3_MASK) + SETUP_DECAL_MASK(3) + #endif + SETUP_DECAL_FINISH(3) +#endif + +#if defined(_DECAL4) + SETUP_DECAL_BASE(4) + #if defined(_DECAL4_ROUGHNESS) + SETUP_DECAL_ROUGHNESS(4) + #endif + #if defined(_DECAL4_METALLIC) + SETUP_DECAL_METALLIC(4) + #endif + #if defined(_DECAL4_MASK) + SETUP_DECAL_MASK(4) + #endif + SETUP_DECAL_FINISH(4) +#endif + +#if defined(_DECAL5) + SETUP_DECAL_BASE(5) + #if defined(_DECAL5_ROUGHNESS) + SETUP_DECAL_ROUGHNESS(5) + #endif + #if defined(_DECAL5_METALLIC) + SETUP_DECAL_METALLIC(5) + #endif + #if defined(_DECAL5_MASK) + SETUP_DECAL_MASK(5) + #endif + SETUP_DECAL_FINISH(5) +#endif + +#if defined(_DECAL6) + SETUP_DECAL_BASE(6) + #if defined(_DECAL6_ROUGHNESS) + SETUP_DECAL_ROUGHNESS(6) + #endif + #if defined(_DECAL6_METALLIC) + SETUP_DECAL_METALLIC(6) + #endif + #if defined(_DECAL6_MASK) + SETUP_DECAL_MASK(6) + #endif + SETUP_DECAL_FINISH(6) +#endif + +#if defined(_DECAL7) + SETUP_DECAL_BASE(7) + #if defined(_DECAL7_ROUGHNESS) + SETUP_DECAL_ROUGHNESS(7) + #endif + #if defined(_DECAL7_METALLIC) + SETUP_DECAL_METALLIC(7) + #endif + #if defined(_DECAL7_MASK) + SETUP_DECAL_MASK(7) + #endif + SETUP_DECAL_FINISH(7) +#endif + +#if defined(_DECAL8) + SETUP_DECAL_BASE(8) + #if defined(_DECAL8_ROUGHNESS) + SETUP_DECAL_ROUGHNESS(8) + #endif + #if defined(_DECAL8_METALLIC) + SETUP_DECAL_METALLIC(8) + #endif + #if defined(_DECAL8_MASK) + SETUP_DECAL_MASK(8) + #endif + SETUP_DECAL_FINISH(8) +#endif + +#if defined(_DECAL9) + SETUP_DECAL_BASE(9) + #if defined(_DECAL9_ROUGHNESS) + SETUP_DECAL_ROUGHNESS(9) + #endif + #if defined(_DECAL9_METALLIC) + SETUP_DECAL_METALLIC(9) + #endif + #if defined(_DECAL9_MASK) + SETUP_DECAL_MASK(9) + #endif + SETUP_DECAL_FINISH(9) #endif -#if defined(_DECAL3_METALLIC) - bool d3_do_metallic = true; -#else - bool d3_do_metallic = false; -#endif - applyDecalImpl(albedo, decal_emission, roughness, metallic, i, - _Decal3_BaseColor, - _Decal3_BaseColor_ST, - _Decal3_Roughness, - _Decal3_Metallic, - _Decal3_Emission_Strength, - _Decal3_Angle, - d3_do_roughness, - d3_do_metallic, - _Decal3_UV_Select); -#endif // _DECAL3 } void mixOverlayAlbedoRoughnessMetallic(inout float4 albedo, @@ -1788,7 +1919,7 @@ float4 effect(inout v2f i, out float depth) mixOverlayAlbedoRoughnessMetallic(albedo, roughness, metallic, ov, 1 - pow((1 - min(matcap_overwrite_mask[0], matcap_overwrite_mask[1])), 8), overlay_glitter_mask); -#if defined(_DECAL0) || defined(_DECAL1) || defined(_DECAL2) || defined(_DECAL3) +#if defined(_DECAL0) || defined(_DECAL1) || defined(_DECAL2) || defined(_DECAL3) || defined(_DECAL4) || defined(_DECAL5) || defined(_DECAL6) || defined(_DECAL7) || defined(_DECAL8) || defined(_DECAL9) float3 decal_emission = 0; applyDecal(albedo, roughness, metallic, decal_emission, i); #endif @@ -2392,20 +2523,13 @@ float4 effect(inout v2f i, out float depth) // This is just the manhattan length of the triangle with edges // ddx(cell_uv.x) and ddy(cell_uv.x). // In other words, an approximation of the gradient of cell_uv.x. - #if 1 + // fwidth is an approximation showing how much cell_uv changes per pixel. // By inverting it, we get an approximation of how many pixels are // spanned by the whole texture, if it was rendered with this pixel's // properties. float2 screen_tex_size = 1 / fwidth(cell_uv); - #else - float2 cell_uv_x = float2(ddx(cell_uv.x), ddy(cell_uv.x)); - float2 cell_uv_y = float2(ddx(cell_uv.y), ddy(cell_uv.y)); - float2 screen_tex_size = float2( - 1 / length(cell_uv_x), - 1 / length(cell_uv_y) - ); - #endif + screen_px_range = max(0.5 * dot(unit_range, screen_tex_size), _Gimmick_Letter_Grid_2_Min_Screen_Px_Range); } float screen_px_distance = screen_px_range * (sd - _Gimmick_Letter_Grid_2_Alpha_Threshold); @@ -2584,7 +2708,7 @@ float4 effect(inout v2f i, out float depth) #if defined(_MATCAP0) || defined(_MATCAP1) || defined(_RIM_LIGHTING0) || defined(_RIM_LIGHTING1) result.rgb += matcap_emission * _Global_Emission_Factor; #endif -#if defined(_DECAL0) || defined(_DECAL1) || defined(_DECAL2) || defined(_DECAL3) +#if defined(_DECAL0) || defined(_DECAL1) || defined(_DECAL2) || defined(_DECAL3) || defined(_DECAL4) || defined(_DECAL5) || defined(_DECAL6) || defined(_DECAL7) || defined(_DECAL8) || defined(_DECAL9) result.rgb += decal_emission * _Global_Emission_Factor; #endif #if defined(_GLITTER) |
