engine icon indicating copy to clipboard operation
engine copied to clipboard

Split standard material into frontend and backend

Open slimbuck opened this issue 3 years ago • 6 comments

Background

Up till now the standard material has been responsible for all parts of the rendering pipeline. Standard material defines an "uber shader" interface for artists to specify the surface properties like diffuse, specular, roughness etc. (We call these properties the material frontend). The standard material also implements the runtime lighting system, including lights, IBL, dynamic shadows and everything else needed to render the surface. (We call this the material backend).

(As an aside, in deferred rendering the components written into the g-buffer can be thought of as the frontend. While the lighting passes which use the g-buffer and generate the final image are the material backend).

The current standard material structure means that users have limited scope for customising the look of materials. Either users must make do with the features provided by the uber shader interface, or they must customise the shader chunk system. Unfortunately the shader chunk system is undocumented, open to change, difficult to debug and results in very brittle code.

For these reasons, we propose to split out the lighting backend from the monolithic standard material. Doing so will mean we can leverage the runtime lighting system with any arbitrary frontend.

The new lighting backend will be used by the standard material as well as the shader-editor (currently in development).

Todo:

  • [x] extract the backend parts of standard.js (done in #4254)
  • [x] restructure shader chunks so there is a formal frontend and backend split (done in #4254)
  • [x] provide runtime support to notify application developers if chunks have changed (#4343)
  • [ ] restructure the options builder into frontend and backend (see options builder) (done in PR #)
  • [ ] implement an engine example of custom frontend shader using the new material backend (done in PR #)

slimbuck avatar May 16 '22 14:05 slimbuck

Will this deprecate shader chunks and the current approach of providing custom chunks?

Maksims avatar May 16 '22 16:05 Maksims

Will this deprecate shader chunks and the current approach of providing custom chunks?

No not at all.

But we have started splitting chunks into frontend and backend, see the directory structure:

  • standard are the standard material frontend chunks
  • lit are the material backend chunks

We will try make as few changes to the standard chunks as possible, so users can continue to override these without future breakages. The backend lit chunks though might change in future and will likely break projects that have these chunks overridden.

slimbuck avatar May 16 '22 16:05 slimbuck

The frontend is considered a blackbox and is responsible for providing the following (optional) values to the backend:

component variable type space
emission dEmission vec3
alpha dAlpha float
normal dNormalMap vec3 tangent
albedo dAlbedo vec3
glossiness dGlossiness float
specularity dSpecularity vec3
ambient occlusion dAo float
lightmap dLightmap vec3
lightmap direction dLightmapDir vec3
clear coat specularity ccSpecularity float
clear coat glossiness ccGlossiness float
clear coat normal ccNormalMap vec3 tangent

In addition the frontend is responsible for:

  • alpha test discard

slimbuck avatar May 17 '22 13:05 slimbuck

In order for the frontend to have access to world and camera space, the fragment shader must calculate data in the following order:

  1. backend calculates world space vertex normal (normalVertexPS)
  2. backend calculates world space view direction (viewDirPS)
  3. based on these the backend calculates TBN matrix (used to transform from tangent/geometry space to world space)
  4. frontend executes, outputs emission, diffuse, tangent space normal etc has access to TBN
  5. backend calculates lighting and outputs final color/depth

slimbuck avatar May 17 '22 13:05 slimbuck

Minor point on naming, but why are all variables prepended with d except clear coat ones, which are cc? Wouldn't more consistent naming be:

dSpecularityCC or dCCSpecularity

What does d mean anyway?

willeastcott avatar May 17 '22 20:05 willeastcott

Also, normals, when unpacked, they are no more a map, but just normals.

Maksims avatar May 18 '22 10:05 Maksims

I suggest we close this now. I know the example isn't written. Maybe open a new issue for that?

willeastcott avatar May 01 '23 18:05 willeastcott

Done!

slimbuck avatar Jun 09 '23 08:06 slimbuck