Assignment Goals
The primary goals of this assignment are:
- Extend the core Unreal Engine code.
- Create a new native Unreal Engine material node.
- Get experience with the strategy of finding and replicating an example, then changing it to suit your needs.
For this assignment, you'll be creating an new MaterialExpression node for the Unreal Engine material editor. Material editor nodes are part of the "Engine" module, and adding a new one requires editing the code in that module. You do not need to add your new node to any plugins that directly access the material system functions.
You will create a native material editor node implementing the random texture tiling described in a chapter of GPU Gems 2, and in slides from the Graphics Hardware Conference. As is typical of real-life instances when you want to implement an existing technique into an engine, though these sources do have some snippets of shader code, you will need to modify them to make them work within the Unreal Engine or treat them as pseudo-code to guide your own implementation. You will also have to look to examples within the engine for how to do it in a material node.
Details
The basic idea of the tiling algorithm that the texture consists of a set of tiles that match edge-to-edge, but can have anything you want on the inside. For variety, you can have a few different choices for the edges, referred to as the edge color (though it need not be an actual color). As long as the edge "colors" match, you can choose tiles at random.
To implement, break your input UV coordinate into an integer tile index and fractional position within the tile. Use the tile index with some kind of random index-to-edge-color hash to determine colors for each of the four edges that'll match the ones determined by the same hash for the neighboring tile. Use the tile mapping algorithm to figure out which tile to use from the source texture, then build a new UV from the selected source tile and the original fractional position. The source references used a texture for the hash function, but we'll use the Rand3DPCG16 shader function from Random.ush, using a hashes based on the current and neighboring tile indices: (X,Y), (X+1,Y), and (X,Y+1).
Test your project using the following two source textures
2 vertical & 2 horizontal edge colors: solid yellow or yellow outside with blue center. | 3 vertical & 2 horizontal edge colors. Wall, open, or door; floor, ladder, or hole. |
Creating results that will look something like this:
Create a project
- Create a a Blank C++ project with no starter content called assn6.
- As usual, put the project at the top level of your git repository.
Create a new material node
- Look at RgbToHsv node as a basis. Replicate its code with a new name. Only replicate the Engine module code, not Plugin code
- RgbToHsv has a pretty unique name, only appearing in the relevant locations in the Engine module and a couple of places in the Interchange engine plugin (which you can ignore).
- Since the Engine module is widely used, recompiles for minor edits take a longer than compiling stand-alone plugin code (though not as long as a full engine build!). Since the Engine module is so low-level, you will need to quit and restart Unreal to recompile.
- Change the node inputs & outputs
- You should have one UV input pin, and integer parameters in the detail panel for the number of edge "colors" in X and Y.
- RgbToHsv does not have detail panel parameters. Look for other material nodes in the same directories where you found RgbToHsv for examples that do.
- Output the tiled UV to plug into a TextureSample node.
- You should have one UV input pin, and integer parameters in the detail panel for the number of edge "colors" in X and Y.
- Generate a call to a shader function & do the rest of your implementation in shader code
- The shader code you emit for your node should mostly just call a shader function. Look for other nodes that calls a MaterialExpression... shader function for examples.
- Put your shader function in a file #included form MaterialTemplate.ush and do most of your shader development there.
- Edits to a widely-used shader file like MaterialTemplate.ush will result in rebuilding almost all of the shaders when you restart the editor. This is actually slower than the rebuild after an Engine module change. You should avoid restarting the editor too often during your shader development and debugging. You can recompile just the shaders for your one test material after each shader change (by making a minor change, even just moving a node, then hitting "Apply").
- Note that if you have a syntax error in MaterialTemplate.ush or file it includes, you'll have to look at the shader compiler error messages and fix it before you'll be able to re-launch the editor again. For changes direclty in MaterialTemplate.ush, either edit the number at the top of the file or delete the DerivedDataCache to force its change to be recompiled.
Test your node
- Create a test material using tile1.png with 2 for both x and y edge "colors".
- Create a second test material using tile2.png, with 3 for x and y edge "colors".
- To avoid blending across tiles, the texture sample node in your tests should use the absolute mip level setting, with "Const Mip Value" set to 0.
Grad
Show the number of X and Y edge colors in the title of the node (as seen in the screenshots above).
Extra credit
For up to 5 points each:
- Include an additional input pin for a seed. The Rand3DPCG16 hash function takes a 3D integer input. You'll probably use X and Y for the tile hash, so just use Z for the seed. Use a default seed value if nothing is connected to that pin
- Default to the object texture coordinates if nothing is hooked up to the UV pin. You'll have to make sure that the texture coordinates will be generated for the material.
- Include the texture lookup as part of your node, with texture selection in the detail panel and color output (this is the hardest of the extra credit options).
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. Be sure to tell us about any extra credit you attempted that you want us to grade. Extra credit will not be graded if it is not mentioned in the assn6.txt file.
Include a screen shot of the material editor for each of your two test materials, with the new material node selected so we can see what is set in the detail panel. You can use the OS screen shot tools, or 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). Scale the coordinate input to your node so we can see the randomized tiling in the material editor preview window in those screen shots.
Push to your repository, and tag your final commit with an assn6 tag.