Skip to content

Add renderer feature support flags to shader preprocessor #6207

Open
@lostminds

Description

@lostminds

Describe the project you are working on

Shaders for use in exports with different renderers (Forward+, Mobile or Compatibility for web)

Describe the problem or limitation you are having in your project

Different renderers support different sets of features. For example the new instance uniforms aren't supported in the Compatiblity renderer and textureLod is not supported on Mobile. If you use an unsupported feature in a shader, this will fail to compile and the material will not render.

Currently this means that either you need to settle for the lowest common supported features for your platforms, or make different shaders for different renderers and assign them using some mechanism on load based on the renderer to use the more advanced versions when supported.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

The recently added shader preprocessor could I think have the potential to make this process much smoother by adding symbols available to the preprocessor describing features available on the current renderer:

For example a RENDERER_FEATURE_INSTANCE_UNIFORMS that is defined when the renderer is Forward+ or Mobile and not on Compatibility renderer.

Using these symbols you could then write your shaders with fallbacks like:

#if defined(RENDERER_FEATURE_X)
<code that uses feature X>
#else
<fallback code>
#endif

Meaning this shader could compile and be used on any renderer, but only include feature X when it's supported.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

I'm not familiar with how the preprocessor is set up, but I imagine this could be done by the preprocessor asking the current renderer for a list of available supported features and then adding those as hidden #defines in some scope that is available to the shader preprocessor.

Another benefit to this approach is that as support for advanced features is added to renderers they can simply add these features to their list of supported features, and any shaders using these preprocessor symbols will compile using the now supported features automatically. Instead of the more clumsy approach of for example checking if we're using the mobile renderer and then applying the mobile version of the shader, which will not automatically update if the mobile renderer starts supporting more features.

Finally, since the visual shader system is as I understand it basically a shader code generator, this system could also use this preprocessor functionality to add fallbacks for features that are not supported on all renderers. For example making instance uniforms fall back to constants or shader uniforms if instance uniforms aren't supported instead of failing to compile.

If this enhancement will not be used often, can it be worked around with a few lines of script?

As discussed above you can work around this by making multiple shader versions for different renderers, but it has drawbacks as noted above.

Is there a reason why this should be core and not an add-on in the asset library?

I think both the shader preprocessor and renderer functionality that would be needed are part of the core.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions