diff options
| -rw-r--r-- | Editor/tooner.cs | 10 | ||||
| -rw-r--r-- | globals.cginc | 2 | ||||
| -rw-r--r-- | mochie_shadow_caster.cginc | 20 | ||||
| -rw-r--r-- | pbr.cginc | 116 | ||||
| -rw-r--r-- | tooner.shader | 6 | ||||
| -rw-r--r-- | tooner_lighting.cginc | 6 | ||||
| -rw-r--r-- | tooner_outline_pass.cginc | 24 |
7 files changed, 143 insertions, 41 deletions
diff --git a/Editor/tooner.cs b/Editor/tooner.cs index fb870ca..a3af66c 100644 --- a/Editor/tooner.cs +++ b/Editor/tooner.cs @@ -1211,6 +1211,16 @@ public class ToonerGUI : ShaderGUI { bc); SetKeyword("_CUBEMAP", bc.textureValue); + bc = FindProperty("_Lighting_Factor"); + editor.RangeProperty( + bc, + "Lighting multiplier"); + + bc = FindProperty("_Reflection_Probe_Saturation"); + editor.RangeProperty( + bc, + "Reflection probe saturation"); + bc = FindProperty("_Shadow_Strength"); editor.RangeProperty( bc, diff --git a/globals.cginc b/globals.cginc index 19e82d4..7191b0f 100644 --- a/globals.cginc +++ b/globals.cginc @@ -12,6 +12,8 @@ float _Roughness; float _Tex_NormalStr; float _NormalStr; +float _Lighting_Factor; +float _Reflection_Probe_Saturation; float _Min_Brightness; float _Max_Brightness; diff --git a/mochie_shadow_caster.cginc b/mochie_shadow_caster.cginc index 8ca599c..6c33ce7 100644 --- a/mochie_shadow_caster.cginc +++ b/mochie_shadow_caster.cginc @@ -32,17 +32,21 @@ #pragma multi_compile_instancing #pragma multi_compile_shadowcaster #include "UnityCG.cginc" +#include "globals.cginc" struct appdata { float4 vertex : POSITION; float3 normal : NORMAL; + float2 uv : TEXCOORD0; + UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID - UNITY_VERTEX_OUTPUT_STEREO + UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata v){ @@ -50,10 +54,22 @@ v2f vert (appdata v){ UNITY_SETUP_INSTANCE_ID(v); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); TRANSFER_SHADOW_CASTER_NORMALOFFSET(o) - return o; + o.uv = v.uv; + return o; } float4 frag (v2f i) : SV_Target { +#if defined(_BASECOLOR_MAP) + float iddx = ddx(i.uv.x); + float iddy = ddx(i.uv.y); + float4 albedo = _MainTex.SampleGrad(linear_repeat_s, i.uv, iddx, iddy); + albedo *= _Color; +#else + float4 albedo = _Color; +#endif // _BASECOLOR_MAP +#if defined(_RENDERING_CUTOUT) + clip(albedo.a - _Alpha_Cutoff); +#endif UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); return 0; } @@ -37,7 +37,7 @@ void ltcgi_cb_specular(inout ltcgi_acc acc, in ltcgi_output output) { UNITY_DECLARE_TEXCUBE(_Cubemap); -UnityLight CreateDirectLight(float3 normal, float ao, v2f i, out float attenuation) +UnityLight CreateDirectLight(float3 normal, v2f i, out float attenuation) { #if 1 // This whole block is yoinked from AutoLight.cginc. I needed a way to @@ -72,7 +72,7 @@ UnityLight CreateDirectLight(float3 normal, float ao, v2f i, out float attenuati #endif UnityLight light; - light.color = _LightColor0.rgb * attenuation * ao; + light.color = _LightColor0.rgb * attenuation; #if defined(POINT) || defined(POINT_COOKIE) || defined(SPOT) light.dir = normalize((_WorldSpaceLightPos0 - i.worldPos).xyz); #else @@ -109,7 +109,7 @@ float3 BoxProjection ( } UnityIndirect CreateIndirectLight(float4 vertexLightColor, float3 view_dir, float3 normal, - float smoothness, float3 worldPos, float ao, float2 uv) { + float smoothness, float3 worldPos, float2 uv) { UnityIndirect indirect; indirect.diffuse = vertexLightColor; indirect.specular = 0; @@ -170,8 +170,6 @@ UnityIndirect CreateIndirectLight(float4 vertexLightColor, float3 view_dir, floa #endif // FORWARD_BASE_PASS - indirect.diffuse *= ao; - return indirect; } @@ -199,10 +197,10 @@ float4 getLitColor( normal = lerp(normal, spherical_normal, normals_mode == 1); UnityIndirect indirect_light = CreateIndirectLight(vertexLightColor, - view_dir, normal, smoothness, worldPos, ao, uv); + view_dir, normal, smoothness, worldPos, uv); float attenuation; - UnityLight direct_light = CreateDirectLight(normal, ao, i, attenuation); + UnityLight direct_light = CreateDirectLight(normal, i, attenuation); if (normals_mode == 0) { float e = 0.8; indirect_light.diffuse += direct_light.color * e; @@ -224,13 +222,32 @@ float4 getLitColor( } #endif + direct_light.color *= _Lighting_Factor; + indirect_light.specular *= _Lighting_Factor; + indirect_light.diffuse *= _Lighting_Factor; + + if (_Reflection_Probe_Saturation < 1.0) { + indirect_light.specular = RGBtoHSV(indirect_light.specular); + indirect_light.specular[1] *= _Reflection_Probe_Saturation; + indirect_light.specular = HSVtoRGB(indirect_light.specular); + indirect_light.diffuse = RGBtoHSV(indirect_light.diffuse); + indirect_light.diffuse[1] *= _Reflection_Probe_Saturation; + indirect_light.diffuse = HSVtoRGB(indirect_light.diffuse); + } + direct_light.color = clamp(direct_light.color, _Min_Brightness, _Max_Brightness); - indirect_light.diffuse = clamp(indirect_light.diffuse, _Min_Brightness, _Max_Brightness); + // Diffuse is set low as a hack. Most maps rely on skybox lighting and set + // diffuse way too high. + indirect_light.diffuse = clamp(indirect_light.diffuse, _Min_Brightness, _Max_Brightness * 0.5); indirect_light.specular = clamp(indirect_light.specular, _Min_Brightness, _Max_Brightness); + // Apply AO + indirect_light.diffuse *= ao; + float3 direct_color = direct_light.color; + direct_light.color *= ao; + float2 screenUVs = 0; float4 screenPos = 0; - #if 1 float4 pbr = BRDF1_Mochie_PBS( albedo, @@ -264,34 +281,61 @@ float4 getLitColor( #endif #if defined(_CLEARCOAT) - half3 half_dir = Unity_SafeNormalize(half3(direct_light.dir) + view_dir); - half lh = saturate(dot(direct_light.dir, half_dir)); - half cc_nh = saturate(dot(i.normal, half_dir)); - float clearcoat = FilamentClearcoat( - _Clearcoat_Roughness, - _Clearcoat_Strength, - cc_nh, - lh, - half_dir); - float cc_mask = _Clearcoat_Mask.SampleGrad(linear_repeat_s, i.uv, ddx(i.uv.x), ddy(i.uv.y)); - pbr.rgb += clearcoat * saturate(dot(i.normal, direct_light.dir)) * cc_mask * 10; + // Direct lighting + float cc_mask = _Clearcoat_Mask.SampleGrad(linear_repeat_s, i.uv, ddx(i.uv.x), ddy(i.uv.y)); + { + float3 cc_L = direct_light.dir; + half3 cc_H = Unity_SafeNormalize(cc_L + view_dir); + half cc_LoH = saturate(dot(direct_light.dir, cc_H)); + float3 cc_N = normalize(i.normal); + half cc_NoH = saturate(dot(i.normal, cc_H)); + float clearcoat = FilamentClearcoat( + _Clearcoat_Roughness, + _Clearcoat_Strength, + cc_NoH, + cc_LoH, + cc_H); + pbr.rgb += clearcoat * saturate(dot(i.normal, cc_L)) * + cc_mask * direct_color * 10; + } + // Indirect specular lighting +#if 1 + { + float3 in_L = normalize(reflect(-view_dir, i.normal)); + half3 in_H = i.normal; + half in_LoH = saturate(dot(in_L, in_H)); + half in_NoH = 1; + float clearcoat = FilamentClearcoat( + _Clearcoat_Roughness, + _Clearcoat_Strength, + in_NoH, + in_LoH, + in_H); + pbr.rgb += clearcoat * saturate(dot(i.normal, in_L)) * + cc_mask * indirect_light.specular * 1; + } +#endif #if defined(VERTEXLIGHT_ON) - for (uint ii = 0; ii < 4; ii++) { - float3 vpos = float3(unity_4LightPosX0[ii], unity_4LightPosY0[ii], unity_4LightPosZ0[ii]); - float3 vl = normalize(vpos - i.worldPos); - - half3 vhalf = Unity_SafeNormalize(half3(vl) + view_dir); - half vlh = saturate(dot(vl, vhalf)); - half cc_vnh = saturate(dot(i.normal, vhalf)); - - clearcoat = FilamentClearcoat( - _Clearcoat_Roughness, - _Clearcoat_Strength, - cc_vnh, - vlh, - vhalf); - pbr.rgb += clearcoat * saturate(dot(i.normal, vl)) * cc_mask * 10; - } + // Vertex lights + for (uint ii = 0; ii < 4; ii++) { + float3 vpos = float3(unity_4LightPosX0[ii], unity_4LightPosY0[ii], + unity_4LightPosZ0[ii]); + float3 vl = normalize(vpos - i.worldPos); + float3 c = unity_LightColor[0].rgb; + + half3 vhalf = Unity_SafeNormalize(half3(vl) + view_dir); + half vlh = saturate(dot(vl, vhalf)); + half cc_vnh = saturate(dot(i.normal, vhalf)); + + float clearcoat = FilamentClearcoat( + _Clearcoat_Roughness, + _Clearcoat_Strength, + cc_vnh, + vlh, + vhalf); + pbr.rgb += clearcoat * saturate(dot(i.normal, vl)) * + cc_mask * c * 10; + } #endif #endif diff --git a/tooner.shader b/tooner.shader index f2df686..46d33e3 100644 --- a/tooner.shader +++ b/tooner.shader @@ -102,6 +102,8 @@ Shader "yum_food/tooner" [NoScaleOffset] _Tex_NormalStr("Normal texture strength", Range(0, 10)) = 1 _Cubemap("Cubemap", Cube) = "" {} + _Lighting_Factor("Lighting factor", Range(0, 5)) = 1 + _Reflection_Probe_Saturation("Reflection probe saturation", Range(0, 1)) = 1 _Min_Brightness("Min brightness", Range(0, 1)) = 0 _Max_Brightness("Max brightness", Range(0, 1.5)) = 1 _Mesh_Normal_Strength("Mesh normal strength", Range(0, 10)) = 1 @@ -402,8 +404,12 @@ Shader "yum_food/tooner" "LightMode" = "ShadowCaster" } CGPROGRAM + #pragma target 5.0 + #include "feature_macros.cginc" + #pragma vertex vert #pragma fragment frag + #include "mochie_shadow_caster.cginc" ENDCG } diff --git a/tooner_lighting.cginc b/tooner_lighting.cginc index be06d69..e11f0dc 100644 --- a/tooner_lighting.cginc +++ b/tooner_lighting.cginc @@ -1,6 +1,8 @@ #ifndef TOONER_LIGHTING #define TOONER_LIGHTING +#include "UnityCG.cginc" + #include "audiolink.cginc" #include "clones.cginc" #include "eyes.cginc" @@ -203,7 +205,7 @@ tess_factors patch_constant(InputPatch<tess_data, 3> patch) tess_factors f; #if defined(_TESSELLATION) - float3 worldPos = mul(unity_ObjectToWorld, patch[0].vertex); + float3 worldPos = mul(unity_ObjectToWorld, patch[0].pos); float factor = _Tess_Factor; if (_Tess_Dist_Cutoff > 0 && length(_WorldSpaceCameraPos - worldPos) > _Tess_Dist_Cutoff) { factor = 1; @@ -782,6 +784,8 @@ float4 effect(inout v2f i) float iddx = ddx(i.uv.x) * _Mip_Multiplier; float iddy = ddx(i.uv.y) * _Mip_Multiplier; const float3 view_dir = normalize(_WorldSpaceCameraPos - i.worldPos); + // Not necessarily normalized after interpolation. + i.normal = normalize(i.normal); #if defined(_TROCHOID) { diff --git a/tooner_outline_pass.cginc b/tooner_outline_pass.cginc index 09c746d..ebc717a 100644 --- a/tooner_outline_pass.cginc +++ b/tooner_outline_pass.cginc @@ -8,6 +8,7 @@ #include "globals.cginc" #include "math.cginc" #include "pbr.cginc" +#include "oklab.cginc" #include "trochoid_math.cginc" #include "tooner_scroll.cginc" #include "UnityCG.cginc" @@ -343,15 +344,34 @@ fixed4 frag (v2f i) : SV_Target // TODO FIXME the normals are fucked in pbr pass, causing flickering //return _Outline_Color; + albedo = _Outline_Color; +#if defined(_OKLAB) + // Do hue shift in perceptually uniform color space so it doesn't look like + // shit. + float oklab_mask = _OKLAB_Mask.SampleGrad(linear_repeat_s, i.uv, iddx, iddy); + if (oklab_mask > 0.01 && + (_OKLAB_Hue_Shift > 1E-6 || + abs(_OKLAB_Chroma_Shift) > 1E-6 || + abs(_OKLAB_Lightness_Shift) > 1E-6)) { + float3 c = albedo.rgb; + c = LRGBtoOKLCH(c); + c.x += _OKLAB_Lightness_Shift; + c.y += _OKLAB_Chroma_Shift; + c.z += _OKLAB_Hue_Shift; + c = OKLCHtoLRGB(c); + albedo.rgb = c; + } +#endif + //float3 flat_normal = normalize(UnpackNormal(float4(128, 128, 255, 255)/255)); float3 flat_normal = normalize(_WorldSpaceCameraPos - i.worldPos); float4 vertex_light_color = 0; float ao = 1; float4 result = getLitColor( vertex_light_color, - _Outline_Color, i.worldPos, flat_normal, 0, 0, i.uv, ao, i); + albedo, i.worldPos, flat_normal, 0, 0, i.uv, ao, i); - result += _Outline_Color * _Outline_Emission_Strength; + result += albedo * _Outline_Emission_Strength; #if defined(_EXPLODE) && defined(_AUDIOLINK) if (AudioLinkIsAvailable() && _Explode_Phase > 1E-6) { |
