summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Editor/tooner.cs153
-rw-r--r--clones.cginc5
-rw-r--r--globals.cginc31
-rw-r--r--interpolators.cginc8
-rw-r--r--pbr.cginc12
-rw-r--r--tooner.shader55
-rw-r--r--tooner_lighting.cginc233
-rw-r--r--tooner_outline_pass.cginc72
8 files changed, 360 insertions, 209 deletions
diff --git a/Editor/tooner.cs b/Editor/tooner.cs
index 414c1b2..8368b55 100644
--- a/Editor/tooner.cs
+++ b/Editor/tooner.cs
@@ -224,90 +224,92 @@ public class ToonerGUI : ShaderGUI {
}
void DoRimLighting() {
- GUILayout.Label($"Rim lighting", EditorStyles.boldLabel);
- EditorGUI.indentLevel += 1;
+ for (int i = 0; i < 2; i++) {
+ GUILayout.Label($"Rim lighting {i}", EditorStyles.boldLabel);
+ EditorGUI.indentLevel += 1;
- MaterialProperty bc;
+ MaterialProperty bc;
- bc = FindProperty("_Rim_Lighting_Enabled");
- bool enabled = bc.floatValue > 1E-6;
- EditorGUI.BeginChangeCheck();
- enabled = EditorGUILayout.Toggle("Enable", enabled);
- EditorGUI.EndChangeCheck();
- bc.floatValue = enabled ? 1.0f : 0.0f;
- SetKeyword($"_RIM_LIGHTING", enabled);
+ bc = FindProperty($"_Rim_Lighting{i}_Enabled");
+ bool enabled = bc.floatValue > 1E-6;
+ EditorGUI.BeginChangeCheck();
+ enabled = EditorGUILayout.Toggle("Enable", enabled);
+ EditorGUI.EndChangeCheck();
+ bc.floatValue = enabled ? 1.0f : 0.0f;
+ SetKeyword($"_RIM_LIGHTING{i}", enabled);
- if (!enabled) {
- return;
- }
+ if (!enabled) {
+ return;
+ }
+
+ bc = FindProperty($"_Rim_Lighting{i}_Color");
+ editor.ColorProperty(bc, "Color (RGB)");
- bc = FindProperty("_Rim_Lighting_Color");
- editor.ColorProperty(bc, "Color (RGB)");
+ bc = FindProperty($"_Rim_Lighting{i}_Mask");
+ editor.TexturePropertySingleLine(
+ MakeLabel(bc, "Mask"),
+ bc);
+ SetKeyword($"_RIM_LIGHTING{i}_MASK", bc.textureValue);
- bc = FindProperty($"_Rim_Lighting_Mask");
- editor.TexturePropertySingleLine(
- MakeLabel(bc, "Mask"),
- bc);
- SetKeyword($"_RIM_LIGHTING_MASK", bc.textureValue);
+ if (bc.textureValue) {
+ bc = FindProperty($"_Rim_Lighting{i}_Mask_Invert");
+ enabled = bc.floatValue > 1E-6;
+ EditorGUI.BeginChangeCheck();
+ enabled = EditorGUILayout.Toggle("Invert mask", enabled);
+ EditorGUI.EndChangeCheck();
+ bc.floatValue = enabled ? 1.0f : 0.0f;
+ }
- if (bc.textureValue) {
- bc = FindProperty($"_Rim_Lighting_Mask_Invert");
- enabled = bc.floatValue > 1E-6;
EditorGUI.BeginChangeCheck();
- enabled = EditorGUILayout.Toggle("Invert mask", enabled);
- EditorGUI.EndChangeCheck();
- bc.floatValue = enabled ? 1.0f : 0.0f;
- }
-
- EditorGUI.BeginChangeCheck();
- bc = FindProperty($"_Rim_Lighting_Mode");
- MatcapMode mode = (MatcapMode) Math.Round(bc.floatValue);
- mode = (MatcapMode) EditorGUILayout.EnumPopup(
- MakeLabel("Rim lighting mode"), mode);
- if (EditorGUI.EndChangeCheck()) {
- RecordAction("Rim lighting mode");
- foreach (Material m in editor.targets) {
- m.SetFloat($"_Rim_Lighting_Mode", (int) mode);
+ bc = FindProperty($"_Rim_Lighting{i}_Mode");
+ MatcapMode mode = (MatcapMode) Math.Round(bc.floatValue);
+ mode = (MatcapMode) EditorGUILayout.EnumPopup(
+ MakeLabel("Rim lighting mode"), mode);
+ if (EditorGUI.EndChangeCheck()) {
+ RecordAction("Rim lighting mode");
+ foreach (Material m in editor.targets) {
+ m.SetFloat($"_Rim_Lighting{i}_Mode", (int) mode);
+ }
}
- }
- bc = FindProperty($"_Rim_Lighting_Center");
- editor.FloatProperty(
- bc,
- "Center");
+ bc = FindProperty($"_Rim_Lighting{i}_Center");
+ editor.FloatProperty(
+ bc,
+ "Center");
- bc = FindProperty($"_Rim_Lighting_Power");
- editor.FloatProperty(
- bc,
- "Power");
+ bc = FindProperty($"_Rim_Lighting{i}_Power");
+ editor.FloatProperty(
+ bc,
+ "Power");
- bc = FindProperty($"_Rim_Lighting_Strength");
- editor.FloatProperty(
- bc,
- "Strength");
+ bc = FindProperty($"_Rim_Lighting{i}_Strength");
+ editor.FloatProperty(
+ bc,
+ "Strength");
- EditorGUI.indentLevel -= 1;
+ EditorGUI.indentLevel -= 1;
+ }
}
+ enum NormalsMode {
+ Flat,
+ Spherical
+ };
+
void DoShadingMode() {
MaterialProperty bc;
- /*
- bc = FindProperty("_Shading_Mode");
- editor.RangeProperty(
- bc,
- "Shading mode (0=realistic,1=flat)");
- SetKeyword("_SHADING_MODE_FLAT", ((int) Math.Round(bc.floatValue, 0)) == 1);
- */
-
- bc = FindProperty("_Flatten_Mesh_Normals");
- bool enabled = bc.floatValue > 1E-6;
+ bc = FindProperty($"_Mesh_Normals_Mode");
EditorGUI.BeginChangeCheck();
- enabled = EditorGUILayout.Toggle("Flatten normals", enabled);
- EditorGUI.EndChangeCheck();
- bc.floatValue = enabled ? 1.0f : 0.0f;
+ NormalsMode mode = (NormalsMode) Math.Round(bc.floatValue, 0);
+ mode = (NormalsMode) EditorGUILayout.EnumPopup(
+ MakeLabel("Normals mode"), mode);
+ if (EditorGUI.EndChangeCheck()) {
+ RecordAction("Rendering Mode");
+ }
+ bc.floatValue = (float) mode;
- if (enabled) {
+ if (mode == NormalsMode.Flat) {
bc = FindProperty("_Flatten_Mesh_Normals_Str");
editor.FloatProperty(
bc,
@@ -315,7 +317,7 @@ public class ToonerGUI : ShaderGUI {
}
bc = FindProperty("_Confabulate_Normals");
- enabled = bc.floatValue > 1E-6;
+ bool enabled = bc.floatValue > 1E-6;
EditorGUI.BeginChangeCheck();
enabled = EditorGUILayout.Toggle("Confabulate normals", enabled);
EditorGUI.EndChangeCheck();
@@ -570,21 +572,26 @@ public class ToonerGUI : ShaderGUI {
}
}
- void DoChainTessellation() {
- MaterialProperty bc = FindProperty("_Enable_Chain_Tessellation");
+ void DoTessellation() {
+ MaterialProperty bc = FindProperty("_Enable_Tessellation");
bool enabled = bc.floatValue > 1E-6;
EditorGUI.BeginChangeCheck();
enabled = EditorGUILayout.Toggle("Enable", enabled);
EditorGUI.EndChangeCheck();
- SetKeyword("_CHAIN_TESSELLATION", enabled);
+ SetKeyword("_TESSELLATION", enabled);
bc.floatValue = enabled ? 1.0f : 0.0f;
if (enabled) {
- bc = FindProperty("_Chain_Tess_Factor");
+ bc = FindProperty("_Tess_Factor");
editor.RangeProperty(
bc,
"Tessellation factor");
+
+ bc = FindProperty("_Tess_Dist_Cutoff");
+ editor.FloatProperty(
+ bc,
+ "Activation distance (negative=always on)");
}
}
@@ -745,12 +752,10 @@ public class ToonerGUI : ShaderGUI {
DoUVScroll();
EditorGUI.indentLevel -= 1;
- /*
- GUILayout.Label("Chain tessellation", EditorStyles.boldLabel);
+ GUILayout.Label("Tessellation", EditorStyles.boldLabel);
EditorGUI.indentLevel += 1;
- DoChainTessellation();
+ DoTessellation();
EditorGUI.indentLevel -= 1;
- */
GUILayout.Label("Hue shift", EditorStyles.boldLabel);
EditorGUI.indentLevel += 1;
diff --git a/clones.cginc b/clones.cginc
index 6369fee..fe51f18 100644
--- a/clones.cginc
+++ b/clones.cginc
@@ -12,6 +12,11 @@ void add_clones(in v2f clone_verts[3], inout TriangleStream<v2f> tri_out)
return;
}
+ float factor = _Tess_Factor;
+ if (_Clones_Dist_Cutoff > 0 && length(_WorldSpaceCameraPos - clone_verts[0].worldPos) > _Clones_Dist_Cutoff) {
+ factor = 1;
+ }
+
uint n_clones = (uint) round(_Clones_Count);
for (uint i = 0; i < (uint) n_clones; i++) {
for (uint j = 0; j < 3; j++) {
diff --git a/globals.cginc b/globals.cginc
index aa23216..2ed4be1 100644
--- a/globals.cginc
+++ b/globals.cginc
@@ -34,7 +34,7 @@ float _Max_Brightness;
float _Alpha_Cutoff;
-float _Flatten_Mesh_Normals;
+float _Mesh_Normals_Mode;
float _Flatten_Mesh_Normals_Str;
float _Confabulate_Normals;
@@ -61,7 +61,8 @@ float _Scroll_Width;
float _Scroll_Strength;
float _Scroll_Speed;
-float _Chain_Tess_Factor;
+float _Tess_Factor;
+float _Tess_Dist_Cutoff;
float _Enable_Matcap0;
texture2D _Matcap0;
@@ -77,14 +78,23 @@ float _Matcap1_Mask_Invert;
float _Matcap1Str;
float _Matcap1Mode;
-float _Rim_Lighting_Enabled;
-float _Rim_Lighting_Mode;
-float3 _Rim_Lighting_Color;
-texture2D _Rim_Lighting_Mask;
-float _Rim_Lighting_Mask_Invert;
-float _Rim_Lighting_Center;
-float _Rim_Lighting_Power;
-float _Rim_Lighting_Strength;
+float _Rim_Lighting0_Enabled;
+float _Rim_Lighting0_Mode;
+float3 _Rim_Lighting0_Color;
+texture2D _Rim_Lighting0_Mask;
+float _Rim_Lighting0_Mask_Invert;
+float _Rim_Lighting0_Center;
+float _Rim_Lighting0_Power;
+float _Rim_Lighting0_Strength;
+
+float _Rim_Lighting1_Enabled;
+float _Rim_Lighting1_Mode;
+float3 _Rim_Lighting1_Color;
+texture2D _Rim_Lighting1_Mask;
+float _Rim_Lighting1_Mask_Invert;
+float _Rim_Lighting1_Center;
+float _Rim_Lighting1_Power;
+float _Rim_Lighting1_Strength;
float _OKLAB_Enabled;
texture2D _OKLAB_Mask;
@@ -95,6 +105,7 @@ float _OKLAB_Hue_Shift;
float _Clones_Enabled;
float _Clones_Count;
float _Clones_dx;
+float _Clones_Dist_Cutoff;
float _UVScroll_Enabled;
texture2D _UVScroll_Mask;
diff --git a/interpolators.cginc b/interpolators.cginc
index 186a851..9e967c3 100644
--- a/interpolators.cginc
+++ b/interpolators.cginc
@@ -17,9 +17,12 @@ struct v2f
{
float4 clipPos : POSITION;
float2 uv : TEXCOORD0;
+ #if defined(LIGHTMAP_ON)
float2 lmuv : TEXCOORD1;
+ #endif
float3 worldPos : TEXCOORD2;
float3 normal : TEXCOORD3;
+ float3 objPos : TEXCOORD4;
};
#else
@@ -37,13 +40,16 @@ struct v2f
{
float4 clipPos : SV_POSITION;
float2 uv : TEXCOORD0;
+ #if defined(LIGHTMAP_ON)
float2 lmuv : TEXCOORD1;
+ #endif
float3 normal : TEXCOORD2;
float4 tangent : TEXCOORD3;
float3 worldPos : TEXCOORD4;
+ float3 objPos : TEXCOORD5;
#if defined(VERTEXLIGHT_ON)
- float3 vertexLightColor : TEXCOORD5;
+ float3 vertexLightColor : TEXCOORD6;
#endif
};
#endif
diff --git a/pbr.cginc b/pbr.cginc
index 1ceef09..e171f89 100644
--- a/pbr.cginc
+++ b/pbr.cginc
@@ -126,13 +126,16 @@ float4 getLitColor(
float3 view_dir = normalize(_WorldSpaceCameraPos - worldPos);
- bool flat = round(_Flatten_Mesh_Normals) == 1.0;
+ uint normals_mode = round(_Mesh_Normals_Mode);
+ bool flat = (normals_mode == 0);
float3 flat_normal = normalize(
(1.0 / _Flatten_Mesh_Normals_Str) * normal +
_Flatten_Mesh_Normals_Str * view_dir);
+ float3 spherical_normal = normalize(UnityObjectToWorldNormal(normalize(i.objPos)));
+ normal = lerp(spherical_normal, flat_normal, flat);
UnityIndirect indirect_light = CreateIndirectLight(vertexLightColor,
- view_dir, flat ? flat_normal : normal, smoothness, worldPos, uv);
+ view_dir, normal, smoothness, worldPos, uv);
UnityLight direct_light = CreateDirectLight(normal, i);
if (flat) {
@@ -141,6 +144,7 @@ float4 getLitColor(
direct_light.color *= (1 - e);
}
+ direct_light.color = clamp(direct_light.color, _Min_Brightness, _Max_Brightness*.5);
indirect_light.diffuse = clamp(indirect_light.diffuse, _Min_Brightness, _Max_Brightness);
indirect_light.specular = clamp(indirect_light.specular, _Min_Brightness, _Max_Brightness);
@@ -152,7 +156,7 @@ float4 getLitColor(
one_minus_reflectivity,
smoothness,
view_dir,
- flat ? flat_normal : normal,
+ normal,
direct_light,
indirect_light).xyz;
} else {
@@ -161,7 +165,7 @@ float4 getLitColor(
specular_tint,
one_minus_reflectivity,
smoothness,
- flat ? flat_normal : normal,
+ normal,
view_dir,
direct_light,
indirect_light).xyz;
diff --git a/tooner.shader b/tooner.shader
index d04a45b..c9f88ac 100644
--- a/tooner.shader
+++ b/tooner.shader
@@ -33,7 +33,7 @@ Shader "yum_food/tooner"
_NormalStr("Normal strength", Range(0, 10)) = 1
_Shading_Mode("Shading mode", Range(0, 1)) = 0
- [MaterialToggle] _Flatten_Mesh_Normals("Flatten mesh normals", Float) = 0.0
+ _Mesh_Normals_Mode("Normals mode", Float) = 0.0
_Flatten_Mesh_Normals_Str("Flatten mesh normals strength", Float) = 100.0
[MaterialToggle] _Confabulate_Normals("Confabulate mesh normals", Float) = 0.0
@@ -82,14 +82,23 @@ Shader "yum_food/tooner"
_Matcap1Mode("Matcap mode", Float) = 0
_Matcap1Str("Matcap strength", Float) = 1
- _Rim_Lighting_Enabled("Enable rim lighting", Float) = 0
- _Rim_Lighting_Mode("Rim lighting mode", Float) = 0
- _Rim_Lighting_Mask("Rim lighting mask", 2D) = "white" {}
- _Rim_Lighting_Mask_Invert("Invert rim lighting mask", Float) = 0.0
- _Rim_Lighting_Color("Rim lighting color", Color) = (1, 1, 1, 1)
- _Rim_Lighting_Center("Rim lighting center", Float) = 0.5
- _Rim_Lighting_Power("Rim lighting power", Float) = 2.0
- _Rim_Lighting_Strength("Rim lighting power", Float) = 1.0
+ _Rim_Lighting0_Enabled("Enable rim lighting", Float) = 0
+ _Rim_Lighting0_Mode("Rim lighting mode", Float) = 0
+ _Rim_Lighting0_Mask("Rim lighting mask", 2D) = "white" {}
+ _Rim_Lighting0_Mask_Invert("Invert rim lighting mask", Float) = 0.0
+ _Rim_Lighting0_Color("Rim lighting color", Color) = (1, 1, 1, 1)
+ _Rim_Lighting0_Center("Rim lighting center", Float) = 0.5
+ _Rim_Lighting0_Power("Rim lighting power", Float) = 2.0
+ _Rim_Lighting0_Strength("Rim lighting power", Float) = 1.0
+
+ _Rim_Lighting1_Enabled("Enable rim lighting", Float) = 0
+ _Rim_Lighting1_Mode("Rim lighting mode", Float) = 0
+ _Rim_Lighting1_Mask("Rim lighting mask", 2D) = "white" {}
+ _Rim_Lighting1_Mask_Invert("Invert rim lighting mask", Float) = 0.0
+ _Rim_Lighting1_Color("Rim lighting color", Color) = (1, 1, 1, 1)
+ _Rim_Lighting1_Center("Rim lighting center", Float) = 0.5
+ _Rim_Lighting1_Power("Rim lighting power", Float) = 2.0
+ _Rim_Lighting1_Strength("Rim lighting power", Float) = 1.0
_OKLAB_Enabled("Enable OKLAB", Float) = 0.0
_OKLAB_Mask("Mask", 2D) = "white" {}
@@ -98,7 +107,8 @@ Shader "yum_food/tooner"
_OKLAB_Hue_Shift("OKLAB hue shift", Range(0, 6.283185307)) = 0.0
_Clones_Enabled("Enable clones", Float) = 0.0
- _Clones_Count("Clones count", Range(0,4)) = 0.0
+ _Clones_Count("Clones count", Range(0,16)) = 0.0
+ _Clones_Dist_Cutoff("Clones distance cutoff", Float) = -1.0
_Clones_dx("Clones dx", Range(0, 1)) = 1.0
_UVScroll_Enabled("Enable UV scrolling", Float) = 0.0
@@ -110,6 +120,10 @@ Shader "yum_food/tooner"
_LTCGI_Enabled("LTCGI enabled", Float) = 0.0
_LTCGI_SpecularColor("LTCGI specular color", Color) = (1, 1, 1, 1)
_LTCGI_DiffuseColor("LTCGI diffuse color", Color) = (1, 1, 1, 1)
+
+ _Enable_Tessellation("Enable tessellation", Float) = 0.0
+ _Tess_Factor("Tessellation factor", Range(1, 64)) = 1.0
+ _Tess_Dist_Cutoff("Tessellation distance cutoff", Float) = -1.0
}
SubShader
{
@@ -153,8 +167,10 @@ Shader "yum_food/tooner"
#pragma shader_feature_local _ _MATCAP0_MASK
#pragma shader_feature_local _ _MATCAP1
#pragma shader_feature_local _ _MATCAP1_MASK
- #pragma shader_feature_local _ _RIM_LIGHTING
- #pragma shader_feature_local _ _RIM_LIGHTING_MASK
+ #pragma shader_feature_local _ _RIM_LIGHTING0
+ #pragma shader_feature_local _ _RIM_LIGHTING0_MASK
+ #pragma shader_feature_local _ _RIM_LIGHTING1
+ #pragma shader_feature_local _ _RIM_LIGHTING1_MASK
#pragma shader_feature_local _ _OKLAB
#pragma shader_feature_local _ _CLONES
#pragma shader_feature_local _ _PBR_OVERLAY
@@ -163,6 +179,7 @@ Shader "yum_food/tooner"
#pragma shader_feature_local _ _PBR_OVERLAY_ROUGHNESS_MAP
#pragma shader_feature_local _ _PBR_OVERLAY_METALLIC_MAP
#pragma shader_feature_local _ _LTCGI
+ #pragma shader_feature_local _ _TESSELLATION
#pragma vertex vert
//#pragma vertex hull_vertex
@@ -211,8 +228,10 @@ Shader "yum_food/tooner"
#pragma shader_feature_local _ _MATCAP0_MASK
#pragma shader_feature_local _MATCAP1
#pragma shader_feature_local _ _MATCAP1_MASK
- #pragma shader_feature_local _ _RIM_LIGHTING
- #pragma shader_feature_local _ _RIM_LIGHTING_MASK
+ #pragma shader_feature_local _ _RIM_LIGHTING0
+ #pragma shader_feature_local _ _RIM_LIGHTING0_MASK
+ #pragma shader_feature_local _ _RIM_LIGHTING1
+ #pragma shader_feature_local _ _RIM_LIGHTING1_MASK
#pragma shader_feature_local _ _OKLAB
#pragma shader_feature_local _ _CLONES
#pragma shader_feature_local _ _PBR_OVERLAY
@@ -221,6 +240,7 @@ Shader "yum_food/tooner"
#pragma shader_feature_local _ _PBR_OVERLAY_ROUGHNESS_MAP
#pragma shader_feature_local _ _PBR_OVERLAY_METALLIC_MAP
#pragma shader_feature_local _ _LTCGI
+ #pragma shader_feature_local _ _TESSELLATION
#pragma vertex vert
//#pragma vertex hull_vertex
@@ -251,8 +271,10 @@ Shader "yum_food/tooner"
#pragma shader_feature_local _ _MATCAP0_MASK
#pragma shader_feature_local _MATCAP1
#pragma shader_feature_local _ _MATCAP1_MASK
- #pragma shader_feature_local _ _RIM_LIGHTING
- #pragma shader_feature_local _ _RIM_LIGHTING_MASK
+ #pragma shader_feature_local _ _RIM_LIGHTING0
+ #pragma shader_feature_local _ _RIM_LIGHTING0_MASK
+ #pragma shader_feature_local _ _RIM_LIGHTING1
+ #pragma shader_feature_local _ _RIM_LIGHTING1_MASK
#pragma shader_feature_local _ _OKLAB
#pragma shader_feature_local _ _CLONES
#pragma shader_feature_local _ _PBR_OVERLAY
@@ -261,6 +283,7 @@ Shader "yum_food/tooner"
#pragma shader_feature_local _ _PBR_OVERLAY_ROUGHNESS_MAP
#pragma shader_feature_local _ _PBR_OVERLAY_METALLIC_MAP
#pragma shader_feature_local _ _LTCGI
+ #pragma shader_feature_local _ _TESSELLATION
#pragma vertex vert
//#pragma vertex hull_vertex
diff --git a/tooner_lighting.cginc b/tooner_lighting.cginc
index cdc10b0..45a69e8 100644
--- a/tooner_lighting.cginc
+++ b/tooner_lighting.cginc
@@ -42,7 +42,9 @@ struct tess_data
{
float4 position : INTERNALTESSPOS;
float2 uv : TEXCOORD0;
+ #if defined(LIGHTMAP_ON)
float2 lmuv : TEXCOORD1;
+ #endif
float3 normal : TEXCOORD2;
float4 tangent : TEXCOORD3;
@@ -52,15 +54,16 @@ struct tess_data
};
struct tess_factors {
- float edge[4] : SV_TessFactor;
- float inside[2] : SV_InsideTessFactor;
+ float edge[3] : SV_TessFactor;
+ float inside : SV_InsideTessFactor;
};
void getVertexLightColor(inout v2f i)
{
#if defined(VERTEXLIGHT_ON)
float3 view_dir = normalize(_WorldSpaceCameraPos - i.worldPos);
- bool flat = round(_Flatten_Mesh_Normals) == 1.0;
+ uint normals_mode = round(_Mesh_Normals_Mode);
+ bool flat = (normals_mode == 0);
float3 flat_normal = normalize(
(1.0 / _Flatten_Mesh_Normals_Str) * i.normal +
_Flatten_Mesh_Normals_Str * view_dir);
@@ -86,12 +89,13 @@ v2f vert(appdata v)
o.clipPos = UnityObjectToClipPos(v.position);
o.worldPos = mul(unity_ObjectToWorld, v.position);
+ o.objPos = v.position;
o.normal = UnityObjectToWorldNormal(v.normal);
o.tangent = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);
o.uv = v.uv0.xy;
#if defined(LIGHTMAP_ON)
- o.lmuv = v.uv1 * unity_LightmapST.xy + unity_LightmapST.zw
+ o.lmuv = v.uv1 * unity_LightmapST.xy + unity_LightmapST.zw;
#endif
getVertexLightColor(o);
@@ -102,13 +106,20 @@ v2f vert(appdata v)
void getVertexLightColorTess(inout tess_data i)
{
#if defined(VERTEXLIGHT_ON)
+ float3 worldPos = mul(unity_ObjectToWorld, i.position).xyz;
+ float3 view_dir = normalize(_WorldSpaceCameraPos - worldPos);
+ uint normals_mode = round(_Mesh_Normals_Mode);
+ bool flat = (normals_mode == 0);
+ float3 flat_normal = normalize(
+ (1.0 / _Flatten_Mesh_Normals_Str) * i.normal +
+ _Flatten_Mesh_Normals_Str * view_dir);
i.vertexLightColor = Shade4PointLights(
unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
unity_LightColor[0].rgb,
unity_LightColor[1].rgb,
unity_LightColor[2].rgb,
unity_LightColor[3].rgb,
- unity_4LightAtten0, worldPos, i.normal
+ unity_4LightAtten0, worldPos, flat ? flat_normal : i.normal
);
#endif
}
@@ -117,13 +128,21 @@ tess_data hull_vertex(appdata v)
{
tess_data o;
+ UNITY_INITIALIZE_OUTPUT(tess_data, o);
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_TRANSFER_INSTANCE_ID(v, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+
o.position = v.position;
+ //o.position = UnityObjectToClipPos(v.position);
+ //o.worldPos = mul(unity_ObjectToWorld, v.position);
+ //o.objPos = v.position;
o.normal = UnityObjectToWorldNormal(v.normal);
o.tangent = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);
o.uv = v.uv0.xy;
#if defined(LIGHTMAP_ON)
- o.lmuv = v.uv1 * unity_LightmapST.xy + unity_LightmapST.zw
+ o.lmuv = v.uv1 * unity_LightmapST.xy + unity_LightmapST.zw;
#endif
getVertexLightColorTess(o);
@@ -131,45 +150,50 @@ tess_data hull_vertex(appdata v)
return o;
}
-tess_factors patch_constant(InputPatch<tess_data, 4> patch)
+tess_factors patch_constant(InputPatch<tess_data, 3> patch)
{
tess_factors f;
- float factor = _Chain_Tess_Factor;
- factor = 1;
+
+ float3 worldPos = mul(unity_ObjectToWorld, patch[0].position);
+ float factor = _Tess_Factor;
+ if (_Tess_Dist_Cutoff > 0 && length(_WorldSpaceCameraPos - worldPos) > _Tess_Dist_Cutoff) {
+ factor = 1;
+ }
+
f.edge[0] = factor;
f.edge[1] = factor;
f.edge[2] = factor;
- f.edge[3] = factor;
- f.inside[0] = factor;
- f.inside[1] = factor;
+ f.inside = factor;
return f;
}
-[UNITY_domain("quad")]
-[UNITY_outputcontrolpoints(4)]
+[UNITY_domain("tri")]
+[UNITY_outputcontrolpoints(3)]
[UNITY_outputtopology("triangle_cw")]
[UNITY_partitioning("fractional_odd")]
[UNITY_patchconstantfunc("patch_constant")]
tess_data hull(
- InputPatch<tess_data, 4> patch,
+ InputPatch<tess_data, 3> patch,
uint id : SV_OutputControlPointID)
{
return patch[id];
}
-[UNITY_domain("quad")]
+[UNITY_domain("tri")]
v2f domain(
tess_factors factors,
- OutputPatch<tess_data, 4> patch,
- float2 uv : SV_DomainLocation)
+ OutputPatch<tess_data, 3> patch,
+ float3 baryc : SV_DomainLocation)
{
v2f data;
#define DOMAIN_INTERP(fieldName) data.fieldName = \
- lerp(\
- lerp(patch[0].fieldName, patch[1].fieldName, uv.x), \
- lerp(patch[2].fieldName, patch[3].fieldName, uv.x), \
- uv.y)
+ patch[0].fieldName * baryc.x + \
+ patch[1].fieldName * baryc.y + \
+ patch[2].fieldName * baryc.z;
DOMAIN_INTERP(uv);
+ #if defined(LIGHTMAP_ON)
+ DOMAIN_INTERP(lmuv);
+ #endif
DOMAIN_INTERP(normal);
DOMAIN_INTERP(tangent);
@@ -177,11 +201,12 @@ v2f domain(
DOMAIN_INTERP(vertexLightColor);
#endif
- float4 pos = lerp(
- lerp(patch[0].position, patch[1].position, uv.x),
- lerp(patch[2].position, patch[3].position, uv.x),
- uv.y);
+ float4 pos =
+ patch[0].position * baryc.x +
+ patch[1].position * baryc.y +
+ patch[2].position * baryc.z;
data.clipPos = UnityObjectToClipPos(pos);
+ data.objPos = pos;
data.worldPos = mul(unity_ObjectToWorld, pos);
return data;
@@ -189,7 +214,7 @@ v2f domain(
// maxvertexcount == the number of vertices we create
#if defined(_CLONES)
-[maxvertexcount(15)]
+[maxvertexcount(45)]
#else
[maxvertexcount(3)]
#endif
@@ -264,12 +289,6 @@ void geom(triangle v2f tri_in[3],
v1.normal = n;
v2.normal = n;
- n = normalize(cross(v1.worldPos - v0.worldPos, v2.worldPos - v0.worldPos));
- avg_pos = (v0.worldPos + v1.worldPos + v2.worldPos) / 3;
- v0.worldPos = applyScroll(v0.worldPos, n, avg_pos);
- v1.worldPos = applyScroll(v1.worldPos, n, avg_pos);
- v2.worldPos = applyScroll(v2.worldPos, n, avg_pos);
-
// Omit geometry that's too close when exploded.
/*
if (_Explode_Phase > .05 && length(v0.worldPos - _WorldSpaceCameraPos) < .2) {
@@ -289,6 +308,23 @@ void geom(triangle v2f tri_in[3],
}
}
#endif // __EXPLODE
+#if defined(_SCROLL)
+ {
+ float3 n = normalize(cross(v1.worldPos - v0.worldPos, v2.worldPos - v0.worldPos));
+ float3 avg_pos = (v0.worldPos + v1.worldPos + v2.worldPos) / 3;
+ v0.worldPos = applyScroll(v0.worldPos, n, avg_pos);
+ v1.worldPos = applyScroll(v1.worldPos, n, avg_pos);
+ v2.worldPos = applyScroll(v2.worldPos, n, avg_pos);
+
+ float3 v0_objPos = mul(unity_WorldToObject, float4(v0.worldPos, 1));
+ float3 v1_objPos = mul(unity_WorldToObject, float4(v1.worldPos, 1));
+ float3 v2_objPos = mul(unity_WorldToObject, float4(v2.worldPos, 1));
+
+ v0.clipPos = UnityObjectToClipPos(v0_objPos);
+ v1.clipPos = UnityObjectToClipPos(v1_objPos);
+ v2.clipPos = UnityObjectToClipPos(v2_objPos);
+ }
+#endif
#if defined(_CLONES)
v2f clone_verts[3] = {v0, v1, v2};
add_clones(clone_verts, tri_out);
@@ -375,6 +411,15 @@ float4 effect(inout v2f i)
albedo.a = 1;
#endif
+#if defined(_PBR_OVERLAY)
+#if defined(_PBR_OVERLAY_BASECOLOR_MAP)
+ float4 ov_albedo = _PBR_Overlay_BaseColorTex.SampleGrad(linear_repeat_s, i.uv, iddx, iddy);
+ ov_albedo *= _PBR_Overlay_BaseColor;
+#else
+ float4 ov_albedo = _BaseColor;
+#endif // _PBR_OVERLAY_BASECOLOR_MAP
+#endif // _PBR_OVERLAY
+
#if defined(_NORMAL_MAP)
// Use UVs to smoothly blend between fully detailed normals when close up and
// flat normals when far away. If we don't do this, then we see moire effects
@@ -386,19 +431,19 @@ float4 effect(inout v2f i)
(1/fw) * raw_normal,
fw * float3(0, 0, 1));
-#if defined(_PBR_OVERLAY_NORMAL_MAP)
+#if defined(_PBR_OVERLAY) && defined(_PBR_OVERLAY_NORMAL_MAP)
{
// Use UVs to smoothly blend between fully detailed normals when close up and
// flat normals when far away. If we don't do this, then we see moire effects
// on e.g. striped normal maps.
//float3 raw_normal = UnpackScaleNormal(_PBR_Overlay_NormalTex.SampleGrad(linear_repeat_s, i.uv, iddx/2, iddy/2), _PBR_Overlay_Tex_NormalStr);
- float3 raw_normal_2 = UnpackScaleNormal(_PBR_Overlay_NormalTex.SampleGrad(linear_repeat_s, i.uv, iddx/2, iddy/2), _PBR_Overlay_Tex_NormalStr);
+ float3 raw_normal_2 = UnpackScaleNormal(_PBR_Overlay_NormalTex.SampleGrad(linear_repeat_s, i.uv, iddx/2, iddy/2), _PBR_Overlay_Tex_NormalStr * ov_albedo.a);
raw_normal = BlendNormals(
raw_normal,
raw_normal_2);
}
-#endif // _PBR_OVERLAY_NORMAL_MAP
+#endif // _PBR_OVERLAY && _PBR_OVERLAY_NORMAL_MAP
float3 binormal = CreateBinormal(i.normal, i.tangent.xyz, i.tangent.w);
float3 normal = normalize(
@@ -427,14 +472,7 @@ float4 effect(inout v2f i)
#endif
#if defined(_PBR_OVERLAY)
-#if defined(_PBR_OVERLAY_BASECOLOR_MAP)
- float4 ov_albedo = _PBR_Overlay_BaseColorTex.SampleGrad(linear_repeat_s, i.uv, iddx, iddy);
- ov_albedo *= _PBR_Overlay_BaseColor;
-#else
- float4 ov_albedo = _BaseColor;
-#endif // _PBR_OVERLAY_BASECOLOR_MAP
albedo.rgb = lerp(albedo.rgb, ov_albedo.rgb, ov_albedo.a);
-
#endif // _PBR_OVERLAY
#if defined(_MATCAP0) || defined(_MATCAP1)
@@ -455,8 +493,8 @@ float4 effect(inout v2f i)
#if defined(_MATCAP0_MASK)
float4 matcap_mask_raw = _Matcap0_Mask.SampleGrad(linear_repeat_s, i.uv.xy, iddx, iddy);
- matcap_mask_raw.rgb = (bool) round(_Matcap0_Mask_Invert) ? 1 - matcap_mask_raw.rgb : matcap_mask_raw.rgb;
float matcap_mask = matcap_mask_raw.r * matcap_mask_raw.a;
+ matcap_mask = (bool) round(_Matcap0_Mask_Invert) ? 1 - matcap_mask : matcap_mask;
#else
float matcap_mask = 1;
#endif
@@ -492,8 +530,8 @@ float4 effect(inout v2f i)
#if defined(_MATCAP1_MASK)
float4 matcap_mask_raw = _Matcap1_Mask.SampleGrad(linear_repeat_s, i.uv.xy, iddx, iddy);
- matcap_mask_raw.rgb = (bool) round(_Matcap1_Mask_Invert) ? 1 - matcap_mask_raw.rgb : matcap_mask_raw.rgb;
float matcap_mask = matcap_mask_raw.r * matcap_mask_raw.a;
+ matcap_mask = (bool) round(_Matcap1_Mask_Invert) ? 1 - matcap_mask : matcap_mask;
#else
float matcap_mask = 1;
#endif
@@ -525,49 +563,88 @@ float4 effect(inout v2f i)
}
}
#endif // _MATCAP0 || _MATCAP1
+#if defined(_RIM_LIGHTING0) || defined(_RIM_LIGHTING1)
{
-#if defined(_RIM_LIGHTING)
// identity: (a, b, c) and (c, c, -(a +b)) are perpendicular to each other
float theta = atan2(length(cross(view_dir, normal)), dot(view_dir, normal));
#define PI 3.14159265
- float rl = abs(theta) / PI; // on [0, 1]
- rl = pow(2, -_Rim_Lighting_Power * abs(rl - _Rim_Lighting_Center));
-
- float3 matcap = rl * _Rim_Lighting_Color * _Rim_Lighting_Strength;
-#if defined(_RIM_LIGHTING_MASK)
- float4 matcap_mask_raw = _Rim_Lighting_Mask.SampleGrad(linear_repeat_s, i.uv.xy, iddx, iddy);
- matcap_mask_raw.rgb = (bool) round(_Rim_Lighting_Mask_Invert) ? 1 - matcap_mask_raw.rgb : matcap_mask_raw.rgb;
- float matcap_mask = matcap_mask_raw.r * matcap_mask_raw.a;
+#if defined(_RIM_LIGHTING0)
+ {
+ float rl = abs(theta) / PI; // on [0, 1]
+ rl = pow(2, -_Rim_Lighting0_Power * abs(rl - _Rim_Lighting0_Center));
+ float3 matcap = rl * _Rim_Lighting0_Color * _Rim_Lighting0_Strength;
+#if defined(_RIM_LIGHTING0_MASK)
+ float4 matcap_mask_raw = _Rim_Lighting0_Mask.SampleGrad(linear_repeat_s, i.uv.xy, iddx, iddy);
+ float matcap_mask = matcap_mask_raw.r * matcap_mask_raw.a;
+ matcap_mask = (bool) round(_Rim_Lighting0_Mask_Invert) ? 1 - matcap_mask : matcap_mask;
#else
- float matcap_mask = 1;
+ float matcap_mask = 1;
#endif
-
- int mode = round(_Rim_Lighting_Mode);
- switch (mode) {
- case 0:
- albedo.rgb += lerp(0, matcap, matcap_mask);
- break;
- case 1:
- albedo.rgb *= lerp(1, matcap, matcap_mask);
- break;
- case 2:
- albedo.rgb = lerp(albedo.rgb, matcap, matcap_mask);;
- break;
- case 3:
- albedo.rgb -= lerp(0, matcap, matcap_mask);
- break;
- case 4:
- albedo.rgb = lerp(albedo.rgb, min(albedo.rgb, matcap), matcap_mask);
- break;
- case 5:
- albedo.rgb = lerp(albedo.rgb, max(albedo.rgb, matcap), matcap_mask);
- break;
- default:
- break;
+ int mode = round(_Rim_Lighting0_Mode);
+ switch (mode) {
+ case 0:
+ albedo.rgb += lerp(0, matcap, matcap_mask);
+ break;
+ case 1:
+ albedo.rgb *= lerp(1, matcap, matcap_mask);
+ break;
+ case 2:
+ albedo.rgb = lerp(albedo.rgb, matcap, matcap_mask);;
+ break;
+ case 3:
+ albedo.rgb -= lerp(0, matcap, matcap_mask);
+ break;
+ case 4:
+ albedo.rgb = lerp(albedo.rgb, min(albedo.rgb, matcap), matcap_mask);
+ break;
+ case 5:
+ albedo.rgb = lerp(albedo.rgb, max(albedo.rgb, matcap), matcap_mask);
+ break;
+ default:
+ break;
+ }
}
+#endif // _RIM_LIGHTING0
+#if defined(_RIM_LIGHTING1)
+ {
+ float rl = abs(theta) / PI; // on [0, 1]
+ rl = pow(2, -_Rim_Lighting1_Power * abs(rl - _Rim_Lighting1_Center));
+ float3 matcap = rl * _Rim_Lighting1_Color * _Rim_Lighting1_Strength;
+#if defined(_RIM_LIGHTING1_MASK)
+ float4 matcap_mask_raw = _Rim_Lighting1_Mask.SampleGrad(linear_repeat_s, i.uv.xy, iddx, iddy);
+ float matcap_mask = matcap_mask_raw.r * matcap_mask_raw.a;
+ matcap_mask = (bool) round(_Rim_Lighting1_Mask_Invert) ? 1 - matcap_mask : matcap_mask;
+#else
+ float matcap_mask = 1;
#endif
+ int mode = round(_Rim_Lighting1_Mode);
+ switch (mode) {
+ case 0:
+ albedo.rgb += lerp(0, matcap, matcap_mask);
+ break;
+ case 1:
+ albedo.rgb *= lerp(1, matcap, matcap_mask);
+ break;
+ case 2:
+ albedo.rgb = lerp(albedo.rgb, matcap, matcap_mask);;
+ break;
+ case 3:
+ albedo.rgb -= lerp(0, matcap, matcap_mask);
+ break;
+ case 4:
+ albedo.rgb = lerp(albedo.rgb, min(albedo.rgb, matcap), matcap_mask);
+ break;
+ case 5:
+ albedo.rgb = lerp(albedo.rgb, max(albedo.rgb, matcap), matcap_mask);
+ break;
+ default:
+ break;
+ }
+ }
+#endif // _RIM_LIGHTING1
}
+#endif // _RIM_LIGHTING0 || _RIM_LIGHTING1
#if defined(_OKLAB)
// Do hue shift in perceptually uniform color space so it doesn't look like
diff --git a/tooner_outline_pass.cginc b/tooner_outline_pass.cginc
index a2b222b..35e22b5 100644
--- a/tooner_outline_pass.cginc
+++ b/tooner_outline_pass.cginc
@@ -19,8 +19,8 @@ struct tess_data
};
struct tess_factors {
- float edge[4] : SV_TessFactor;
- float inside[2] : SV_InsideTessFactor;
+ float edge[3] : SV_TessFactor;
+ float inside: SV_InsideTessFactor;
};
v2f vert(appdata v)
@@ -61,6 +61,7 @@ v2f vert(appdata v)
v2f o;
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
+ o.objPos = v.vertex;
o.clipPos = UnityObjectToClipPos(v.vertex);
o.normal = normal;
o.uv = v.uv0.xy;
@@ -103,43 +104,46 @@ tess_data hull_vertex(appdata v)
return o;
}
-tess_factors patch_constant(InputPatch<tess_data, 4> patch)
+tess_factors patch_constant(InputPatch<tess_data, 3> patch)
{
tess_factors f;
- float factor = _Chain_Tess_Factor;
+
+ float3 worldPos = mul(unity_ObjectToWorld, patch[0].vertex);
+ float factor = _Tess_Factor;
+ if (_Tess_Dist_Cutoff > 0 && length(_WorldSpaceCameraPos - worldPos) > _Tess_Dist_Cutoff) {
+ factor = 1;
+ }
+
f.edge[0] = factor;
f.edge[1] = factor;
f.edge[2] = factor;
- f.edge[3] = factor;
- f.inside[0] = factor;
- f.inside[1] = factor;
+ f.inside = factor;
return f;
}
-[UNITY_domain("quad")]
+[UNITY_domain("tri")]
[UNITY_outputcontrolpoints(3)]
[UNITY_outputtopology("triangle_cw")]
[UNITY_partitioning("fractional_odd")]
[UNITY_patchconstantfunc("patch_constant")]
tess_data hull(
- InputPatch<tess_data, 4> patch,
+ InputPatch<tess_data, 3> patch,
uint id : SV_OutputControlPointID)
{
return patch[id];
}
-[UNITY_domain("quad")]
+[UNITY_domain("tri")]
v2f domain(
tess_factors factors,
- OutputPatch<tess_data, 4> patch,
- float2 uv : SV_DomainLocation)
+ OutputPatch<tess_data, 3> patch,
+ float3 baryc : SV_DomainLocation)
{
v2f data;
#define DOMAIN_INTERP(fieldName) data.fieldName = \
- lerp(\
- lerp(patch[0].fieldName, patch[1].fieldName, uv.x), \
- lerp(patch[2].fieldName, patch[3].fieldName, uv.x), \
- uv.y)
+ patch[0].fieldName * baryc.x + \
+ patch[1].fieldName * baryc.y + \
+ patch[2].fieldName * baryc.z;
DOMAIN_INTERP(uv);
DOMAIN_INTERP(normal);
//DOMAIN_INTERP(tangent);
@@ -148,11 +152,12 @@ v2f domain(
DOMAIN_INTERP(vertexLightColor);
#endif
- float4 pos = lerp(
- lerp(patch[0].vertex, patch[1].vertex, uv.x),
- lerp(patch[2].vertex, patch[3].vertex, uv.x),
- uv.y);
+ float4 pos =
+ patch[0].vertex * baryc.x +
+ patch[1].vertex * baryc.y +
+ patch[2].vertex * baryc.z;
data.clipPos = UnityObjectToClipPos(pos);
+ data.objPos = pos;
data.worldPos = mul(unity_ObjectToWorld, pos);
return data;
@@ -168,6 +173,10 @@ void geom(triangle v2f tri_in[3],
uint pid: SV_PrimitiveID,
inout TriangleStream<v2f> tri_out)
{
+#if !defined(_OUTLINES)
+ return;
+#endif
+
v2f v0 = tri_in[0];
v2f v1 = tri_in[1];
v2f v2 = tri_in[2];
@@ -245,12 +254,6 @@ void geom(triangle v2f tri_in[3],
v1.normal = nn;
v2.normal = nn;
- n = normalize(cross(v1.worldPos - v0.worldPos, v2.worldPos - v0.worldPos));
- avg_pos = (v0.worldPos + v1.worldPos + v2.worldPos) / 3;
- v0.worldPos = applyScroll(v0.worldPos, n, avg_pos);
- v1.worldPos = applyScroll(v1.worldPos, n, avg_pos);
- v2.worldPos = applyScroll(v2.worldPos, n, avg_pos);
-
// Omit geometry that's too close when exploded.
/*
if (_Explode_Phase > .05 && length(v0.worldPos - _WorldSpaceCameraPos) < .2) {
@@ -268,6 +271,23 @@ void geom(triangle v2f tri_in[3],
v2.clipPos = UnityObjectToClipPos(v2_objPos);
}
#endif
+#if defined(_SCROLL)
+ {
+ float3 n = normalize(cross(v1.worldPos - v0.worldPos, v2.worldPos - v0.worldPos));
+ float3 avg_pos = (v0.worldPos + v1.worldPos + v2.worldPos) / 3;
+ v0.worldPos = applyScroll(v0.worldPos, n, avg_pos);
+ v1.worldPos = applyScroll(v1.worldPos, n, avg_pos);
+ v2.worldPos = applyScroll(v2.worldPos, n, avg_pos);
+
+ float3 v0_objPos = mul(unity_WorldToObject, float4(v0.worldPos, 1));
+ float3 v1_objPos = mul(unity_WorldToObject, float4(v1.worldPos, 1));
+ float3 v2_objPos = mul(unity_WorldToObject, float4(v2.worldPos, 1));
+
+ v0.clipPos = UnityObjectToClipPos(v0_objPos);
+ v1.clipPos = UnityObjectToClipPos(v1_objPos);
+ v2.clipPos = UnityObjectToClipPos(v2_objPos);
+ }
+#endif
#if defined(_CLONES)
v2f clone_verts[3] = {v0, v1, v2};
add_clones(clone_verts, tri_out);