Skip to content

Phyronnaz/HLSLMaterial

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

96 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HLSL Material for Unreal Engine

Ever wanted to write complex material functions directly in HLSL? Now you can!

Unreal Engine 4.26, 4.27 and 5.0 are supported. 4.25 cannot be supported as custom nodes have a single output in that version.

Demo: https://twitter.com/phyronnaz/status/1452553917204733953

Discord: https://discord.gg/UjtexdkWxC

Marketplace: https://www.unrealengine.com/marketplace/en-US/product/hlsl-material

Features

  • HLSL support: write all your functions in a single hlsl file and use any of them in regular materials
  • Team-friendly: regular material functions are generated, so your team members don't need the plugin to use them!
  • Live updates: material functions & opened material editors are refreshed when saving the hlsl file (Windows only)
  • Comment support: comments are parsed & pin tooltips are set accordingly
  • Smart updates: only modified functions are updated
  • Texture parameters support
  • Bool parameters support
  • Define support
  • Includes support (with auto updates when included files are edited)
  • Default value support
  • Clickable errors: errors are properly displayed relative to your file(s), and clicking them will open your IDE

Installing from source

Download the repo as a zip and extract it under your project Plugins folder so you have YourProject/Plugins/HLSLMaterial/HLSLMaterial.uplugin

Visual Studio will be required.

How to

  • Create a new HLSL Material Function Library (right click Content Browser -> Material & Textures). This asset will be the link between your hlsl file and all the generated material functions.
  • Set the File on it to point to your HLSL file
  • Add functions to the file
  • Material functions will be created when you save the HLSL file
  • You can also disable the automatic updates and manually right click the asset -> Update from HLSL

Syntax

  • All return types must be void to ensure the pins are all properly named
  • To mark a parameter as an output, use out: eg, out float3 MyOutput
  • Comments must use the // syntax, /* is not supported
  • @param in comments will be parsed & put into the pin tooltips
// Ray-sphere intersection
// @param   RayOrigin       The origin of the ray
// @param   RayDirection    The direction of the ray
// @param   SphereCenter    The center of the sphere
// @param   SphereRadius    The radius of the sphere
// @param   Distance        The distance from the ray origin to the hit on the sphere
void RaySphereIntersect(float3 RayOrigin, float3 RayDirection, float3 SphereCenter, float SphereRadius, out float Distance) 
{
    float a = dot(RayDirection, RayDirection);
    float3 SphereCenterToRayOrigin = RayOrigin - SphereCenter;
    float b = 2.0 * dot(RayDirection, SphereCenterToRayOrigin);
    float c = dot(SphereCenterToRayOrigin, SphereCenterToRayOrigin) - (SphereRadius * SphereRadius);
    float Discriminant = b * b - 4.0 * a* c;

    if (Discriminant < 0.0) 
    {
        Distance = -1.0;
    }
    else
    {
      Distance = (-b - sqrt(Discriminant)) / 2 * a;
    }
}

#define BLUE 1

void Test(
    out float3 Color,
    float Red = 1.f,
    bool Green = false,
    Texture2D Texture,
    SamplerState TextureSampler,
    FMaterialPixelParameters Parameters)
{
    Color.r = Red;
    Color.g = Green ? 1 : 0;
    Color.b = BLUE;

    const float2 UVs = GetSceneTextureUV(Parameters);
    Color = Texture2DSample(Texture, TextureSampler, UVs);
}

Texture

For textures, an additional parameter named YourTextureParameterSampler of type SamplerState will automatically be added by Unreal:

void Test(Texture2D MyTexture, float2 UVs, out float3 Color)
{
	Color = Texture2DSample(MyTexture, MyTextureSampler, UVs).rgb;
}

How it works

The plugin manually parses the functions in the HLSL file. From there, it creates new material functions with a Custom node holding the function body.

The logic is pretty simple & straightforward, so it should be relatively robust.

Project management

Moving functions

Material functions are generated next to your library asset, under YourFunctionLibraryAsset_Generated/. Once they are generated, you should be able to move them anywhere - the library keeps a ref to them.

Renaming functions

If you rename a function in your HLSL file, you need to manually rename the corresponding material function in Unreal, ideally before saving the HLSL. Otherwise, a new one will be created with the new name.

Deleting functions

The plugin will never delete any asset. If you remove a function from the HLSL, it is up to you to remove it from Unreal.

Source Control

You don't need to check in the HLSL file or the library - simply checking in the generated functions should be enough. However, if your teammates are also using the plugin it might be best to check in everything.