Is there a way to define a material using only C++ and HLSL?

I’ve got some existing HLSL code that I’d like to re-use as a Material without having to completely re-write it as a node graph. Is it possible to do this?

Depending on what your original HLSL code does, you may be able to use the custom expression in the Material Editor, which lets you enter raw HLSL code.

Thanks for the quick response!

I’ve looked at custom expressions already, and they appear to be more designed for the case where you want to inject a small amount of custom shader code, as opposed to allowing to re-purpose existing shaders.

My 2 main blockers to this approach appear to be:

  1. I’d have to convert all of my uniform buffer declarations and textures into material parameters collections (which, ironically, appear to be implemented using uniform buffers) to pass in the various bits of state into the material.
  2. The material editor doesn’t appear to support operations on matrices, and it doesn’t seem possible to have a matrix parameter in a Material Parameter Collection.

As I understand it, materials appear to be, (on the gpu side, at least) an interface used by the pass-specific shader code in conjunction with a similar interface exposed by the ( mesh-specific ) vertex factory, allowing the pass-specific code to only need to implement the functionality required for its corresponding drawing policy.

What I’m curious about is if I take my existing shader code and make it conform to that material shader interface, shouldn’t I be able to refer to that code as a “material”, and use it in places instead of a standard node-graph material?

Unfortunately, the material compilation pipeline is very involved and not hookable at the level you’re talking about AFAIK. If you take a look at FMaterial/FMaterialResource, you can see there is a lot more state produced than just HLSL source - uniform expressions metadata, uniform textures metadata, various metadata about usage of certain buffers or other state. You’d end up having to duplicate a lot of the logic which produces this, even if it were hookable.

In the past when we wanted to pass in matrices we just split them into vectors and recombined in the custom HLSL node. You can create helper functions for this on both sides (C++ and HLSL).

If this isn’t just a one off, and you’re dealing with a lot of shaders you are trying to convert, you could write some editor code which would create a UMaterial with custom expressions and automatically generate the various parameters from your shader source. It’d be a lot of work, but without knowing how many shaders you want to convert to materials, can’t tell you if it would be worth it.

Dang, that’s what I was afraid of. Oh well, thanks!