o3de / sig-graphics-audio

Documents and communications for the O3DE Graphics-Audio Special Interest Group
14 stars 14 forks source link

Draft: Proposed RFC Feature: Support for multiple Material-Types in Raytracing Hit Shaders #152

Open kh-huawei opened 10 months ago

kh-huawei commented 10 months ago

Summary:

During raytracing the hit-shaders need access to all materials in the scene at once, which clashes with the current setup for the Forward+ - Pipeline, where a shader needs only access to a single Material Instance at any given time. The current solution for Raytracing is somewhat unfinished, in that it assumes that there exists only one material-type, and collects all Material-Instances in a single RayTracingMaterialSrg, and uses one single hit-shader that re-implements almost but not quite the BasePBR - material type.

What is the relevance of this feature?

The new Material-Pipeline and the Material Canvas allows users to easily create their own material types, but that has no influence on the material used during raytracing. This feature would remedy that, and enable user-created material types during raytracing. Incidentally, this would also make implementing a deferred pipeline easier.

Feature design description:

Similar to the existing RayTracingMaterialSrg - solution, but more general: Automatically create one MaterialSrg for each material type, that contains the settings of all material-instances of that type that are currently active in the scene. Each sub-mesh needs a Material Instance Index somehow to refer to the relevant instance. And to not have material shader-utils exist twice in the engine, the shader functions should be re-written so that they work with a MaterialInfo - struct and an array of textures, instead of accessing the MaterialSrg directly.

--- OR ---

Stick the MaterialInfo - struct for each instance into a BufferView so it ends up in a ByteArrayBuffer of the Bindless SRG, and the RayTracingMaterialSrg redirects only from the mesh to the right MaterialInfo - ByteArray Buffer. The shader for the material-type knows how to decode the contents of the ByteArrayBuffer to the appropriate MaterialInfo struct (from the Material Canvas Abstraction).

Technical design description:

First rough draft:

What are the advantages of the feature?

Actually support user-provided materials during raytracing.

What are the disadvantages of the feature?

Breaking changes with existing (old) materials

How will this be implemented or integrated into the O3DE environment?

Are there any alternatives to this feature?

How will users learn this feature?

Are there any open questions?

adiblev commented 10 months ago

How would this cope with exposure of textures and handling them via the definition of a surface? was this taken into account?

kh-huawei commented 10 months ago

Like the RayTracingMaterialSrg does now: the Material-Info struct holds the indices of the Texture Views relevant for the material instance, and the textures are then accessed via the bindless Srg.

There are actually two indirections going on currently: The MaterialInfo holds one start-index into the m_materialTextureIndices, and that buffer holds the index of the bindless texture view (either in the bindless m_materialTextures array in the same srg, or the Bindless_Srg - index directly). Seems like an optimization so the materialInfo-struct only needs one texture-index, and/or so that the texture-views for one material-instance are sequential in memory, but i'm not sure how useful that actually is.