Skip to content

Optimization: Output flags on materials to avoid material switching for specialized outputs. #14018

@bhouston

Description

@bhouston
Description of the problem

So I am interested in quickly switching between different outputs of a shader without having to create new materials to just get different outputs.

One area in particular were this would be useful (there are many) is in the shadowing code. It would allow us to not have to create a library of cached depth materials just for shadows. Instead we could keep the original materials but just change the flag for an early out after writing the depth. Basically it would deal with this complex caching situation here: https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLShadowMap.js#L56

This is a huge time saver when you have complex shaders that have bones, displacement, normal maps, etc.

It would be an optional feature. Something like:

#ifdef OUTPUT_FLAGS

#define OUTPUTFLAG_NONE 0x0000
#define OUTPUTFLAG_DIFFUSE_DIRECT 0x0001
#define OUTPUTFLAG_DIFFUSE_INDIRECT 0x0002
#define OUTPUTFLAG_DIFFUSE ( OUTPUTFLAG_DIFFUSE_INDIRECT | OUTPUTFLAG_DIFFUSE_DIRECT )
#define OUTPUTFLAG_SPECULAR_DIRECT 0x0004
#define OUTPUTFLAG_SPECULAR_INDIRECT 0x0008
#define OUTPUTFLAG_SPECULAR ( OUTPUTFLAG_SPECULAR_DIRECT | OUTPUTFLAG_SPECULAR_INDIRECT )
#define OUTPUTFLAG_ALBEDO 0x0016 // pre-shading value
#define OUTPUTFLAG_ALPHA 0x0016 // pre-shading value
#define OUTPUTFLAG_METALNESS 0x0016 // pre-shading value
#define OUTPUTFLAG_ROUGHNESS 0x0016 // pre-shading value
#define OUTPUTFLAG_SHADOW_DIRECT 0x0032
#define OUTPUTFLAG_SHADOW_INDIRECT 0x0064 // Include ambient
#define OUTPUTFLAG_LIGHT_DIRECT 0x0128
#define OUTPUTFLAG_NORMAL 0x0256  // Includes bump
#define OUTPUTFLAG_DEPTH 0x0512
#define OUTPUTFLAG_POSITION 0x1024

uniform int outputFlags;

#endif

It would also enable, as you can surmise by looking at my desired output flags, nice deferred workflows via multi-pass rendering.

I would implement it as a uniform flag so that we could change outputs without a recompile. That is key to performance because I would like to switch each material multiple times per render.

PS. I wonder if there is a way to incorporate multi-target rendering in this somehow. I just do not know how to specify optional packing of these outputs. MAybe when there is multi-target support, we can specify multiple output flags? Or that would just be a completely different type of output speification.

/ping @WestLangley @takahirox @tschw

Three.js version
  • Dev
Browser
  • All of them
OS
  • All of them
Hardware Requirements (graphics card, VR Device, ...)

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions