Assignment Goals

The primary goals of this assignment are:

  1. Extend the core Unreal Engine code.
  2. Create a new Unreal Engine material node.
  3. Get experience with the strategy of finding and replicating an example, then changing it to suit your needs.

spectrum node

For this assignment, you'll be creating a new native MaterialExpression node for the UE material editor. Material editor nodes are part of the "Engine" module, and adding a new one requires editing the code in that module.

You will create a native material editor node to generate color spectrum given a floating point temperature input. Your node will support any of the non-texture-based spectral curves from Alan Zucconi's Improving the Rainbow blog posts Part 1 and Part 2.

This blog provides HLSL shader code, a shadertoy with GLSL shader code, and a Unity project. As is typical of real-life instances when you want to implement an existing technique into an engine, you may find some sample code, but that code may be in a different language, or for a different engine than you need. You can use these kinds of examples, but will need to modify them a bit to make them work within UE. You will also have to look to examples within UE for the material node plumbing necessary to get it into the engine.

Details

Create a project

  1. Create a Blank Blueprint project with no starter content called assn6.
    • Since you'll only be working with C++ engine code, you do not need the game project itself to be C++. Startup times will be faster if it is not.
    • As usual, put the project at the top level of your git repository.
    • Launch the Blueprint project directly from your IDE (not through the Epic launcher)
      • In Visual Studio, choose UE5 as your startup project, and add an assn6/assn6.uproject command line parameter to the debugging options.
      • In XCode, choose UE5 from the project list next to the play button, then add the assn6/assn6/uproject command line option in the "Edit Scheme" dialog.

Create your spectral node

  1. Find a reasonably uniquely named simple material node. You want a native node with at least one input and one output as a sample (native nodes appear green or red in the Material Editor). Replicate its code to reproduce its functionality with a new name (it'll be spread across about 4-5 files).
    • For full credit, I am looking for changes in the Engine module involving files in Engine/Source/Runtime/Engine.
    • Since the Engine module is widely used, recompiling may take a bit longer than it did for your plugins, though fortunately not as long as needed for a full engine build. I was seeing about 40 build steps (vs about 4000 for the complege engine build)
    • Given the compile times, it'll be worth it to spend some extra time double-checking for simple syntax errors and the like rather than relying on the compiler to report them, though code errors will cause the compile to fail before the linking phase.
  2. Modify your node to implement the spectral functions. If your template node didn't have one of the features you need (for example with the UENUM detail panel menu), look at other nodes for supporting examples, and copy over what they are doing.
    • You should have one float input pin.
    • You should have a UENUM selection in your node's Details panel to choose which spectral model to use.
    • The output pin should be a float3 color.
    • For fastest iteration time, the C++ code for your material node should primarily just call some new shader function or functions defined in MaterialTemplate.ush.
    • Once calling this function is working (and even before the function itself works), you can edit the MaterialTemplate.ush code and recompile one testing material repeatedly without having to recompile the C++ code or all of the other shaders dependent on MaterialTemplate.ush.
    • When you quit and restart the engine, it will recompile all shaders dependent on MaterialTemplate.ush, so do this as rarely as you can.
    • If there's a syntax error in MaterialTemplate.ush, you won't be able to launch the engine until you fix it. When debugging core shader file changes, you may want to set the r.ShaderDebugMode console variable to 1 in your Engine/Config/ConsoleVariables.ini to enable better reporting of startup-time shader compile errors.
  3. Create a test material that can show your spectral node and its variations in action.

Grad Students

No special grad student part this time

Extra Credit

For up to 10 points of extra credit, also implement the texture-based spectrum. You can get a suitable texture by downloading the spectral map image from the blog page.

Options to implement this include adding the spectrum image to the core engine like the internal textures used by the Noise or Sobol nodes, or similarly to the way the default texture works in the texture node. How ever you do it, the existance of the texture should be built-in and hidden from the user.

Be aware that changes in any widely used header can cause large build times. Note also that if you choose the first option, the engine files that initialize global texture data do not have access to the UFactory functions for loading images from a file. To make the spectrum into a core global texture, you'll need to convert the texture data into code form as C++ array initialization. It is sufficient to make it 1024 x 1 instead of the 1024 x 256 of the original texture.

Submission

For full credit, you must commit multiple times during your development.

Add an assn6.txt. Tell us what works and what doesn't, and anything else you think we should know for grading.

Include a screen shot of a material showing your spectral material node in action

Also include links to screen shot(s) of the material editor for your test material(s) like the image at the top of this assignment. Make sure your new node is selected so we can see what is set in the detail panel. You do not need to show the tool tip. You can capture a screen shot of the full material editor window with the "EditorScreenShot" console command (By default, EditorScreenShot captures the main editor window to the Saved/Screenshots directory. Dock the material editor window with the main UE window, or use "EditorScreenShot Name=window-name to capture an image of the material editor).

Push to your repository, and tag your final commit with an assn6 tag.