forked from NoiRC256/URPSimpleGenshinShaders
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSimpleGenshinFacial_LightingEquation.hlsl
116 lines (91 loc) · 4.78 KB
/
SimpleGenshinFacial_LightingEquation.hlsl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// For more information, visit -> https://github.com/NoiRC256/UnityURPToonLitShaderExample
// Original shader -> https://github.com/ColinLeung-NiloCat/UnityURPToonLitShaderExample
// This file is intented for you to edit and experiment with different lighting equation.
// Add or edit whatever code you want here
// #ifndef XXX + #define XXX + #endif is a safe guard best practice in almost every .hlsl,
// doing this can make sure your .hlsl's user can include this .hlsl anywhere anytime without producing any multi include conflict
#ifndef SimpleGenshinFacial_LightingEquation_Include
#define SimpleGenshinFacial_LightingEquation_Include
half3 InternalShadeGI(ToonSurfaceData surfaceData, ToonLightingData lightingData)
{
// hide 3D feeling by ignoring all detail SH
// SH 1 (only use this)
// SH 234 (ignored)
// SH 56789 (ignored)
// we just want to tint some average envi color only
half3 averageSH = SampleSH(0);
// occlusion
// separated control for indirect occlusion
half indirectOcclusion = lerp(1, surfaceData.occlusion, _OcclusionIndirectStrength);
half3 indirectLight = averageSH * (_IndirectLightMultiplier * indirectOcclusion);
return max(indirectLight, _IndirectLightMinColor); // can prevent completely black if lightprobe was not baked
}
half3 InternalShadeMainLight(ToonSurfaceData surfaceData, ToonLightingData lightingData, Light light, bool isAdditionalLight)
{
half3 L = light.direction;
// Get forward and right directions from rotation matrix.
float3 Forward = unity_ObjectToWorld._m02_m12_m22;
float3 Right = unity_ObjectToWorld._m00_m10_m20;
// Get xz plane dot products with light direction.
float FdotL = dot(normalize(Forward.xz), normalize(L.xz));
float RdotL = dot(normalize(Right.xz), normalize(L.xz));
// Choose original lightmap L (light from left) or flipped lightmap R (light from right).
float LightMap = lerp(surfaceData._lightMapR.r, surfaceData._lightMapL.r, step(RdotL, 0));
// Calculate result.
float litOrShadow = step((-FdotL + 1) / 2, LightMap);
return light.color * lerp(litOrShadow, 1, step(surfaceData._useLightMap, 0));
}
half3 InternalShadeAdditionalLights(ToonSurfaceData surfaceData,
ToonLightingData lightingData, Light light, bool isAdditionalLight)
{
return 0; //write your own equation here ! (see ShadeSingleLightDefaultMethod(...))
}
half3 InternalShadeEmission(ToonSurfaceData surfaceData, ToonLightingData lightingData, Light light, bool isAdditionalLight)
{
half3 N = lightingData.normalWS;
half3 L = light.direction;
half3 V = lightingData.viewDirectionWS;
half3 H = normalize(L + V);
half3 shadowColor = surfaceData._shadowColor;
half3 emission = surfaceData.emission;
half NoL = dot(N, L);
half3 emissionResult = lerp(emission, emission * surfaceData.albedo, _EmissionMulByBaseColor); // optional mul albedo
return emissionResult;
}
// Composite all shading results.
half3 InternalCompositeLightResults(half3 indirectResult, half3 mainLightResult, half3 additionalLightSumResult, half3 emissionResult,
ToonSurfaceData surfaceData, ToonLightingData lightingData, Light light)
{
half3 shadowColor = light.color * lerp(1 * surfaceData._shadowColor, 1, mainLightResult);
half3 rawLightSum = max(indirectResult * shadowColor, mainLightResult + additionalLightSumResult); // pick the highest between indirect and direct light
half lightLuminance = Luminance(rawLightSum);
half3 finalLightMulResult = rawLightSum / max(1, lightLuminance / max(1, log(lightLuminance))); // allow controlled over bright using log
return surfaceData.albedo * finalLightMulResult + emissionResult;
}
// We split lighting functions into:
// - indirect
// - main light
// - additional lights (point lights/spot lights)
// - emission
half3 ShadeGI(ToonSurfaceData surfaceData, ToonLightingData lightingData)
{
return InternalShadeGI(surfaceData, lightingData);
}
half3 ShadeMainLight(ToonSurfaceData surfaceData, ToonLightingData lightingData, Light light)
{
return InternalShadeMainLight(surfaceData, lightingData, light, false);
}
half3 ShadeAdditionalLight(ToonSurfaceData surfaceData, ToonLightingData lightingData, Light light)
{
return InternalShadeAdditionalLights(surfaceData, lightingData, light, true);
}
half3 ShadeEmission(ToonSurfaceData surfaceData, ToonLightingData lightingData, Light light)
{
return InternalShadeEmission(surfaceData, lightingData, light, false);
}
half3 CompositeAllLightResults(half3 indirectResult, half3 mainLightResult, half3 additionalLightSumResult, half3 emissionResult,
ToonSurfaceData surfaceData, ToonLightingData lightingData, Light light)
{
return InternalCompositeLightResults(indirectResult, mainLightResult, additionalLightSumResult, emissionResult, surfaceData, lightingData, light);
}
#endif