yum-archive/Tooner

A toon shader for Unity's BIRP.

git clone https://git.yummers.dev/yum-archive/Tooner

yumoops12e8a5c

master
6.9 KiB211 linesraw
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