Assignment Goals

The primary goals of this assignment are:

  1. Create a UE4 Plugin.
  2. Extend the Blueprint system.
  3. Create and use a blue noise point distribution

For this assignment, you'll be creating a new Blueprint node and data type in a UE4 plugin. In this case, we'll create a new Blueprint type to hold data about a blue noise point distribution generated using Mitchell's best candidate algorithm. You'll also create a Blueprint node to provide a random number seed to an object of this new type, and one to return a point location from it, and a simple Blueprint script to place some objects using this blue noise point distribution.

Objects distributed using true random numbers will tend to be clumpy because each position is independent of all of the ones before, so has no memory that another object has been placed nearby or that there is an unfilled gap. A blue noise distribution spaces has correlation between the point placements to make them more even in density, To summarize Mitchell's algorithm, you first place one point at a random x/y location. At each step, select several candidate points and keep the one furthest from any already placed points. You should use distance calculations that wrap around from left to right and top to bottom so the distribution will tile and to avoid preference for point locations along the edges.

The linked page suggests choosing a set of candidate points at each iteration proportional to the number of points placed so far. If you naively loop through all of the already placed points to find the distances for each candidate, the resulting algorithm to generate N points will run in O(N3) time

Randomly placed trees Blue-noise-distributed trees
Randomly distributed objects Blue-noise distributed objects

Details

For this assignment, I've gone a bit more general with the steps, though I have given some pointers for where to find examples of code similar to what you will need to write.

Create a project

  1. Create a Basic Code C++ project (with no starter content) called assn4, and a level called "assn4" set as your default editor level.
    • As usual, put the project at the top level of your git repository

Create a Blueprint test case

  1. Create a Blueprint actor to spawn models with random positions and rotations within a square.
  2. Your Blueprint should have four variables: an integer random seed, a number of elements to spawn, and two hidden RandomStream variables (one for positions and one for rotation).
    • When you create a variable, you can change its type (and allowable range and other attributes) in the panel on the right
    • Click the closed eye icon next to the variable name in the variable list to make it visible in the editor details window. Otherwise, it is considered a hidden local variable.
  3. The screenshot below shows a working Construction script actor Blueprint to do the random placement. Recreate this Blueprint or something similar.
    • Initialize the random stream for position given the seed.
    • Add an InstancedStaticMeshComponent
      • In the detail panel for this node, you can choose any static mesh and material you want, either one already available or by making something new
    • Loop for the number of elements
    • On each iteration, create a transform using the position random stream for X/Y, and the rotation random stream for orientation.
    • Use AddInstance to add a copy at that location
      • Random numbers can be clumpy and pack objects too closely. This is why it is common to use something like a blue noise distribution for placement of things like trees or vegetation.

Blueprint for random distribution

Create a Blueprint plugin

  1. In Settings > Plugins, create a new Blueprint plugin
  2. Once loaded, you can recompile and hot-reload from Windows > Developer > Modules > (find your plugin in the list) > Recompile
    • The editor toolbar "Compile" button only does "game" code (actors and components), not plugins

Create Blueprint nodes and data

  1. Make a Blueprint type to hold a random stream object and set of generated 2D point locations
    • Look for things tagged USTRUCT(BlueprintType) for examples of Blueprint-accessible types
    • KismetMathLibrary has some of the simpler examples.
  2. Make Blueprint node to initialize that type from a random seed, and another to return a single point
    • Look at how the RandomStream blueprint nodes work.
    • To get something working and testable quickly, you can just return a random position (equivalent to the first Blueprint) before you do the full blue noise algorithm.

Blueprint test case

  1. Make a copy of your existing Blueprint test class
  2. Modify it to use your new blue noise type instead of RandomStream for the position.
    • This should look similar to the image below

Blueprint for blue noise distribution

Mitchell's Best-candidate Algorithm

  1. Implement Mitchell's best-candidate algorithm in your Blueprint node.
  2. If N points have been generated so far, your node should try 5N candidate points, and return the one farthest from any already placed point.

Grad Students

Adapt multi-class blue noise sampling to use Mitchell's best candidate algorithm instead of naive dart throwing. You only need to support two point classes, and should add a point-class ratio parameter as an extra input when seeding the stream, and an additional point-class numeric (0 or 1) parameter output from the point generation. You will need to modify your test blueprint to show the two different point classes using different static meshes and/or different materials.

Since Mitchell's algorithm always places a point at the best location it can find, you won't need to do the sample removal from the original algorithm. This will not give as good a distribution as the method in the paper including sample removal, but should be simpler to implement.

Extra Credit (all)

For up to 10 points of extra credit, only available if you submit by the original due date, use some data structure to make the point distance queries faster (for the base version of the assignment, you can just do a linear search through all of the already-placed points). A few options include a uniform grid (with re-binning as the number of points grows), a quad tree, a K-D tree, or a BSP tree.

Submission

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

Add an assn4.txt. Tell us what works and what doesn't, and anything else you think we should know for grading. Include a couple of screen shots showing different numbers of spawned objects with both the random and blue noise distributions.

Make sure your assn4.txt file tells us if you attempted the extra credit, and if so, includes a description of the data structure you decided to use and your source(s) of information on it.

Push to your repository, and tag your final commit with an assn4 tag (git tag assn4 followed by git push origin assn4).