Распределение света по сфере находится на самом базовом уровне c, определяемом точечным произведением между нормалью поверхности и вектором к свету. Это называется затенением Ламберта. На языке шейдеров это было бы написано так:
float NdotL = dot(normal, lightDir);
Мы можем включить это в пользовательскую функцию аналогичным образом. Создайте пользовательскую функцию с двумя входными переменными с именами Normal и WorldPos и выходной переменной с именем Shadow. Вставьте в него этот код:
#if SHADERGRAPH_PREVIEW
Shadow = 1 - saturate(dot(float3(0.707, 0.707, 0), Normal));
#else
Light mainLight = GetMainLight();
float lightAmount = saturate(dot(mainLight.direction, Normal));
#ifdef _ADDITIONAL_LIGHTS
uint pixelLightCount = GetAdditionalLightsCount();
for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex)
{
Light light = GetAdditionalLight(lightIndex, WorldPos);
lightAmount += saturate(dot(light.direction, Normal));
}
#endif
Shadow = saturate(1 - lightAmount);
#endif
Эта функция делает то, что она суммирует вклад света от основного источника света и всех дополнительных источников света и возвращает значение, обратное этому. Поскольку скалярное произведение выдает значение от -1 до 1, оно сначала фиксируется в диапазоне [0, 1] с помощью saturate ().
Примечание. То, что вы получаете от этой функции, - это, по сути, градиент, который идет от 0 на конце до 1 в точке, противоположной Солнцу. Возможно, вы захотите каким-то образом переназначить это значение, чтобы получить более четкую границу, например, вы можете умножить его на 100 и зафиксировать в [0, 1], или использовать квадрат root.