A game about forced loneliness, made by TACStudios
1#ifndef UNITY_SIX_WAY_COMMON_INCLUDED
2#define UNITY_SIX_WAY_COMMON_INCLUDED
3
4#define ABSORPTION_EPSILON max(REAL_MIN, 1e-5)
5
6real3 ComputeDensityScales(real3 absorptionColor)
7{
8 absorptionColor.rgb = max(ABSORPTION_EPSILON, absorptionColor.rgb);
9
10 // Empirical value used to parametrize absorption from color
11 const real absorptionStrength = 0.2f;
12 return 1.0f + log2(absorptionColor.rgb) / log2(absorptionStrength);
13}
14
15real3 GetTransmissionWithAbsorption(real transmission, real3 densityScales, real absorptionRange)
16{
17 // Recompute transmission based on density scaling
18 return pow(saturate(transmission / absorptionRange), densityScales);
19}
20
21real3 GetTransmissionWithAbsorption(real transmission, real4 absorptionColor, real absorptionRange, bool alphaPremultiplied)
22{
23#if defined(_SIX_WAY_COLOR_ABSORPTION)
24 real3 densityScales = ComputeDensityScales(absorptionColor.rgb);
25
26 if(alphaPremultiplied)
27 absorptionRange *= (absorptionColor.a > 0) ? absorptionColor.a : 1.0f;
28
29 real3 outTransmission = GetTransmissionWithAbsorption(transmission, densityScales, absorptionRange);
30 outTransmission *= absorptionRange;
31
32 return outTransmission;
33#else
34 return transmission.xxx * absorptionColor.rgb; // simple multiply
35#endif
36}
37
38
39real3 GetSixWayDiffuseContributions(real3 rightTopBack, real3 leftBottomFront, real4 baseColor, real3 L0, real3 diffuseGIData[3], real absorptionRange, bool alphaPremultiplied)
40{
41 real3 giColor = real3(0,0,0);
42
43 // Scale to be energy conserving: Total energy = 4*pi; divided by 6 directions
44 real scale = 4.0f * PI / 6.0f;
45 #if defined(_SIX_WAY_COLOR_ABSORPTION)
46 real3 densityScales = ComputeDensityScales(baseColor.rgb);
47 if(alphaPremultiplied)
48 absorptionRange *= (baseColor.a > 0) ? baseColor.a : 1.0f;
49 for(int i = 0; i < 3; i++)
50 {
51 real3 bakeDiffuseLighting = L0 + diffuseGIData[i];
52 giColor += GetTransmissionWithAbsorption(rightTopBack[i], densityScales, absorptionRange) * bakeDiffuseLighting;
53 bakeDiffuseLighting = L0 - diffuseGIData[i];
54 giColor += GetTransmissionWithAbsorption(leftBottomFront[i], densityScales, absorptionRange) * bakeDiffuseLighting;
55 }
56 giColor *= absorptionRange;
57 #else
58 for(int i = 0; i < 3; i++)
59 {
60 real3 bakeDiffuseLighting = L0 + diffuseGIData[i];
61 giColor += rightTopBack[i] * bakeDiffuseLighting;
62 bakeDiffuseLighting = L0 - diffuseGIData[i];
63 giColor += leftBottomFront[i] * bakeDiffuseLighting;
64 }
65 giColor *= baseColor.rgb;
66 #endif
67 return giColor * scale;
68}
69
70#endif // UNITY_SIX_WAY_COMMON_INCLUDED