summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--2ner.shader1
-rw-r--r--poi.cginc61
-rw-r--r--yum_lighting.cginc50
3 files changed, 43 insertions, 69 deletions
diff --git a/2ner.shader b/2ner.shader
index ad29182..1192b58 100644
--- a/2ner.shader
+++ b/2ner.shader
@@ -672,7 +672,6 @@ Shader "yum_food/2ner"
[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend("Source Blend", Float) = 1
[Enum(UnityEngine.Rendering.BlendMode)] _DstBlend("Destination Blend", Float) = 0
[Enum(Off, 0, On, 1)] _ZWrite("ZWrite", Int) = 1
- [Enum(Realistic, 0, Toon, 1)] _SphericalHarmonics("Spherical harmonics", Int) = 1
[HideInInspector] m_start_blending ("Blending--{button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/rendering/blending},hover:Documentation}}", Float) = 0
[DoNotAnimate][Enum(Thry.BlendOp)]_BlendOp ("RGB Blend Op", Int) = 0
[DoNotAnimate][Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend ("RGB Source Blend", Int) = 1
diff --git a/poi.cginc b/poi.cginc
index df89bbf..cc12b1a 100644
--- a/poi.cginc
+++ b/poi.cginc
@@ -57,72 +57,11 @@ float3 HSVtoRGB(in float3 HSV)
return ((RGB - 1) * HSV.y + 1) * HSV.z;
}
-float shEvaluateDiffuseL1Geomerics_local(float L0, float3 L1, float3 n)
-{
- // average energy
- float R0 = max(0, L0);
-
- // avg direction of incoming light
- float3 R1 = 0.5f * L1;
-
- // directional brightness
- float lenR1 = length(R1);
-
- // linear angle between normal and direction 0-1
- //float q = 0.5f * (1.0f + dot(R1 / lenR1, n));
- //float q = dot(R1 / lenR1, n) * 0.5 + 0.5;
- float q = dot(normalize(R1), n) * 0.5 + 0.5;
- q = saturate(q); // Thanks to ScruffyRuffles for the bug identity.
-
- // power for q
- // lerps from 1 (linear) to 3 (cubic) based on directionality
- float p = 1.0f + 2.0f * lenR1 / R0;
-
- // dynamic range constant
- // should vary between 4 (highly directional) and 0 (ambient)
- float a = (1.0f - lenR1 / R0) / (1.0f + lenR1 / R0);
-
- return R0 * (a + (1.0f - a) * (p + 1.0f) * pow(q, p));
-}
-
-half3 BetterSH9(half4 normal)
-{
- float3 indirect;
- float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w) + float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / 3.0;
- indirect.r = shEvaluateDiffuseL1Geomerics_local(L0.r, unity_SHAr.xyz, normal.xyz);
- indirect.g = shEvaluateDiffuseL1Geomerics_local(L0.g, unity_SHAg.xyz, normal.xyz);
- indirect.b = shEvaluateDiffuseL1Geomerics_local(L0.b, unity_SHAb.xyz, normal.xyz);
- indirect = max(0, indirect);
- indirect += SHEvalLinearL2(normal);
- return indirect;
-}
-
float calculateluminance(float3 color)
{
return color.r * 0.299 + color.g * 0.587 + color.b * 0.114;
}
-float3 getPoiLightingDirect(float3 normal) {
- float3 magic = max(BetterSH9(normalize(unity_SHAr + unity_SHAg + unity_SHAb)), 0);
- float3 normalLight = _LightColor0.rgb + BetterSH9(float4(0, 0, 0, 1));
-
- float magiLumi = calculateluminance(magic);
- float normaLumi = calculateluminance(normalLight);
- float maginormalumi = magiLumi + normaLumi;
-
- float magiratio = magiLumi / maginormalumi;
- float normaRatio = normaLumi / maginormalumi;
-
- float target = calculateluminance(magic * magiratio + normalLight * normaRatio);
- float3 properLightColor = magic + normalLight;
- float properLuminance = calculateluminance(magic + normalLight);
- return properLightColor * max(0.0001, (target / properLuminance));
-}
-
-float3 getPoiLightingIndirect() {
- return BetterSH9(float4(0, 0, 0, 1));
-}
-
bool SceneHasReflections()
{
float width, height;
diff --git a/yum_lighting.cginc b/yum_lighting.cginc
index b8856ed..23e360e 100644
--- a/yum_lighting.cginc
+++ b/yum_lighting.cginc
@@ -142,13 +142,54 @@ float3 getIndirectSpecular(v2f i, YumPbr pbr, float3 view_dir) {
return UnityGI_prefilteredRadiance(data, roughness, reflect_dir);
}
+float3 yumSH9(float4 n) {
+#if defined(YUM_SH9_STANDARD)
+ // Unity gives us the first three bands (L0-L2) of SH coefficients as follows:
+ // unity_SHA*.w: L0 coefficients
+ // unity_SHA*.xyz: L1 coefficients
+ // unity_SHB*: first four of the L2 coefficients
+ // unity_SHC: last L2 coefficient
+
+ // Parse out coefficients into a simpler but less efficient format.
+ float3 L00 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
+ float3 L1_1 = float3(unity_SHAr.x, unity_SHAg.x, unity_SHAb.x);
+ float3 L10 = float3(unity_SHAr.y, unity_SHAg.y, unity_SHAb.y);
+ float3 L11 = float3(unity_SHAr.z, unity_SHAg.z, unity_SHAb.z);
+ float3 L2_2 = float3(unity_SHBr.x, unity_SHBg.x, unity_SHBb.x);
+ float3 L2_1 = float3(unity_SHBr.y, unity_SHBg.y, unity_SHBb.y);
+ float3 L20 = float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z);
+ float3 L21 = float3(unity_SHBr.w, unity_SHBg.w, unity_SHBb.w);
+ float3 L22 = unity_SHC;
+
+ // Equation 13 from "An Efficient Representation for Irradiance Environment
+ // Maps" by Ramamoorthi and Hanrahan. Note that the order of some
+ // coefficients is different, and normalization constants have been
+ // premultiplied by Unity.
+ float3 L0 = L00;
+ float3 L1 = L1_1 * n.x + L10 * n.y + L11 * n.z;
+ float3 L2 =
+ L2_2 * n.x * n.y +
+ L2_1 * n.y * n.z +
+ L20 * n.z * n.z +
+ L21 * n.x * n.z +
+ L22 * (n.x * n.x - n.y * n.y);
+
+ return L0 + L1 + L2;
+#else
+ // On non-photorealistic avatars, simply using the diffuse component looks
+ // better. *shruge*
+ float3 L00 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
+ return L00;
+#endif
+}
+
float4 getIndirectDiffuse(v2f i, float4 vertexLightColor) {
float4 diffuse = vertexLightColor;
#if defined(FORWARD_BASE_PASS)
#if defined(LIGHTMAP_ON)
diffuse.xyz = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uv2));
#else
- diffuse.xyz += max(0, BetterSH9(float4(0, 0, 0, 1)));
+ diffuse.xyz += max(0, yumSH9(float4(0, 0, 0, 1)));
#endif
#endif
return diffuse;
@@ -169,12 +210,7 @@ YumLighting GetYumLighting(v2f i, YumPbr pbr) {
light.direct = _LightColor0.rgb;
// TODO filament's spherical harmonics look nicer than this.
// See FilamentLightIndirect.cginc::UnityGI_Irradiance in filamented.
- //ifex _Spherical_Harmonics==0
- light.diffuse = max(0, BetterSH9(float4(i.normal, 1)));
- //endex
- //ifex _Spherical_Harmonics==1
- light.diffuse = max(0, BetterSH9(float4(0, 0, 0, 1)));
- //endex
+ light.diffuse = getIndirectDiffuse(i, /*vertexLightColor=*/0);
#if defined(_MIN_BRIGHTNESS)
light.diffuse = max(_Min_Brightness, light.diffuse);
#endif