HeavenStudio/Assets/Plugins/UnityURPToonLitShaderExample-master/SimpleURPToonLitOutlineExample_LightingEquation.hlsl
2022-02-15 00:17:53 -05:00

75 lines
3.6 KiB
HLSL

// For more information, visit -> 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
// #pragma once is a safe guard best practice in almost every .hlsl (need Unity2020 or up),
// doing this can make sure your .hlsl's user can include this .hlsl anywhere anytime without producing any multi include conflict
#pragma once
half3 ShadeGI(ToonSurfaceData surfaceData, ToonLightingData lightingData)
{
// hide 3D feeling by ignoring all detail SH (leaving only the constant SH term)
// we just want some average envi indirect color only
half3 averageSH = SampleSH(0);
// can prevent result becomes completely black if lightprobe was not baked
averageSH = max(_IndirectLightMinColor,averageSH);
// occlusion (maximum 50% darken for indirect to prevent result becomes completely black)
half indirectOcclusion = lerp(1, surfaceData.occlusion, 0.5);
return averageSH * indirectOcclusion;
}
// Most important part: lighting equation, edit it according to your needs, write whatever you want here, be creative!
// This function will be used by all direct lights (directional/point/spot)
half3 ShadeSingleLight(ToonSurfaceData surfaceData, ToonLightingData lightingData, Light light, bool isAdditionalLight)
{
half3 N = lightingData.normalWS;
half3 L = light.direction;
half NoL = dot(N,L);
half lightAttenuation = 1;
// light's distance & angle fade for point light & spot light (see GetAdditionalPerObjectLight(...) in Lighting.hlsl)
// Lighting.hlsl -> https://github.com/Unity-Technologies/Graphics/blob/master/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl
half distanceAttenuation = min(4,light.distanceAttenuation); //clamp to prevent light over bright if point/spot light too close to vertex
// N dot L
// simplest 1 line cel shade, you can always replace this line by your own method!
half litOrShadowArea = smoothstep(_CelShadeMidPoint-_CelShadeSoftness,_CelShadeMidPoint+_CelShadeSoftness, NoL);
// occlusion
litOrShadowArea *= surfaceData.occlusion;
// face ignore celshade since it is usually very ugly using NoL method
litOrShadowArea = _IsFace? lerp(0.5,1,litOrShadowArea) : litOrShadowArea;
// light's shadow map
litOrShadowArea *= lerp(1,light.shadowAttenuation,_ReceiveShadowMappingAmount);
half3 litOrShadowColor = lerp(_ShadowMapColor,1, litOrShadowArea);
half3 lightAttenuationRGB = litOrShadowColor * distanceAttenuation;
// saturate() light.color to prevent over bright
// additional light reduce intensity since it is additive
return saturate(light.color) * lightAttenuationRGB * (isAdditionalLight ? 0.25 : 1);
}
half3 ShadeEmission(ToonSurfaceData surfaceData, ToonLightingData lightingData)
{
half3 emissionResult = lerp(surfaceData.emission, surfaceData.emission * surfaceData.albedo, _EmissionMulByBaseColor); // optional mul albedo
return emissionResult;
}
half3 CompositeAllLightResults(half3 indirectResult, half3 mainLightResult, half3 additionalLightSumResult, half3 emissionResult, ToonSurfaceData surfaceData, ToonLightingData lightingData)
{
// [remember you can write anything here, this is just a simple tutorial method]
// here we prevent light over bright,
// while still want to preserve light color's hue
half3 rawLightSum = max(indirectResult, mainLightResult + additionalLightSumResult); // pick the highest between indirect and direct light
return surfaceData.albedo * rawLightSum + emissionResult;
}