reckfellENGINE

Освещение 3D: источники, слои и тени

Получить освещённый уровень и реальные тени, проверить область света и отделить визуальные маски от физических.

На этой странице

Запустить освещённый уровень

Нужны C# SDK 1.0.0, net10.0 и уровень .rscene с Entity3D-корнем. Сохраните LightingMaterials.cs из руководства материалов и LightingLab3D.cs ниже. Выполните dotnet build, назначьте LightingLab3D.cs корню и запустите. Внешние ассеты не нужны.

Виден белый куб, синий шар и пол. Key — DirectionalLight3D с включёнными тенями. Point и Spot созданы, но Visible=false: их включают отдельно для сравнения, не складывают все источники сразу.

LightingLab3D.cs
C#
using Reckfell;

public partial class LightingLab3D : Entity3D
{
    public MeshInstance3D Floor { get; private set; } = null!;
    public MeshInstance3D Cube { get; private set; } = null!;
    public MeshInstance3D MetalSphere { get; private set; } = null!;
    public DirectionalLight3D Key { get; private set; } = null!;
    public OmniLight3D Point { get; private set; } = null!;
    public SpotLight3D Spot { get; private set; } = null!;
    public Camera3D Camera { get; private set; } = null!;
    public WorldEnvironment World { get; private set; } = null!;

    public override void _Ready()
    {
        World = new WorldEnvironment { Environment = LightingMaterials.Environment() };
        AddChild(World);
        Floor = new MeshInstance3D
        {
            Mesh = new PlaneMesh { Size = new Vector2(10, 10) },
            MaterialOverride = LightingMaterials.Surface(new Color(0.48f, 0.5f, 0.55f))
        };
        Cube = new MeshInstance3D
        {
            Mesh = new BoxMesh { Size = new Vector3(1.4f, 2, 1.4f) },
            Position = new Vector3(0, 1, 0),
            MaterialOverride = LightingMaterials.Surface(Colors.White)
        };
        MetalSphere = new MeshInstance3D
        {
            Mesh = new SphereMesh { Radius = 0.8f, Height = 1.6f },
            Position = new Vector3(-2.2f, 0.8f, 0),
            MaterialOverride = LightingMaterials.Surface(new Color(0.08f, 0.25f, 1), 0.2f, 0.8f)
        };
        AddChild(Floor); AddChild(Cube); AddChild(MetalSphere);
        Key = new DirectionalLight3D
        {
            RotationDegrees = new Vector3(-50, -25, 0),
            LightColor = Colors.White,
            LightEnergy = 1,
            ShadowEnabled = true
        };
        Point = new OmniLight3D
        {
            Position = new Vector3(0, 3, 1),
            OmniRange = 8,
            LightEnergy = 3,
            Visible = false
        };
        Spot = new SpotLight3D
        {
            Position = new Vector3(0, 4, 3),
            SpotRange = 10,
            SpotAngle = 35,
            LightEnergy = 4,
            Visible = false
        };
        AddChild(Key); AddChild(Point); AddChild(Spot);
        Spot.LookAt(Vector3.Zero);
        Camera = new Camera3D { Current = true, Position = new Vector3(5, 4, 7), Fov = 55 };
        AddChild(Camera);
        Camera.LookAt(new Vector3(0, 0.7f, 0));
    }
}

Направленный свет, блики и реальные тени куба и шара в Compatibility

Кадр текущей локальной сборки 1.0.0, Compatibility/OpenGL, 512×384. Коллизий и контроллера персонажа в этом примере нет.

Выбрать источник

ТипИспользованиеЧто проверить
DirectionalLight3DСолнце или общий направленный светПоворот, дистанцию покрытия теней; позиция не задаёт точку лампы
OmniLight3DЛампа, освещающая вокруг себяПоложение, OmniRange, затухание
SpotLight3DФонарь или прожекторНаправление локальной -Z, SpotRange и SpotAngle
AreaLight3DПротяжённый источникПоддержку конкретного renderer; в Compatibility по исходникам нет его теней и текстурированного area light

Первые три типа проверены в текущем runtime. AreaLight3D здесь не запускается. У Spot после добавления вызывается LookAt(Vector3.Zero), чтобы направить конус к полу, а не полагаться на случайный поворот.

LightEnergy — множитель, а не универсальная «правильная яркость». На результат влияют материал, расстояние, настройки физических единиц и окружение. Если свет не достаёт до объекта, рост энергии не исправляет слишком маленький range или неверный конус.

Изолировать проблему света

После _Ready доступны Key, Point, Spot и World.Environment. Выключите Key.Visible, поставьте AmbientLightEnergy=0 и включите только Point.Visible. Затем верните Point.Visible=false и включите Spot.Visible. Делайте изменения после создания этих объектов; до _Ready свойства ещё не готовы.

При OmniRange=8 Point осветил геометрию, при 0.2 — перестал до неё доставать. Spot осветил поверхность внутри направленного конуса. AmbientLightSource=Color с энергией 1 также осветил уровень без Key, но не создал направленных теней.

LightCullMask сравнивается с визуальными Layers геометрии. Смена маски источника с 1 на 2 исключила объекты, оставшиеся на первом визуальном слое. CollisionLayer/CollisionMask физики к этому не относятся.

Получить тень

Проверьте цепочку целиком:

  1. У источника включён ShadowEnabled, а его тип и режим рендеринга поддерживают нужные тени.
  2. Геометрия находится в области влияния и допустимых визуальных слоях.
  3. У отбрасывающей геометрии CastShadow не Off.
  4. Получатель имеет материал, принимающий нужное освещение/тени, и попадает в кадр.
  5. Дистанция покрытия и качество теневой карты подходят масштабу уровня.

В проверке ShadowEnabled=false убрал тени, а отдельное переключение CastShadow=Off у куба и шара убрало их тени без скрытия мешей. ShadowBias и ShadowNormalBias уменьшают самозатенение, но чрезмерные значения отрывают тень от поверхности и портят тонкие детали. Подбирайте их после масштаба и покрытия, а не вместо них.

Реальная тень источника, AO материала и экранный SSAO — разные эффекты. SSAO добавляет контактное затемнение по видимой глубине, но не заменяет отбрасываемую через весь уровень тень. Запускаемый пример SSAO и glow.

Не спутать свечение с освещением

Emission делает материал ярким. Glow добавляет ореол вокруг ярких пикселей. Ни одно из них само по себе не создаёт прямой Light3D для пола и соседних объектов. Для такой лампы добавьте источник; непрямое освещение и отражения настраиваются отдельно.

Если в редакторе уровень выглядит иначе, сверяйте фактические источники и WorldEnvironment проекта. Этот пример задаёт их явно и не использует редакторский preview как настройку игры.

Диагностика

СимптомПроверка
Чёрный кубМатериал, включённый источник/ambient, LightCullMask и Layers
Point не влияетРасстояние до поверхности и OmniRange
Spot светит мимоПоворот/LookAt, SpotAngle и SpotRange
Объект светится, тени нетShadowEnabled, CastShadow, тип источника и покрытие теней
Тень дрожит или отрываетсяМасштаб, разрешение/покрытие, затем bias
Много источников сильно снижает FPSПрофиль целевого уровня; уменьшить перекрытие, range и количество динамических теней

Проверены базовые источники и направленные тени в Compatibility. Все режимы shadow atlas, физические единицы, GI, экспорт и производительность больших уровней здесь не подтверждаются.

Light3D API

Документация Reckfell EngineНаверх ↑
БЫСТРЫЙ ПЕРЕХОДНачало работыEntity и иерархияC# & .NET 10Сцены и префабы
Руководства и полный API Reckfell K
reckfellENGINE
RECKFELL ACCOUNT

Вход в аккаунт

Войдите в аккаунт Reckfell.

Один аккаунт для всей платформы Reckfell.