「Dev:2.8/Source/Viewport/EngineAPI」の版間の差分
(→Engine API) |
細 (1版 をインポートしました) |
(相違点なし)
|
2018年6月29日 (金) 06:21時点における最新版
目次
Engine API
This API aims to provide a simple way to create a whole Opengl/Vulkan rendering pipeline inside Blender. The Engine is in charge of rendering to a buffer that will be composited with all Blender specific Overlays on top of it.
Drawing Pipeline
The viewport drawing function would look like this (pseudo C code):
// This function pretty much dispatch object lists to passes
void draw_viewport(RenderEngine *re, View3D *v3d){
// Setup Color and Depth buffer (always)
// Create optional Framebuffers needed by the render engine
// Store them in View3D
setup_buffers(re, v3d);
if (use_probes)
update_probes(re);
if (use_shadows)
update_shadows(re);
if (is_realtime_engine) {
re->type->view_realtime(); // <- here we plug our render pipeline
}
else {
re->type->view_draw();
}
// Draw wire for objects that needs it
wire_pass();
// Draw anything Mode-related
switch(mode){
case OBJECT:
object_pass();
case EDIT:
edit_pass();
...
}
region_info();
}
It's pretty straight forward. What we will expose to Render engines is the view_realtime() function. This function will have to make draw calls to fill the color buffers that will be composited with the rest of the passes.
Engine API
In short what a RenderEngine do is :
- Define glsl shaders
- Define needed screen buffers
- Create a view_realtime method that renders a frame to the viewport
- Create a render_ogl method that outputs a frame as final render
In order to support a large range of techniques, the API must allow us to :
- Draw Geometry in batches with different states
- Create our own utility Shaders
- Get Shader from Materials Nodes
- Bind framebuffers
To achieve this, we propose the following DRW module which is a wrapper of all blender's GPU modules. It will be fairly high level and concise. Preferably all of what the engine can do is in this DRW module. It will obviously be extended and adjusted as the engines development progresses.
// DRW_engines.h
struct DRWBatch{
DRWBatch *next, *prev; // Linked list
GPUGeometry *geometry; // List with all objects and transform
GPUShader *shader; // Shader to bind
GPUInterface *interface; // Uniforms values
};
// Create custom shader to store in RenderEngineType
GPUShader *DRW_shader_create(char *vs_glsl, char *gs_glsl, char *fs_glsl);
// Main draw function everything else is shortcut functions
// Draw a batch by switching the less resources possible
// flags for things like backfacecull, depth test...
static void DRW_draw_batch(DRWBatch *batch, int flags, ...);
// Draw batches in order to avoid state changes
void DRW_draw_batch_list(ListBase *blist);
void DRW_draw_fullscreen(GPUShader *shader, GPUInterface *interface);
void DRW_draw_depth(DRWBatch *batch);
// Frame buffer operations (for deffered rendering or other effects (DOF))
void DRW_bind_framebuffer(GPUFramebuffer *fb);
void DRW_unbind_framebuffer(GPUFramebuffer *fb);
// Shortcut functions to draw background
void DRW_background_world(Scene *scene);
void DRW_background_default();
// Shortcut function to batch surfaces by material (can be reused by engines that use materials)
ListBase *DRW_create_material_batches(ListBase *ob);
// RE_engine.h
struct RenderEngineType {
...
void (*render_realtime)(struct RenderEngine *engine, struct Scene *scene);
void (*view_realtime)(struct RenderEngine *engine, const struct bContext *context);
ListBase *gpushaders; // Allocated GPUShaders to draw with
ListBase *gpufbdescs; // Describe each FBO to generate for this RE.
...
}
Ideally each overlay passes (wire/overlays) should be composited on top of the render pass using different buffers. As it may decrease performance and add code complexity we will try to render overlay passes to the same color buffer.
How to expose this API through Python is still under discussion.
Clay Engine
First example using this API is the Clay Engine.
From the user persperctive :
- Not compatible with nodetree (grey nodes)
- Matcap is defined at Material Level with Layer override and (maybe) object override
- Material Panel Reflect this
From the Engine perspective :
- Define matcap property inside RNA
- Define only one shader
- Optimize drawing as much as possible
void view_realtime(RenderEngine *re, ListBase *objs){
ListBase *batches;
DRW_background_default(gradient);
// Depth Prepass performance boost depends on shading complexity and overdraw
// So it might not be needed in all cases
if (ao)
DRW_draw_depth();
// Matcap rendering
if (!re->gpushader) {
DRW_shader_create(matcap_vert_glsl, NULL, matcap_frag_glsl);
}
batches = Batch_by_matcap(objs); // Make Batches
// Draw Meshes
DRW_draw_batch_list(batches);
// Post Processes
DRW_fullscreen(dof_shader);
}
Workbench Engine
- Reuse basically the same API that the Clay Engine is using
- Draw floor plan with drawing command
- Uses Custom Shadows
Eevee Engine
This one is far more complex. What will be required:
- Getting Nodetree Materials (With new PyNode GLSL API)
- Transparency rendering
- Probe rendering
- Lamps Shadows
At this stage, we expect the Engine API to grow big enough to support all sort of fancy rendering this engine will support.