Вспомогательный свет без GI
Создать цветную подсветку, ограничить её область и проверить тени на непрозрачной перегородке.
Когда подходит
Ручной вспомогательный свет помогает настроить читаемость тёмной стороны объекта или добавить нужный оттенок. В примере синяя OmniLight3D имитирует художественную подсветку. Цвет задаёт разработчик; он не вычисляется автоматически из цвета соседней стены.
Такой источник остаётся обычным прямым светом со своими range, слоями, затуханием и тенями. При перемещении стен или изменении материалов его настройки не становятся физически правильными автоматически.
Запустить полный пример
Выполните настройку C#. Нужны SDK 1.0.0, net10.0 и Entity3D-корень уровня .rscene. Сохраните два файла ниже, выполните dotnet build и назначьте FillLightLab3D.cs корню. Камера, куб, пол, перегородка и источники создаются кодом.
FillMaterials.cs
using Reckfell;
public static class FillMaterials
{
public static StandardMaterial3D Surface(Color color) => new() { AlbedoColor = color, Roughness = 0.7f };
public static Reckfell.Environment Dark() => new()
{
BackgroundMode = Reckfell.Environment.BGMode.Color,
BackgroundColor = Colors.Black,
AmbientLightSource = Reckfell.Environment.AmbientSource.Color,
AmbientLightColor = Colors.Black, AmbientLightEnergy = 1, AmbientLightSkyContribution = 0,
ReflectedLightSource = Reckfell.Environment.ReflectionSource.Bg
};
}FillLightLab3D.cs
using Reckfell;
public partial class FillLightLab3D : Entity3D
{
public OmniLight3D Fill { get; private set; } = null!;
public override void _Ready()
{
GetViewport().PositionalShadowAtlasSize = 1024;
AddChild(new WorldEnvironment { Environment = FillMaterials.Dark() });
AddChild(new MeshInstance3D
{
Mesh = new PlaneMesh { Size = new Vector2(8, 8) },
MaterialOverride = FillMaterials.Surface(Colors.White)
});
AddChild(new MeshInstance3D
{
Mesh = new BoxMesh { Size = new Vector3(1.4f, 2, 1.4f) }, Position = new Vector3(0, 1, 0),
MaterialOverride = FillMaterials.Surface(Colors.White)
});
AddChild(new MeshInstance3D
{
Mesh = new BoxMesh { Size = new Vector3(0.15f, 3, 4) }, Position = new Vector3(1.2f, 1.5f, 0),
MaterialOverride = FillMaterials.Surface(Colors.White)
});
AddChild(new DirectionalLight3D { RotationDegrees = new Vector3(-45, -20, 0), LightEnergy = 0.5f, ShadowEnabled = true });
Fill = new OmniLight3D
{
Position = new Vector3(2, 1.5f, 0), LightColor = new Color(0.08f, 0.25f, 1),
LightEnergy = 1, OmniRange = 6, ShadowEnabled = false
};
AddChild(Fill);
var camera = new Camera3D { Current = true, Position = new Vector3(-4, 3, 6), Fov = 55 };
AddChild(camera);camera.LookAt(new Vector3(0, 0.8f, 0));
}
}После _Ready доступен Fill. Для первого сравнения задайте Fill.Visible=false; затем true при прежней камере и экспозиции. Делайте это после создания источника, а не до _Ready.
Это реальные кадры текущей локальной сборки 1.0.0 в Compatibility/OpenGL, 512×384. Изменение цветных пикселей отдельно подтверждено в Forward+/Vulkan. Это демонстрация прямой подсветки, а не расчёта GI или производительности.
Ограничить влияние
- Подберите позицию со стороны предполагаемой подсветки; не увеличивайте энергию для исправления неверного положения.
- Ограничьте OmniRange пространством, где эффект нужен. В проверке уменьшение range до 0.1 убрало цветной вклад на удалённых поверхностях.
- Подберите LightEnergy и LightColor после базового освещения. Сильный синий цвет здесь нужен для наглядного сравнения.
- LightCullMask относится к визуальным Layers; физические CollisionLayer/CollisionMask не ограничивают свет.
Для отдельного игрового объекта можно использовать согласованные визуальные слои. Но маски — ручное управление видимостью света, а не восстановление физического пути отражений.
Проверить утечку через стену
Fill расположен справа от непрозрачной перегородки. При ShadowEnabled=false он освещает и часть поверхностей слева: сама видимая стена не блокирует этот свет автоматически.
Включите Fill.ShadowEnabled=true. Пример заранее задаёт PositionalShadowAtlasSize=1024 у своего viewport. Это общий atlas для позиционных теней; он не заменяет флаг источника. У геометрии также должен быть допустимый CastShadow.
На обоих проверенных renderer включение теней уменьшило синий вклад за непрозрачной геометрией. Это не доказывает отсутствие всех световых утечек: проверяйте тонкие поверхности, bias, масштаб и область действия. Для мягкой художественной подсветки динамические тени могут оказаться лишними по стоимости; решение принимайте по кадру и профилю проекта.
Диагностика
| Проблема | Что проверить |
|---|---|
| Цвет не появился | Fill.Visible, расстояние/range, LightCullMask и материал |
| Подсветка проходит через стену | ShadowEnabled, atlas viewport, CastShadow и геометрию |
| После перестройки уровня свет не подходит | Позицию и область ручного источника нужно пересмотреть |
| Всё стало плоским и пересвеченным | Снизить энергию и отделить подсветку от основного света |
| Ожидается автоматический цветной bounce | Нужен выбранный GI-метод и его данные, а не ручной Omni |