Page MenuHome

Engineering Plan for EEVEE Renderpasses in 3D Viewport
Closed, ResolvedPublicDESIGN

Authored By
Jeroen Bakker (jbakker)
Nov 6 2019, 1:46 PM
Tokens
"Love" token, awarded by ofuscado."Love" token, awarded by filibis."Like" token, awarded by Alrob."Love" token, awarded by Brandon777."Love" token, awarded by ogierm."Cup of Joe" token, awarded by fclem."Love" token, awarded by amonpaike.

Description

This task is for looking at the details how to get the EEVEE Renderpasses in the 3D Viewport.

Current Situation

Currently the EEVEE renderpasses are post-processed on the CPU.

The next post-processing happens:
a. EEVEE stores the sample data in accumulated buffers. By downloading them to CPU it saves some GPU memory what is important during rendering. On the CPU the accumulated buffers are divided by the number of samples. This is the case for SCE_PASS_SUBSURFACE_COLOR, SCE_PASS_SUBSURFACE_DIRECT, SCE_PASS_MIST
b. EEVEE stores normals encoded. the post processing will decode the data. doing this on the CPU reduces the needed memory on the GPU. SCE_PASS_NORMAL. This only happens for the first sample as the first sample contains the center pixel normal
c. In OpenGL the data in the depth buffer is stored between 0.0 and 1.0. 0.0 is the near plane and 1.0 is the far plane. On the CPU the data is converted back in the dimension between [near..far] based on the active viewport settings. SCE_PASS_Z. This only happens for the first sample as the first sample contains the center pixel depth
d. For SCE_PASS_AO the accumulated ambient occlusion is divided by the number of samples and converted to a gradient-color.
e. no post processing takes place for the combined pass.

This information is extracted from eevee_render.c

Out of scope

  • The SCE_PASS_Z is not relevant as it won't display information that is useful for the user. Users can use the normalized SCE_PASS_MIST as this pass is more friendly to display to the user. This is similar to what we have done for Cycles.
  • Adding new passes to EEVEE. This design will only make existing passes available in the viewport. All future created passes must also be made available in the viewport (of course when it makes sense and is feasible)

Approach

  1. Move current post processing to a GLSL shader.
  2. Enable selection of renderpasses in the 3d viewport

Modification

Modifications seems to be straight forward. In the end some detail may change due to optimizations but the overall impact is described below.

makesdna/DNA_view3d_types.h

add the active renderpass to shown to the View3DShading struct.
There are two options. One for the OB_MATERIAL mode and one for the OB_RENDER mode. by default the render pass is set to SCE_PASS_COMBINED

makesrna/intern/rna_space.c

Add renderpass option to the View3DShading rna type based on the active draw type the correct DNA will be selected.

draw/engines/eevee/eevee_renderpasses.c

Currently the renderpasses are implemented in eevee_render.c. as we also want to use the renderpasses in eevee_engine.c we move the implementation to a new compilation unit eevee_renderpasses.c.

If we are rendering in the viewport we can skip the creation of a temp buffer and draw directly to the default_fb. When doing image rendering we can create a single framebuffer (RGBAf16?) to keep the processed data for downloading. After downloading the texture can be reused for other renderpasses. Of course the combined renderpass uses the default_fb directly.

draw/engines/eevee/eevee_engine.c

Add logic when a renderpass is selected (other than combined) to postprocess the buffer with the default_fb as target.

When rendering the normal pass we can disable TAA as the first sample decides the result.

Note that the result pass can now have value, color or raw data. The correct color management option needs to be passed to DRW_transform_to_display. In normal cases the rule should be that value and raw data should be sent to the display without any color management applied. But the guideline should be that the viewport should look the same as when the render pass is shown in the Image editor.

draw/engines/eevee/eevee_render.c

in the methods eevee_render_result_* we use the eevee_renderpasses to prepare a result GPU offscreen texture containing the data that maps directly to an RenderResult.

It is not allowed to do any post processing here.

draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl

Screen space fragment shader to convert 'raw' renderpass data to a final render result or a displayable result that can be displayed in the 3d viewport.

Using uniforms we will switch between behaviors

  • convert an accumulated buffer to a color by dividing the accumulated color by a sample number.
  • convert an accumulated mist to a value by dividing the accumulated mist by a sample number.
  • convert an OpenGL depth buffer to a view depth.
  • decode an eevee encoded normal by calling the bsdf_common_lib.glsl#normal_decode
  • convert the ao accum buffer to a gradient value.

Event Timeline

Jeroen Bakker (jbakker) renamed this task from Create Engineering Plan for EEVEE Renderpasses in 3D Viewport to Engineering Plan for EEVEE Renderpasses in 3D Viewport.Nov 6 2019, 4:05 PM

Sounds good. For simplicity I would only create one post process shader and use uniforms to select the right operation. The branches are likely to be small enough so it won't make a difference.

Concerning the texture bitdepth, I remember having to use 32bits/channel because of float precision of the accumulation, but this might be caused by the way we do the accumulation in normal viewport rendering (we keep the target intensity of the lights in the texture instead of the accumulated value).
If you accumulate then divide for display, it might be ok to use 16bits/channels (to test).

I want to ask not only for actual render passes in the viewport, also we need artist useful passes, for example roughness.

For an artist, have access to see the final roughness/specular/metallic/... value passes is really important, first to keep the style with other assets of our project. And in the case that we want to paint the texture, a way to see the final outputs that our material will have, like we can do in the viewport of other programs like Substance or Mari. Without do workarounds like reconnect roughness input to the base color and put the shading in "texture/flat"

Yes we are aware of many things that can be added, that is not part of this patch. This change will enable the possibility to use render passes it will not introduce new ones.

Please note that it is not allowed to add screen shots of other software here!

Jeroen Bakker (jbakker) changed the task status from Unknown Status to Resolved.Dec 5 2019, 8:23 AM