Documentation

Rendering Pipeline

Π’ этом Ρ€Π°Π·Π΄Π΅Π»Π΅ описываСтся графичСский ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ Wudgine, основанный Π½Π° Vulkan.

ΠžΠ±Π·ΠΎΡ€

Wudgine ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ соврСмСнный графичСский ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ Π½Π° основС Vulkan, ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉ Π²Ρ‹ΡΠΎΠΊΡƒΡŽ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΈ Π³ΠΈΠ±ΠΊΠΎΡΡ‚ΡŒ. ΠšΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³Π° состоит ΠΈΠ· Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… этапов, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ аспСкт Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ.

Π­Ρ‚Π°ΠΏΡ‹ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π°

Π‘Π±ΠΎΡ€ Π³Π΅ΠΎΠΌΠ΅Ρ‚Ρ€ΠΈΠΈ

Π‘Π±ΠΎΡ€ всСх Π²ΠΈΠ΄ΠΈΠΌΡ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π² сцСнС ΠΈ ΠΈΡ… Π³Π΅ΠΎΠΌΠ΅Ρ‚Ρ€ΠΈΠΈ

Π‘ΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²ΠΊΠ° ΠΈ Π³Ρ€ΡƒΠΏΠΏΠΈΡ€ΠΎΠ²ΠΊΠ°

Π‘ΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²ΠΊΠ° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΏΠΎ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Π°ΠΌ ΠΈ состояниям для ΠΌΠΈΠ½ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ состояний

Π Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³ Ρ‚Π΅Π½Π΅ΠΉ

ГСнСрация ΠΊΠ°Ρ€Ρ‚ Ρ‚Π΅Π½Π΅ΠΉ для источников свСта

ГСомСтричСский ΠΏΡ€ΠΎΡ…ΠΎΠ΄

Π Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³ Π³Π΅ΠΎΠΌΠ΅Ρ‚Ρ€ΠΈΠΈ ΠΈ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΎΠ² Π² G-Π±ΡƒΡ„Π΅Ρ€ (позиция, Π½ΠΎΡ€ΠΌΠ°Π»ΠΈ, альбСдо, ΡˆΠ΅Ρ€ΠΎΡ…ΠΎΠ²Π°Ρ‚ΠΎΡΡ‚ΡŒ ΠΈ Ρ‚.Π΄.)

ΠžΡΠ²Π΅Ρ‰Π΅Π½ΠΈΠ΅

РасчСт освСщСния с использованиСм Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ· G-Π±ΡƒΡ„Π΅Ρ€Π°

ΠŸΠΎΡΡ‚ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°

ΠŸΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ эффСктов постобработки (bloom, Ρ‚ΠΎΠ½Π°Π»ΡŒΠ½Π°Ρ компрСссия, цвСтокоррСкция ΠΈ Ρ‚.Π΄.)

Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡ

Π Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ интСрфСйса ΠΏΠΎΠ²Π΅Ρ€Ρ… сцСны

Π’Ρ‹Π²ΠΎΠ΄ Π½Π° экран

Π’Ρ‹Π²ΠΎΠ΄ Ρ„ΠΈΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ изобраТСния Π½Π° экран

ΠžΡ‚Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³

Wudgine ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ‚Π΅Ρ…Π½ΠΈΠΊΡƒ ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³Π° (Deferred Rendering) для эффСктивной ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ большого количСства источников свСта:

// ΠŸΡ€ΠΈΠΌΠ΅Ρ€ настройки ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³Π°
RenderingPipeline pipeline;

// Настройка G-Π±ΡƒΡ„Π΅Ρ€Π°
GBufferConfig gbufferConfig;
gbufferConfig.addRenderTarget(RenderTargetFormat::RGBA16F);  // ΠŸΠΎΠ·ΠΈΡ†ΠΈΡ
gbufferConfig.addRenderTarget(RenderTargetFormat::RGBA16F);  // Нормали
gbufferConfig.addRenderTarget(RenderTargetFormat::RGBA8);    // АльбСдо
gbufferConfig.addRenderTarget(RenderTargetFormat::RGBA8);    // PBR ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹
gbufferConfig.setDepthStencilFormat(DepthStencilFormat::D24S8);

pipeline.setGBufferConfig(gbufferConfig);

// Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΡ…ΠΎΠ΄ΠΎΠ² Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³Π°
pipeline.addPass<ShadowPass>();
pipeline.addPass<GeometryPass>();
pipeline.addPass<LightingPass>();
pipeline.addPass<SkyboxPass>();
pipeline.addPass<TransparencyPass>();
pipeline.addPass<PostProcessPass>();
pipeline.addPass<UIPass>();

// Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π°
pipeline.initialize();

ЀизичСски ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹ΠΉ Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³ (PBR)

Wudgine ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ физичСски ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹ΠΉ Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³ для рСалистичного отобраТСния ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΎΠ²:

АльбСдо

Π‘Π°Π·ΠΎΠ²Ρ‹ΠΉ Ρ†Π²Π΅Ρ‚ повСрхности

ΠœΠ΅Ρ‚Π°Π»Π»ΠΈΡ‡Π½ΠΎΡΡ‚ΡŒ

ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅Ρ‚, являСтся Π»ΠΈ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ ΠΌΠ΅Ρ‚Π°Π»Π»ΠΎΠΌ ΠΈΠ»ΠΈ диэлСктриком

Π¨Π΅Ρ€ΠΎΡ…ΠΎΠ²Π°Ρ‚ΠΎΡΡ‚ΡŒ

ΠœΠΈΠΊΡ€ΠΎΡΠΊΠΎΠΏΠΈΡ‡Π΅ΡΠΊΠΈΠ΅ нСровности повСрхности

Нормали

ДСтализация повСрхности Π±Π΅Π· увСличСния ΠΏΠΎΠ»ΠΈΠ³ΠΎΠ½ΠΎΠ²

Эмиссия

БамосвСчСниС повСрхности

Окклюзия

Π—Π°Ρ‚Π΅Π½Π΅Π½ΠΈΠ΅ Π² углублСниях ΠΈ щСлях

// ΠŸΡ€ΠΈΠΌΠ΅Ρ€ создания PBR ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Π°
Material material;
material.setAlbedoTexture("assets/textures/metal/albedo.png");
material.setNormalTexture("assets/textures/metal/normal.png");
material.setMetallicTexture("assets/textures/metal/metallic.png");
material.setRoughnessTexture("assets/textures/metal/roughness.png");
material.setAoTexture("assets/textures/metal/ao.png");

// Установка ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Π°
material.setAlbedoFactor(Vector3(1.0f, 1.0f, 1.0f));
material.setMetallicFactor(1.0f);
material.setRoughnessFactor(0.5f);

ΠžΡΠ²Π΅Ρ‰Π΅Π½ΠΈΠ΅

Wudgine ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ источников свСта:

// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Π½ΠΎΠ³ΠΎ свСта
Entity lightEntity = world.createEntity();
auto& transform = lightEntity.addComponent<Transform>();
transform.setRotation(Quaternion::fromEulerAngles(-45.0f, 30.0f, 0.0f));

auto& directionalLight = lightEntity.addComponent<DirectionalLight>();
directionalLight.setColor(Vector3(1.0f, 0.95f, 0.9f));
directionalLight.setIntensity(5.0f);
directionalLight.setCastShadows(true);
directionalLight.setShadowResolution(2048);

ΠŸΠΎΡΡ‚ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°

Wudgine прСдоставляСт ΡˆΠΈΡ€ΠΎΠΊΠΈΠΉ Π½Π°Π±ΠΎΡ€ эффСктов постобработки:

Bloom

Π‘Π²Π΅Ρ‡Π΅Π½ΠΈΠ΅ ярких областСй изобраТСния

Вональная компрСссия

ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ HDR Π² LDR с сохранСниСм Π΄Π΅Ρ‚Π°Π»Π΅ΠΉ

ЦвСтокоррСкция

Настройка Ρ†Π²Π΅Ρ‚ΠΎΠ² ΠΈ контраста изобраТСния

Π“Π»ΡƒΠ±ΠΈΠ½Π° рСзкости

Π Π°Π·ΠΌΡ‹Ρ‚ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π²Π½Π΅ фокуса

Π Π°Π·ΠΌΡ‹Ρ‚ΠΈΠ΅ Π² Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠΈ

Π­Ρ„Ρ„Π΅ΠΊΡ‚ размытия ΠΏΡ€ΠΈ быстром Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠΈ

SSAO

Π—Π°Ρ‚Π΅Π½Π΅Π½ΠΈΠ΅ Π² углублСниях ΠΈ щСлях

// ΠŸΡ€ΠΈΠΌΠ΅Ρ€ настройки постобработки
PostProcessSettings settings;

// Bloom
settings.bloom.enabled = true;
settings.bloom.threshold = 1.0f;
settings.bloom.intensity = 0.5f;

// Вональная компрСссия
settings.tonemap.enabled = true;
settings.tonemap.operator = TonemapOperator::ACES;
settings.tonemap.exposure = 1.0f;

// ЦвСтокоррСкция
settings.colorGrading.enabled = true;
settings.colorGrading.contrast = 1.1f;
settings.colorGrading.saturation = 1.05f;
settings.colorGrading.gamma = Vector3(1.0f, 1.0f, 1.0f);
settings.colorGrading.lutTexture = "assets/textures/lut/cinematic.png";

// ΠŸΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ настроСк
renderer.setPostProcessSettings(settings);

ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ

Wudgine ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ‚Π΅Ρ…Π½ΠΈΠΊΠΈ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³Π°:

  • ΠžΡ‚ΡΠ΅Ρ‡Π΅Π½ΠΈΠ΅ Π½Π΅Π²ΠΈΠ΄ΠΈΠΌΡ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²: Hierarchical Z-Buffer, Occlusion Culling
  • Π£Ρ€ΠΎΠ²Π½ΠΈ Π΄Π΅Ρ‚Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ (LOD): автоматичСскоС сниТСниС Π΄Π΅Ρ‚Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²
  • Π˜Π½ΡΡ‚Π°Π½ΡΠΈΠ½Π³: эффСктивный Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³ мноТСства ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²
  • ΠœΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½Π°Ρ ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ° ΠΊΠΎΠΌΠ°Π½Π΄: распараллСливаниС ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠΈ ΠΊΠΎΠΌΠ°Π½Π΄ Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³Π°
  • АсинхронныС вычислСния: использованиС compute shaders для ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹Ρ… вычислСний
// ΠŸΡ€ΠΈΠΌΠ΅Ρ€ настройки LOD для ΠΌΠΎΠ΄Π΅Π»ΠΈ
Model model = resourceManager.loadModel("assets/models/tree.fbx");
model.setLodLevels({
    { 0.0f, "assets/models/tree_lod0.fbx" },
    { 10.0f, "assets/models/tree_lod1.fbx" },
    { 30.0f, "assets/models/tree_lod2.fbx" },
    { 100.0f, "assets/models/tree_lod3.fbx" }
});

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ шаги

Π’Π΅ΠΏΠ΅Ρ€ΡŒ, ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ ознакомились с ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ΠΎΠΌ Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³Π° Wudgine, Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌ:

ΠœΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Ρ‹ ΠΈ ΡˆΠ΅ΠΉΠ΄Π΅Ρ€Ρ‹

Π˜Π·ΡƒΡ‡ΠΈΡ‚Π΅ систСму ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΎΠ² ΠΈ ΡˆΠ΅ΠΉΠ΄Π΅Ρ€ΠΎΠ² Wudgine.

ΠžΡΠ²Π΅Ρ‰Π΅Π½ΠΈΠ΅ ΠΈ Ρ‚Π΅Π½ΠΈ

ΠŸΠΎΠ·Π½Π°ΠΊΠΎΠΌΡŒΡ‚Π΅ΡΡŒ с систСмой освСщСния ΠΈ Ρ‚Π΅Π½Π΅ΠΉ.

Wudgine β€’ Β© 2025