diff options
Diffstat (limited to 'VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Includes/CGI_FurLighting.cginc')
-rw-r--r-- | VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Includes/CGI_FurLighting.cginc | 345 |
1 files changed, 345 insertions, 0 deletions
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Includes/CGI_FurLighting.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Includes/CGI_FurLighting.cginc new file mode 100644 index 00000000..c5f2dd06 --- /dev/null +++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Includes/CGI_FurLighting.cginc @@ -0,0 +1,345 @@ + +#ifndef POI_LIGHTING + #define POI_LIGHTING + + int _LightingType; + float _AdditiveSoftness; + float _AdditiveOffset; + float _ForceLightDirection; + float _ShadowStrength; + float _OutlineShadowStrength; + float _ShadowOffset; + float3 _LightDirection; + float _ForceShadowStrength; + float _CastedShadowSmoothing; + float _LightingIndirectContribution; + float _AttenuationMultiplier; + float _EnableLighting; + float _LightingControlledUseLightColor; + uint _LightingAOTexUV; + fixed _LightingStandardSmoothness; + fixed _LightingStandardControlsToon; + fixed _LightingMinLightBrightness; + fixed _LightingAdditiveIntensity; + fixed _AoIndirectStrength; + UNITY_DECLARE_TEX2D(_ToonRamp); + + sampler2D _LightingAOTex; float4 _LightingAOTex_ST; + sampler2D _LightingShadowMask; float4 _LightingShadowMask_ST; + float _AOStrength; + + float3 BoxProjection(float3 direction, float3 position, float4 cubemapPosition, float3 boxMin, float3 boxMax) + { + #if UNITY_SPECCUBE_BOX_PROJECTION + UNITY_BRANCH + if (cubemapPosition.w > 0) + { + float3 factors = ((direction > 0 ? boxMax: boxMin) - position) / direction; + float scalar = min(min(factors.x, factors.y), factors.z); + direction = direction * scalar + (position - cubemapPosition); + } + #endif + return direction; + } + + /* + * Standard stuff Start + */ + UnityLight CreateLight(half3 lightDirection, half attenuation, half ndotl) + { + UnityLight light; + light.dir = lightDirection; + light.color = saturate(_LightColor0.rgb * lerp(1, attenuation, _AttenuationMultiplier)); + light.ndotl = ndotl; + return light; + } + + float FadeShadows(float attenuation) + { + #if HANDLE_SHADOWS_BLENDING_IN_GI || ADDITIONAL_MASKED_DIRECTIONAL_SHADOWS + // UNITY_LIGHT_ATTENUATION doesn't fade shadows for us. + + #if ADDITIONAL_MASKED_DIRECTIONAL_SHADOWS + attenuation = lerp(1, attenuation, _AttenuationMultiplier); + #endif + + float viewZ = dot(_WorldSpaceCameraPos - worldPos, UNITY_MATRIX_V[2].xyz); + float shadowFadeDistance = UnityComputeShadowFadeDistance(worldPos, viewZ); + float shadowFade = UnityComputeShadowFade(shadowFadeDistance); + float bakedAttenuation = UnitySampleBakedOcclusion(lightmapUV.xy, worldPos); + attenuation = UnityMixRealtimeAndBakedShadows( + attenuation, bakedAttenuation, shadowFade + ); + #endif + + return attenuation; + } + + void ApplySubtractiveLighting(inout UnityIndirect indirectLight) + { + #if SUBTRACTIVE_LIGHTING + attenuation = FadeShadows(lerp(1, attenuation, _AttenuationMultiplier)); + + float nDotL = saturate(dot(i.normal, _WorldSpaceLightPos0.xyz)); + float3 shadowedLightEstimate = nDotL * (1 - attenuation) * _LightColor0.rgb; + float3 subtractedLight = indirectLight.diffuse - shadowedLightEstimate; + subtractedLight = max(subtractedLight, unity_ShadowColor.rgb); + subtractedLight = lerp(subtractedLight, indirectLight.diffuse, _LightShadowData.x); + indirectLight.diffuse = min(subtractedLight, indirectLight.diffuse); + #endif + } + + UnityIndirect CreateIndirectLight(float3 normal, float3 worldPos, half3 viewDir, float2 uv) + { + UnityIndirect indirectLight; + indirectLight.diffuse = 0; + indirectLight.specular = 0; + + #if defined(FORWARD_BASE_PASS) + #if defined(LIGHTMAP_ON) + indirectLight.diffuse = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, lightmapUV.xy)); + + #if defined(DIRLIGHTMAP_COMBINED) + float4 lightmapDirection = UNITY_SAMPLE_TEX2D_SAMPLER( + unity_LightmapInd, unity_Lightmap, lightmapUV.xy + ); + indirectLight.diffuse = DecodeDirectionalLightmap( + indirectLight.diffuse, lightmapDirection, normal + ); + #endif + ApplySubtractiveLighting(indirectLight); + #endif + + #if defined(DYNAMICLIGHTMAP_ON) + float3 dynamicLightDiffuse = DecodeRealtimeLightmap( + UNITY_SAMPLE_TEX2D(unity_DynamicLightmap, lightmapUV.zw) + ); + + #if defined(DIRLIGHTMAP_COMBINED) + float4 dynamicLightmapDirection = UNITY_SAMPLE_TEX2D_SAMPLER( + unity_DynamicDirectionality, unity_DynamicLightmap, + lightmapUV.zw + ); + indirectLight.diffuse += DecodeDirectionalLightmap( + dynamicLightDiffuse, dynamicLightmapDirection, normal + ); + #else + indirectLight.diffuse += dynamicLightDiffuse; + #endif + #endif + + #if !defined(LIGHTMAP_ON) && !defined(DYNAMICLIGHTMAP_ON) + #if UNITY_LIGHT_PROBE_PROXY_VOLUME + if (unity_ProbeVolumeParams.x == 1) + { + indirectLight.diffuse = SHEvalLinearL0L1_SampleProbeVolume( + float4(normal, 1), worldPos + ); + indirectLight.diffuse = max(0, indirectLight.diffuse); + #if defined(UNITY_COLORSPACE_GAMMA) + indirectLight.diffuse = LinearToGammaSpace(indirectLight.diffuse); + #endif + } + else + { + indirectLight.diffuse += max(0, ShadeSH9(float4(normal, 1))); + } + #else + indirectLight.diffuse += max(0, ShadeSH9(float4(normal, 1))); + #endif + #endif + + float3 reflectionDir = reflect(-viewDir, normal); + Unity_GlossyEnvironmentData envData; + envData.roughness = 1 - _LightingStandardSmoothness; + envData.reflUVW = BoxProjection( + reflectionDir, worldPos.xyz, + unity_SpecCube0_ProbePosition, + unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax + ); + float3 probe0 = Unity_GlossyEnvironment( + UNITY_PASS_TEXCUBE(unity_SpecCube0), unity_SpecCube0_HDR, envData + ); + envData.reflUVW = BoxProjection( + reflectionDir, worldPos.xyz, + unity_SpecCube1_ProbePosition, + unity_SpecCube1_BoxMin, unity_SpecCube1_BoxMax + ); + #if UNITY_SPECCUBE_BLENDING + float interpolator = unity_SpecCube0_BoxMin.w; + UNITY_BRANCH + if(interpolator < 0.99999) + { + float3 probe1 = Unity_GlossyEnvironment( + UNITY_PASS_TEXCUBE_SAMPLER(unity_SpecCube1, unity_SpecCube0), + unity_SpecCube0_HDR, envData + ); + indirectLight.specular = lerp(probe1, probe0, interpolator); + } + else + { + indirectLight.specular = probe0; + } + #else + indirectLight.specular = probe0; + #endif + + float occlusion = lerp(1, tex2D(_LightingAOTex, TRANSFORM_TEX(uv, _LightingAOTex)), _AOStrength); + + indirectLight.diffuse *= occlusion; + indirectLight.diffuse = max(indirectLight.diffuse, _LightingMinLightBrightness); + indirectLight.specular *= occlusion; + #endif + + return indirectLight; + } + + /* + * Standard stuff End + */ + + half PoiDiffuse(half NdotV, half nDotL, half LdotH) + { + half fd90 = 0.5 + 2 * LdotH * LdotH * SmoothnessToPerceptualRoughness(.5); + // Two schlick fresnel term + half lightScatter = (1 + (fd90 - 1) * Pow5(1 - nDotL)); + half viewScatter = (1 + (fd90 - 1) * Pow5(1 - NdotV)); + + return lightScatter * viewScatter; + } + + float3 ShadeSH9Indirect() + { + return ShadeSH9(half4(0.0, -1.0, 0.0, 1.0)); + } + + float3 ShadeSH9Direct() + { + return ShadeSH9(half4(0.0, 1.0, 0.0, 1.0)); + } + + float3 ShadeSH9Normal(float3 normalDirection) + { + return ShadeSH9(half4(normalDirection, 1.0)); + } + + half3 GetSHLength() + { + half3 x, x1; + x.r = length(unity_SHAr); + x.g = length(unity_SHAg); + x.b = length(unity_SHAb); + x1.r = length(unity_SHBr); + x1.g = length(unity_SHBg); + x1.b = length(unity_SHBb); + return x + x1; + } + + float3 calculateRealisticLighting(float4 colorToLight, float3 normal, float3 viewDir, half3 lightDirection, half attenuation, half ndotl, float3 worldPos, float2 uv) + { + return UNITY_BRDF_PBS(colorToLight, 0, 0, _LightingStandardSmoothness, + normal, viewDir, CreateLight(lightDirection, attenuation, ndotl), CreateIndirectLight(normal, worldPos, viewDir, uv)); + } + + half3 calculateBasePassLighting(float2 uv, float3 lightColor, half nDotL, half attenuation, half3 normal, half3 viewDir, half3 lightDirection, float3 worldPos) + { + half3 finalLighting = 0; + UNITY_BRANCH + if (_LightingType == 0 || _LightingType == 1) + { + float AOMap = 1; + float DirectAO = 1; + float IndirectAO = 1; + #ifndef OUTLINE + AOMap = tex2D(_LightingAOTex, TRANSFORM_TEX(uv, _LightingAOTex)); + DirectAO = lerp(1, AOMap, _AOStrength); + IndirectAO = lerp(1, AOMap, _AoIndirectStrength); + #endif + + half3 grayscale_vector = float3(.33333, .33333, .33333); + half3 ShadeSH9Plus = GetSHLength(); + half3 ShadeSH9Minus = ShadeSH9(float4(0, 0, 0, 1)); + half3 directLighting = saturate(lerp(ShadeSH9Plus, lightColor, 1 - _LightingIndirectContribution)); + half3 indirectLighting = saturate(ShadeSH9Minus) * IndirectAO; + + half4 shadowStrength = 1; + #ifndef OUTLINE + shadowStrength = tex2D(_LightingShadowMask, TRANSFORM_TEX(uv, _LightingShadowMask)); + shadowStrength *= _ShadowStrength; + #else + shadowStrength = _OutlineShadowStrength; + #endif + + float bw_lightColor = dot(lightColor, grayscale_vector); + float bw_directLighting = (((nDotL * 0.5 + 0.5) * bw_lightColor * lerp(1, attenuation, _AttenuationMultiplier)) + dot(ShadeSH9Normal(normal), grayscale_vector)); + float bw_bottomIndirectLighting = dot(ShadeSH9Minus, grayscale_vector); + float bw_topIndirectLighting = dot(ShadeSH9Plus, grayscale_vector); + float lightDifference = ((bw_topIndirectLighting + bw_lightColor) - bw_bottomIndirectLighting); + float lightMap = smoothstep(0, lightDifference, bw_directLighting - bw_bottomIndirectLighting) * DirectAO; + float3 rampedLightMap = lerp(1, UNITY_SAMPLE_TEX2D(_ToonRamp, lightMap + _ShadowOffset), shadowStrength.r); + + UNITY_BRANCH + if(_LightingType == 0) + { + finalLighting = lerp(indirectLighting, directLighting, rampedLightMap); + } + UNITY_BRANCH + if(_LightingType == 1) + { + finalLighting = rampedLightMap * directLighting; + } + } + return finalLighting; + } + + void applyFurLighting(inout float4 finalColor, float2 uv, half attenuation, half3 normal, half3 viewDir, float3 worldPos) + { + float3 finalLighting = 0; + float3 lightColor = 0; + float3 lightDirection = 0; + + #ifdef FORWARD_BASE_PASS + //lightColor = saturate(_LightColor0.rgb) + saturate(ShadeSH9(normalize(unity_SHAr + unity_SHAg + unity_SHAb))); + float3 magic = saturate(ShadeSH9(normalize(unity_SHAr + unity_SHAg + unity_SHAb))); + float3 normalLight = saturate(_LightColor0.rgb); + lightColor = saturate(magic + normalLight); + #else + #if defined(POINT) || defined(SPOT) + lightColor = _LightColor0.rgb; + #endif + #endif + + #ifdef FORWARD_BASE_PASS + lightDirection = normalize(_WorldSpaceLightPos0 + unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz); + #else + #if defined(POINT) || defined(SPOT) + lightDirection = normalize(_WorldSpaceLightPos0.xyz - i.worldPos); + #endif + #endif + + half nDotL = dot(normal, lightDirection); + + #ifdef FORWARD_BASE_PASS + finalLighting = calculateBasePassLighting(uv, lightColor, nDotL, attenuation, normal, viewDir, lightDirection, worldPos); + #else + #if defined(POINT) || defined(SPOT) + finalLighting = lightColor * attenuation * smoothstep(.5 - _AdditiveSoftness + _AdditiveOffset, .5 + _AdditiveSoftness + _AdditiveOffset, .5 * nDotL + .5); + finalLighting *= _LightingAdditiveIntensity; + #endif + #endif + + #ifdef FORWARD_BASE_PASS + UNITY_BRANCH + if (_LightingType == 2) + { + finalColor.rgb = calculateRealisticLighting(finalColor, normal, viewDir, lightDirection, attenuation, nDotL, worldPos, uv); + } + else + { + finalColor.rgb *= max(finalLighting, _LightingMinLightBrightness); + } + #else + finalColor.rgb *= max(finalLighting, _LightingMinLightBrightness); + #endif + } +#endif
\ No newline at end of file |