-
-
Notifications
You must be signed in to change notification settings - Fork 78
3DOverview
NPL/ParaEngine provides a rich set of graphical API and libraries to create a sophisticated interactive 3D application. ParaEngine used to be a full-featured computer game engine, it is now built-in with NPLRuntime. ParaEngine implementation is C/C++ based. All of its API can be accessed via NPL scripts.
The rendering pipeline is hard-coded into CSceneObject
class. The shader code of all 3d objects is predefined, which allows us to switch between fixed-function, programmable or deferred shading pipeline at runtime. However, one can also specify custom shaders at per object level, but it is up to the programmer to change those shaders when user switch say from deferred shading to a standard programmable pipeline.
The main render function begins at CParaEngineApp::Render()
, which calls the viewport manager's render
function.
A viewport manager generally have a single viewport, but in case of stereo display, it may have two or more.
m_pViewportManager->UpdateViewport(m_d3dpp.BackBufferWidth, m_d3dpp.BackBufferHeight);
m_pViewportManager->Render(fElapsedTime, PIPELINE_3D_SCENE);
m_pViewportManager->Render(fElapsedTime, PIPELINE_UI);
m_pViewportManager->Render(fElapsedTime, PIPELINE_POST_UI_3D_SCENE);
It will render 3d scene first, followed by UI objects and then some post rendering stuffs.
All viewports share the same CSceneObject
class and CGUIRoot
class, and calls CSceneObject::AdvanceScene
and CGUIRoot::AdvanceGUI
respectively.
CSceneObject
is the main singleton class for managing all 3d objects in the world.
The main 3d rendering pipeline is hard-coded in CSceneObject::AdvanceScene
, roughly as below.
- draw mini scene graphs with their own render targets
-
PrepareRender()
and generatesceneState
containing objects that should be rendered in this frame.- we will sort objects into different queues for different rendering orders according to a number of criteria, like distance to the camera, whether it is transparent, object's shader (materials), size of the object, etc.
- objects with their own render targets
- RenderSelection(RENDER_OWNER_DRAW);
- render all reflection map in the scene.
- pOcean->UpdateReflectionTexture(sceneState);
-
RenderShadowMap();
the global shadow map - BlockWorldClient::GetInstance()->PrepareAllRenderTargets(); prepare render target first for deferred shading if fancy graphics is enabled in block world.
- Draw Opache objects
- RenderSelection(RENDER_GLOBAL_TERRAIN);
- m_pBlockWorldClient->Render(BlockRenderPass_Opaque); draw opaque blocks
- m_pBlockWorldClient->Render(BlockRenderPass_AlphaTest);
- RenderSelection(RENDER_MESH_FRONT_TO_BACK); big static meshes
- RenderSelection(RENDER_MESH_BACK_TO_FRONT); small static meshes
- RenderSelection(RENDER_SPRITES);
- RenderSelection(RENDER_CHARACTERS); all animated characters
- RenderSelection(RENDER_SELECTION);
- RenderSelection(RENDER_SKY_BOX);
- RenderSelection(RENDER_MISSILES);
- m_pBlockWorldClient->DoPostRenderingProcessing(BlockRenderPass_Opaque); deferred shading for opaque objects so far
- Draw Transparent objects
- m_pBlockWorldClient->Render(BlockRenderPass_ReflectedWater);
- m_pBatchedElementDraw->DrawBatchedParticles(true);
- m_pBlockWorldClient->Render(BlockRenderPass_AlphaBlended); blocks with alpha blending texture
- RenderSelection(RENDER_TRANSPARENT_CHARACTERS);
- m_pBlockWorldClient->DoPostRenderingProcessing(BlockRenderPass_AlphaBlended); deferred shading for transparent objects
- RenderHeadOnDisplay(0);
- pOcean->Render(&sceneState);
- RenderSelection(RENDER_MESH_TRANSPARENT);
- RenderSelection(RENDER_TRANSLUCENT_FACE_GROUPS);
- RenderSelection(RENDER_POST_RENDER_LIST);
- RenderSelection(RENDER_PARTICLES, dTimeDelta);
- Call post processing callbacks in the NPL
- Draw debug objects
- GetPhysicsInterface()->DebugDrawWorld();
- RenderSelection(RENDER_BOUNDINGBOX);
- RenderSelection(RENDER_PORTAL_SYSTEM);
- RenderHeadOnDisplay(1); overlay objects
We use a hard-coded pipeline with predefined shaders (materials) for a given type of objects. Right now, we do not have an easy way to change those shaders or customize materials without changing the core engine. This is because managing shaders for all platforms (android/ios/pc with DirectX/OpenGL with/without deferred shading) is a tough task and we will handle this task for you to create a general-purpose
rendering pipeline that ensures everything can be rendered correctly on all platforms with or without fancy graphics.
However, we do allow developers to overwrite all of our predefined shaders via NPL scripts, adding post rendering shaders or specify a custom shader for a scene object. The developers, however, need to provide several versions of the custom shader in order to support all platforms and all graphics levels. Please note, the fixed function pipeline is hard-coded in C++ and cannot be altered. See following sections for details.
- System shaders for standard programmable pipeline is at shaders
- please note some OpenGL shaders are cross-compiled from DirectX' fx files.
- System shaders for deferred rendering is at script/apps/Aries/Creator/Game/Shaders
Here (search for render_tech) is the list of all predefined id for these system shaders, replacing the id(handle) with your own shader file will replace the actual shader used.
The following code will replace all character rendering shaders to a custom shader at "script/ide/Effect/Shaders/frozen.fxo". *.fxo
is compiled version of *.fx
file.
NPL.load("(gl)script/ide/event_mapping.lua");
local my_effect = ParaAsset.LoadEffectFile("frozen", "script/ide/Effect/Shaders/frozen.fxo");
local params = my_effect:GetParamBlock();
params:SetTexture(1,"Texture/Aries/ShaderResource/frozenNoise.dds");
my_effect:SetHandle(render_tech.TECH_CHARACTER);
script/ide/Effect/frozenEffect.lua is a custom effect that one can apply to any ParaObject via NPL.
Please note, user defined effect handle should use id larger than 1000. Id less than 1000 is reserved for system use.
local my_effectHandle = 1002;
my_paraobject:SetField("render_tech", my_effectHandle);
see script/ide/Effect for more examples
see script/ide/PostProcessor.lua for examples.
see script/apps/Aries/Creator/Game/Effects/ShaderManager.lua for a more advanced example in paracraft. One can write a MOD that registered a new command for a new shader effect like this CommandEffect.lua
Download Paracraft | ParacraftSDK | copyright by tatfook 2016 | upload image