yum-archive/Tooner
A toon shader for Unity's BIRP.
git clone https://git.yummers.dev/yum-archive/Tooner
12e8a5c
master
1#ifndef MOCHIE_STANDARD_BRDF_INCLUDED 2#define MOCHIE_STANDARD_BRDF_INCLUDED 3 4/* 5 * MIT License 6 * 7 * Copyright (c) 2020 MochiesCode 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a copy 10 * of this software and associated documentation files (the "Software"), to 11 * deal 12 * in the Software without restriction, including without limitation the rights 13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 * copies of the Software, and to permit persons to whom the Software is 15 * furnished to do so, subject to the following conditions: 16 * 17 * The above copyright notice and this permission notice shall be included in 18 * all 19 * copies or substantial portions of the Software. 20 * 21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 26 * FROM, 27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 * THE 29 * SOFTWARE. 30 */ 31 32#include "UnityCG.cginc" 33#include "UnityStandardConfig.cginc" 34#include "UnityLightingCommon.cginc" 35#include "MochieStandardSSR.cginc" 36#include "MochieStandardSSS.cginc" 37 38float3 get_camera_pos() { 39 float3 worldCam; 40 worldCam.x = unity_CameraToWorld[0][3]; 41 worldCam.y = unity_CameraToWorld[1][3]; 42 worldCam.z = unity_CameraToWorld[2][3]; 43 return worldCam; 44} 45 46float GSAARoughness(float3 normal, float roughness){ 47 float3 normalDDX = ddx(normal); 48 float3 normalDDY = ddy(normal); 49 float dotX = dot(normalDDX, normalDDX); 50 float dotY = dot(normalDDY, normalDDY); 51 float base = saturate(max(dotX, dotY)); 52 return max(roughness, pow(base, 0.333)*_GSAAStrength); 53} 54 55float3 Desaturate(float3 col){ 56 return dot(col, float3(0.3, 0.59, 0.11)); 57} 58 59float3 GetContrast(float3 col, float contrast){ 60 return lerp(float3(0.5,0.5,0.5), col, contrast); 61} 62 63float oetf_sRGB_scalar(float L) { 64 float V = 1.055 * (pow(L, 1.0 / 2.4)) - 0.055; 65 if (L <= 0.0031308) 66 V = L * 12.92; 67 return V; 68} 69 70float3 oetf_sRGB(float3 L) { 71 return float3(oetf_sRGB_scalar(L.r), oetf_sRGB_scalar(L.g), oetf_sRGB_scalar(L.b)); 72} 73 74float eotf_sRGB_scalar(float V) { 75 float L = pow((V + 0.055) / 1.055, 2.4); 76 if (V <= oetf_sRGB_scalar(0.0031308)) 77 L = V / 12.92; 78 return L; 79} 80 81float3 GetHDR(float3 rgb) { 82 return float3(eotf_sRGB_scalar(rgb.r), eotf_sRGB_scalar(rgb.g), eotf_sRGB_scalar(rgb.b)); 83} 84 85half4 BRDF1_Mochie_PBS ( 86 half3 diffColor, half3 specColor, half oneMinusReflectivity, half smoothness, 87 half3 normal, half3 viewDir, half3 worldPos, half2 screenUVs, half4 screenPos, 88 half metallic, half thickness, half3 ssColor, half atten, float2 lightmapUV, float3 vertexColor, 89 UnityLight light, UnityIndirect gi, float reflection_strength, float ssr_mask) 90{ 91 92 half perceptualRoughness = SmoothnessToPerceptualRoughness(smoothness); 93 if (_GSAA == 1){ 94 perceptualRoughness = GSAARoughness(normal, perceptualRoughness); 95 } 96 half3 halfDir = Unity_SafeNormalize (half3(light.dir) + viewDir); 97 half nv = abs(dot(normal, viewDir)); 98 half nl = saturate(dot(normal, light.dir)); 99 half nh = saturate(dot(normal, halfDir)); 100 half lv = saturate(dot(light.dir, viewDir)); 101 half lh = saturate(dot(light.dir, halfDir)); 102 103 // Diffuse term 104 half diffuseTerm = DisneyDiffuse(nv, nl, lh, perceptualRoughness) * nl; 105 float wrappedDiffuse = saturate((diffuseTerm + _WrappingFactor) / 106 (1.0f + _WrappingFactor)) * 2 / (2 * (1 + _WrappingFactor)); 107 108 // Specular term 109 half roughness = PerceptualRoughnessToRoughness(perceptualRoughness); 110#if UNITY_BRDF_GGX 111 roughness = max(roughness, 0.002); 112 half V = SmithJointGGXVisibilityTerm (nl, nv, roughness); 113 half D = GGXTerm(nh, roughness); 114#else 115 half V = SmithBeckmannVisibilityTerm (nl, nv, roughness); 116 half D = NDFBlinnPhongNormalizedTerm (nh, PerceptualRoughnessToSpecPower(perceptualRoughness)); 117#endif 118 119#if defined(_SPECULARHIGHLIGHTS_OFF) 120 half specularTerm = 0.0; 121#else 122 half specularTerm = V*D * UNITY_PI; 123#ifdef UNITY_COLORSPACE_GAMMA 124 specularTerm = sqrt(max(1e-4h, specularTerm)); 125#endif 126 specularTerm = max(0, specularTerm * nl); 127#endif 128 half surfaceReduction; 129#ifdef UNITY_COLORSPACE_GAMMA 130 surfaceReduction = 1.0-0.28*roughness*perceptualRoughness; 131#else 132 surfaceReduction = 1.0 / (roughness*roughness + 1.0); 133#endif 134 135 half grazingTerm = saturate(smoothness + (1-oneMinusReflectivity)); 136 137 half3 diffCol = 0; 138 diffCol = diffColor * (gi.diffuse + light.color * lerp(diffuseTerm, wrappedDiffuse, thickness)); 139 140 // TODO this should probably use its own version of _WrappingFactor 141 specularTerm = saturate((specularTerm + _WrappingFactor) / 142 (1.0f + _WrappingFactor)) * 2 / (2 * (1 + _WrappingFactor)); 143 144 half3 specCol = specularTerm * light.color * FresnelTerm (specColor, lh) * _SpecularStrength; 145 146 half3 reflCol = surfaceReduction * gi.specular * FresnelLerp (specColor, grazingTerm, lerp(1, nv, _FresnelStrength*_UseFresnel)) * reflection_strength; 147#if SSR_ENABLED 148 half4 ssrCol = GetSSR(worldPos, viewDir, reflect(-viewDir, normal), normal, smoothness, diffColor, metallic, screenUVs, screenPos); 149 ssrCol.rgb *= _SSRStrength; 150 if (_EdgeFade == 0) 151 ssrCol.a = ssrCol.a > 0 ? 1 : 0; 152 reflCol = lerp(reflCol, ssrCol.rgb, ssrCol.a * saturate(_SSRStrength * ssr_mask)); 153 specCol *= 1 - ssrCol.a * ssr_mask; 154#endif 155 156 half3 subsurfaceCol = 0; 157 if (_Subsurface == 1){ 158 subsurfaceCol = GetSubsurfaceLight( 159 light.color, 160 light.dir, 161 normal, 162 viewDir, 163 atten, 164 thickness, 165 gi.diffuse, 166 ssColor 167 ); 168 } 169 170#ifdef LTCGI 171 if (_LTCGIStrength > 0){ 172 half3 diffLight = 0; 173 LTCGI_Contribution( 174 worldPos, 175 normal, 176 viewDir, 177 perceptualRoughness, 178 (lightmapUV - unity_LightmapST.zw) / unity_LightmapST.xy, 179 diffLight 180#ifndef _GLOSSYREFLECTIONS_OFF 181 , reflCol 182#endif 183 ); 184 diffCol += (diffColor * diffLight) * _LTCGIStrength; 185 } 186#endif 187 188#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON) 189 if (_ReflShadows == 1){ 190 float3 lightmap = Desaturate(DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, lightmapUV))); 191 lightmap = GetContrast(lightmap, _ContrastReflShad); 192 lightmap = lerp(lightmap, GetHDR(lightmap), _HDRReflShad); 193 lightmap *= _BrightnessReflShad; 194 lightmap *= _TintReflShad; 195 shadowedReflections = saturate(lerp(1, lightmap, _ReflShadowStrength)); 196 reflCol *= shadowedReflections; 197 specCol *= shadowedReflections; 198 } 199#else 200 shadowedReflections = lerp(1, lerp(1, atten, 0.9), _ReflShadows*_ReflShadowStrength); 201 reflCol *= shadowedReflections; 202#endif 203 204 // #ifdef FULL_VERSION 205 // reflCol *= lerp(1, vertexColor, _ReflVertexColor*_ReflVertexColorStrength); 206 // #endif 207 208 return half4(diffCol + specCol + reflCol + subsurfaceCol, 1); 209} 210 211#endif // MOCHIE_STANDARD_BRDF_INCLUDED