Offscreen Rendering (mimoreální rendering) — je technika renderování 3D scény ne na obrazovku, ale do texturového bufferu (FBO — Framebuffer Object), který pak může být použit jako textura. Podle Apple Metal Documentation, 2025 se offscreen rendering používá pro vytváření stínů, odrazů, post-efektů a předzpracování grafiky. Offscreen Rendering umožňuje rozdělení složité scény na průchody (passes) bez ztráty kvality.
Klíčové body
Offscreen Rendering — je metoda vykreslování grafického obsahu do mezipaměti ve video paměti, nikoli do hlavního framebufferu, který se zobrazuje na obrazovce. Výsledek mimoreálního renderování je uložen v textuře nebo renderbufferu.
Hlavním cílem offscreen rendering je víceprůchodové renderování (multi-pass rendering). Složitá scéna je rozdělena do několika průchodů: nejprve se scéna vykreslí do textury (offscreen), poté se tato textura použije jako vstup pro další průchod, a tak dále až do získání výsledného obrazu. Tento přístup umožňuje efekty, které jsou v jednom průchodu nemožné.
Klíčovým mechanismem mimoreálního renderování v OpenGL ES je Framebuffer Object (FBO). FBO je kontejner, ke kterému lze připojit texturové obrázky nebo objekty renderbuffer. Po připojení FBO jsou všechny následující příkazy renderování směrovány k připojené textuře, nikoli na obrazovku.
Offscreen Rendering se realizuje vytvořením samostatného framebuffer objektu, připojením textury nebo renderbufferu k němu, přepnutím kontextu renderování na tento FBO a provedením příkazů kreslení. Po dokončení průchodu se kontext přepne zpátky na hlavní framebuffer.
Proces se skládá ze tří kroků: vytvoření FBO a připojení textury — vykreslení scény do offscreen textury — použití získané textury v dalším průchodu. GL_COLOR_ATTACHMENT0 určuje, do které barevné textury bude vykreslováno.
// Vytvoření FBO pro offscreen rendering (OpenGL ES 3.0)
GLuint fbo, offscreenTex;
glGenFramebuffers(1, &fbo);
glGenTextures(1, &offscreenTex);
glBindTexture(GL_TEXTURE_2D, offscreenTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER),
GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
offscreenTex, 0);
Offscreen Rendering se používá pro široké spektrum grafických efektů. Každá technika vyžaduje jeden nebo více mimoreálních průchodů a určitou konfiguraci FBO.
| Technika | Počet průchodů | Účel |
|---|---|---|
| Shadow Mapping | 2+ | Generování mapy stínů ze zdroje světla |
| Reflection Mapping | 1-2 | Vykreslení odrazů do krychlové mapy |
| Bloom Effect | 3-5 | Záře světlých částí obrazu |
| HDR Rendering | 2 | Ton-mapping pro HDR obrázky |
| Depth Prepass | 1 | Předběžné naplnění depth bufferu |
Základní technika, při které je výsledek renderování uložen do textury pro pozdější použití. Render-to-Texture se používá pro vytváření mini-map, textur dynamických objektů a předběžné vizualizace složitých materiálů.
Složité efekty (HDR, bloom, hloubka ostrosti) vyžadují několik po sobě jdoucích průchodů. Každý průchod vykresluje scénu do offscreen textury, aplikuje filtr a předává výsledek dalšímu průchodu. Tento přístup umožňuje kumulovat efekty bez ztráty kvality výsledného obrazu.
Shadow Mapping — klasický příklad použití offscreen rendering. Stín se vytváří ve dvou průchodech: nejprve se scéna vykreslí z pohledu zdroje světla do depth textury (offscreen), poté se při hlavním renderování každý fragment porovná s touto depth mapou, aby se určilo, zda je ve stínu.
První průchod: kamera se umístí do pozice zdroje světla, scéna se vykreslí do offscreen bufferu, zapisuje se pouze hloubka (depth) do textury. Druhý průchod: hlavní renderování s kontrolou každého fragmentu — pokud je jeho hloubka větší než hodnota v depth mapě, fragment je zastíněn.
// Fragment Shader pro mapování stínů
in vec4 vShadowCoord;
uniform sampler2D uShadowMap;
float calcShadow(vec4 coord) {
vec3 uvw = coord.xyz / coord.w;
float depth = texture(uShadowMap, uvw.xy).r;
return (uvw.z > depth + 0.005) ? 0.3 : 1.0;
}
Offscreen Rendering přidává další průchody GPU, což zvyšuje celkovou výpočetní zátěž a spotřebu energie. V mobilním vývoji je to obzvlášť kritické: každé přepnutí FBO vyžaduje reset pipeline (pipeline flush) a další čas.
Pro mobilní zařízení se doporučuje: používat renderbuffer místo textury, pokud není vyžadováno čtení výsledku (pouze depth průchod); zvolit minimálně nutné rozlišení offscreen textur; spojovat průchody tam, kde je to možné, pomocí MRT (Multiple Render Targets).
Offscreen Rendering na různých platformách se realizuje prostřednictvím vlastních API. Podívejme se na příklady pro OpenGL ES a Apple Metal.
// Nastavení FBO a vykreslení scény do textury
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glViewport(0, 0, texWidth, texHeight);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(offscreenProgram);
glBindVertexArray(sceneVAO);
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT, 0);
// Přepnutí zpět na výchozí framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Metal: offscreen průchod vykreslení do textury
MTLRenderPassDescriptor passDesc = [MTLRenderPassDescriptor renderPassDescriptor];
passDesc.colorAttachments[0].texture = offscreenTexture;
passDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
passDesc.colorAttachments[0].clearColor =
MTLClearColorMake(0.0, 0.0, 0.0, 0.0);
id<MTLCommandBuffer> cmdBuffer = [commandQueue commandBuffer];
id<MTLRenderCommandEncoder> enc =
[cmdBuffer renderCommandEncoderWithDescriptor:passDesc];
[enc drawIndexedPrimitives:MTLPrimitiveTypeTriangle
indexCount:indexCount
indexType:MTLIndexTypeUInt16
indexBuffer:indexBuffer
indexBufferOffset:0];
[enc endEncoding];
Často kladené otázky
Offscreen Rendering je situace, kdy se grafika kreslí ne na obrazovku, ale do neviditelného bufferu (textury). Tento buffer se poté použije jako textura pro jiné efekty. Představte si, že kreslíte na průhlednou fólii, kterou pak překryjete přes výsledný obrázek.
Mimoreální rendering umožňuje vytvářet efekty nemožné v jednom průchodu: stíny (vykreslení z pohledu světla), odrazy, rozmazání, záři (bloom) a HDR tónování. Každý efekt vyžaduje samostatný průchod do offscreen textury.
Ano, každý mimoreální průchod zdvojnásobuje množství práce GPU, protože se scéna znovu vykresluje. Optimalizace zahrnuje snížení rozlišení offscreen textur, použití renderbufferu a spojení průchodů pomocí MRT (Multiple Render Targets).
FBO (Framebuffer Object) je kontejner, ke kterému se připojují textury nebo renderbuffer. Texture umožňuje čtení výsledků renderování (potřebné pro mapování stínů, post-efekty). Renderbuffer je rychlejší, ale jeho obsah nelze použít jako texturu.
Všechna moderní grafická API: OpenGL ES (přes FBO), Apple Metal (přes MTLRenderPassDescriptor), Vulkan (přes VkFramebuffer), Direct3D (přes Render Target View). Koncepčně je mechanismus stejný — vykreslování do textury místo na obrazovku.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také