General notes

All results have been acquired on a pretty old setup(i7 3770+GTX 770) running on DirectX 11 with medium quality and using RenderDoc and Nsight.
The game runs on Re Engine, a successor of MT Framework - the previous generation engine from Capcom R&D. Aside from RE2 it is used in DMC5 and RE7:Biohazard.
Frame breakdowns are among those things I really like on the internet.

I couldn’t find any material on RE Engine on the internet, so everything here is an (hopefully)educated guess. I’m covering about 90% of the frame structure here and just the general gist of the algorithms. It’s really difficult to cover more as it would require more experience than I have and time to reverse engineer the shaders.

As always, check out cool links at the bottom and don’t forget to reach out if you find any mistakes or have suggestions. I really like learning from the feedback.

Table of content

Frame Structure

Particle/Fluid sim

Among other things ripple textures are being generated(Example from a different frame).
particle sim 0 particle sim 0

Ripples are used for water rendering which is not present in this frame.

Some of the results are being copied into a staging buffer which suggests that results may be used by CPU.

Light list calculation

This pass generates visible light list by testing light frustums against the view frustum. The result is visible light list and some sort of 3d table that maps view space positions to the corresponding lights.

Also per light visible instance lists are computed for later use in shadow map update.

White point

This pass builds a histogram of brightness based on the previous hdr image and metering table. Then determines the whitepoint based on that data.
metering table prevhdr

Determine occluders

Occluders’ bounding boxes are being tested against view frustum in a compute shader and an indirect argument buffer is filled.

Occlusion culling

Occluders are rendered into a small resolution depth buffer and then bounding boxes are being tested against this depth buffer.

Sample 0 Sample 1 Sample 2 Sample 3

Used depth buffer is 4x multisampled. Probably to compensate for low res.

occlusion culling 0

Looks like view oriented bounding boxes.
occlusion culling 0

Example of occlusion test(From a different frame). Surviving pixels(green) write flags(1 for example) to the visibility buffer with per instance slots.

store_raw RWDrawIndirectArguments.x, v1.x, l(1)

Accumulate indirect arguments

Almost every world space geometry object is being rendered with an indirect drawcall. Nsight profiler shows calls to NvAPI_D3D11_MultiDrawIndexedInstancedIndirect. Read [1] and [2] about its usage. RenderDoc blocks MultiDraw extension so instead in the EventBrowser these expand into a lot of DrawIndexedInstancedIndirect where some of them are empty.
The job of this pass is to aggregate visibility masks from the previous pass and generate an argument buffer.

Depth prepass

Nothing fancy. Subset of the scene with major occluders.
depth prepass

G-Buffer pass Geometry+Decals

RT0.rgb - emission RT1.rgb - albedo RT1.a - metalness RT2.rg - normal RT2.b - roughness RT2.a - misc RT3.r - baked AO RT3.gb - View space velocity RT3.a - SSS coefficient Depth bufffer Stencil buffer

Output:

  • RT0 - r11g11b10 emissive
  • RT1 - rgba8 albedo.rgb + metallness.a
  • RT2 - r10g10b10a2 normal.rg + roughness.b + misc.a
  • RT3 - r16g16b16a16 baked_ao.x + velocity.yz + sss.a

The rendered models use pre-baked ambient occlusion from hi-res models.

HiZ calculation

HiZ gif
Multi pass compute shader determines each level of depth hierarchy.

AO

SSAO or HBAO+ depending on your settings. SSAO in this case.
AO is calculated based on HiZ from the previous pass.
G virus guy final form

Global Specular+Diffuse

Using some non trivial algorithm light probes, cubemaps and AO are combined into global diffuse and specular maps.

GID GID

Example cubemaps from the scene.

GID

Global illumination diffuse component.

GIS

Global illumination specular component.

Update shadowmaps

Per light shadowmaps are being updated for those lights that are affected by dynamic objects. Each shadow map is allocated on a big texture array.

slice 0 slice 2 slice 11 slice 6

Local Specular+Diffuse+SSS

Per light contribution to specular and diffuse component is computed.

GID

Diffuse+SSS. SSS contribution is not visible is this frame.

GIS

Specular component.

Integrating the light

The original buffer If everything was white dielectric If everything was white metal Mixed white metal and dielectric Shadowmaps off Replace shadowmaps with checkerboard pattern Whatever Whatever

Specular/Diffuse components for radiosity/local lights are integrated with albedo. Check out the slider to get the gist of how each component contributes to the image.

Apply transparent glass

After all light has been applied, transparent glass is rendered.

Compute volumetrics/haze/smoke

Basically just a bunch of sprites.

Apply volumetrics/haze/smoke

This pass computes the blurred image to better lit the haze.

If the original haze mask is replaced with checkerboard.

GIS

The result of this pass.

TAA with previous HDR image

GIS

TTA is just magic.

Motion blur

GIS

Blur guide map is computed based on velocity map.

GIS

Post Processing

GIS

This pass computes the downscaled image first

GIS

And then applies bloom filter, tonemapping, distortion and chromatic aberration.

Conclusion

The Engine relies heavily on compute+indirect draw approach. All meshes and textures are of high quality. The game employs deferred rendering with TAA/FXAA and glass as a post process. Read this for more details on deferred rendering tricks. A lot of textures are BC7 compressed. In general, the used techniques are similar to those described at [4].

Bonus section

SSS contribution

GIS

Had to really search for the right frame to notice the SSS contribution.

Tentacle monster breakdown

G virus guy final form

The monster is split into many parts.

The guts

G virus guy final form

The game has a lot of gore textures for different details.

Mip levels for textures are not just linearly filtered. The crispiness increases with each level. Also some textures already have specular highlights, not sure how this contributes to the look.

Geometry

G virus guy final form

Geometry has good topology.

HBAO

G virus guy final form

HBAO is of much better quality than SSAO.

Smoke

Smoke takes cone lights into account.

The actual planes used to render the smoke.

References

[1]Kostas Anagnostou: Experiments in GPU-based occlusion culling

[2]Daniel Rákos: Multi-Draw-Indirect is here

[3]Adrian Courrèges’ Blog

[4]Alien: Isolation

Comments

Resident Evil 2 Frame breakdown from r/GraphicsProgramming