Wednesday 29 March 2017

Procedural Generation Tutorial Basic Cell Pattern Texture - Part 1

Procedural Generation Tutorial Basic Cell Pattern Texture - Part 1



The end result of the full tutorial.

At the end of Part 1 we will have produced this (See image 1.0).
Image 1.0

Before you start you should know these things:
  • Create Texture variables
  • Manipulate textures using SetPixels
  • Create a basic texture pattern
  • What noise is and hot to use it with a texture pattern

You should have gone through these tutorials before going further:

  • Checker Board Texture
  • Brick Pattern Texture
  • Brick Pattern Noise Texture


If you find yourself not understanding some of the terminology or code of the tutorial I would also recommend going through the previous tutorial to get up to speed. I will leave a link to it below to go through at your leisure.

Checker Board Pattern Texture http://joseph-easter.blogspot.nl/2016/12/procedural-generation-tutorial-checker.html

Brick Texture Tutorial http://joseph-easter.blogspot.co.uk/2017/01/procedural-generation-tutorial-brick.html

Brick Noise Texture Tutorial http://joseph-easter.blogspot.nl/2017/02/procedural-generation-tutorial-brick_8.html

If you follow this tutorial and find I am moving too fast or if you don’t know the things in the list above, I would recommend getting up to speed and then come back to this tutorial when you are ready.

With this tutorial if you want to convert this into JavaScript by all means do so but it may be easier for you to follow this in C# and stick with the language of the tutorial to make it easier.

PROJECT RESOURCES: At the bottom of the post there is a download link to a zip file. This files includes all files needed to follow Part 1 and the completed project file of Part 1.

In this tutorial series, we will be adding a pattern to the texture using code by adding noise to the texture image.



In this tutorial series, we will be creating a very simple pattern using a cellular texture using code. This tutorial will use and build upon what we have learnt from the previous texture tutorials, by creating two textures, one for the background, and one for the foreground, dividing the foreground into cells and adding an image into those cells then combining those textures. Later we will add variation to it by deciding whether to show a cell based on it noise value in the texture space, then using that noise to position it with in the cell itself using bombing.


We will:
  • Explain the theory
  • Add the Noise script to a quad
  • Bootstrap some of our code from the BrickNoisePattern class
  • Create the background texture (one block colour)
  • Import the PNG image file
  • Add the background colour to it

Step 1: The theory

Theory for the project:

In this project, we will be using techniques we used in previous tutorials. Then later when we have the foundations laid out we will add some more variation to it by implementing a new technique using noise generated by the game object’s position.

In procedural generation, a ‘bomb’ is essentially a node or a seed to place a given item. For example, if you had a grid texture, you would divide that texture into chunks. You may decide that this would create a regular pattern, a tiling effect. You may not want this, so you would use an algorithm to decide which chunks to show. This may still show a regular pattern to some degree, because the image you placed in the chunk is smaller than the chunk itself and it’s in the centre of the chunk itself. Then you decide to create random nodes or seeds inside each chunk. This decides where the image will be placed inside each chunk.

Note: In some engines and with some Shaders if the image is so far from the centre that it protrudes into another cell it may clip off part of the image that is outside the cell (or chunk). In this case, you would modify the shader to check the surrounding eight cells of the shader or texture.


However, in unity this is not a problem because it will set the pixels of the image if it has enough pixels to set in the texture. This causes another problem though. One image may overlap another one from another cell or two, this can be fixed by making the sure image is set between two predefined points within its cell.

Theory for Part 1:

In this part, we will set the basics for the project. We will create a quad in the centre of the scene, add the noise class to it since we have already done the work for it. Then we will create a new class above it called ‘Basic Cellular Texture’ and add some of the code from ‘Brick Noise Pattern Texture’ to it. After this we will create and colour the background texture, then do the same with the top layer texture. With the top layer texture, we want this to be transparent (or alpha out the pixels so the background texture can show through the top layer). Then we will create a texture variable to store the image we will be putting into the top layer texture.

Step 2: Bootstrapping code from the Brick Noise Texture and Setup

In this step, we are not doing anything difficult here. First create a Quad and name it ‘Basic Cell Texture’. Then if you have not already done so, import the ‘Noise’ and ‘NoiseLibrary’ scripts into your project. Then create and add a new script to the quad named ‘BasicCellPatternCreator’, then add the ‘Noise’ script to the quad (make sure it is under ‘BasicCellPatternCreator’).

If you have not already done so, create a folder for your scripts (called ‘Scripts’) and put your scripts in there. (See image 1.1).

Image 1.1: This is the order they should be in.

Now we need to do one more thing before we start, import the image [insert file name here] into your project and put it into your ‘Art’ folder. When you import it make sure you click on the PNG file and make sure ‘Alpha is transparency’ is set to true and set ‘Max Size’ to ‘64’ (See Image 1.2). The image itself is 64 by 64 pixels.


Image 1.2: Make sure the Quad is set to 

the default values in the inspector.

Now we go into our script and prepare it buy bootstrapping some code from ‘BrickNoiseTextureCreator’, essentially copy and pasting code we have already done before. First, we copy and paste a few variables ‘mainTexture’. Then we copy over the variables ‘mainTexWidth’, ‘mainTexHeight’, ‘blockWidth’, ‘blockHeight’, ‘colour0’, ‘colour1’, ‘colour0Arr’, ‘colour1Arr’ and ‘NoiseScr’ of type ‘Noise’. After this we copy and paste the functions ‘SetMainTextureSize’, ‘CreateMortarColour’, ‘ConvertColourToArray’, ‘SetBlockSize’, ‘CreatePattern’ and ‘AddTexturesTogether’. (Also below ‘mainTexture’ add ‘combinedTexture’).


Code:


public Texture2D mainTexture;
public Texture2D combinedTexture;

public int mainTexWidth;
public int mainTexHeight;

int squaresX;
int squaresY;

int blockWidth;
int blockHeight;

public Color32 color0;
public Color32 color1;

public Color32[] color0Arr;
public Color32[] color1Arr;

public Noise noiseScr;

void Start()
{
   SetMaintextureSize();
   CreateMortarColour();
   ConvertColourToArray(blockWidth * 
                        blockHeight);
   CreatePattern();
   AddTexturesTogether();
}


void SetMaintextureSize()
{
   ...


}

void CreateMortarColour(Texture2D tex)
{
   ...

}

void ConvertColourToArray()
{
   ...

}


void CreatePattern()
{
   ...


}


void AddTexturesTogether()
{
   ...



}

Great, now comment out the functions ‘CreatePattern’, ‘AddNoiseToTexture’ and their respective references in the ‘Start’ function. Then in ‘SetMainTextureSize’ remove the reference to ‘ConvertBricksToSquares’ and the lines setting up the ‘leftBrickTexture’ and ‘rightBrickTexture’ variables. With these respective functions, we don’t need them now and in their current state they will throw in errors, but we will need them later. Next stop we will fix an error in our code and create the background colour.


Step 3: Creating and Setting the Background Colour

Now, the error we are getting is a ‘no overload for method’ error. Which means it needs to have the appropriate variable parsed to it. This is an easy fix, when we reference it in ‘Start’ we will parse it the background texture ‘mainTexture’. Then we change the variable’s name to ‘CreateBackgroundColour’ since this makes more sense. (See image 1.3).

Code:
...
void Start()
{
   SetMaintextureSize();
   CreateBackgroundColour(mainTexture);
   ConvertColourToArray(blockWidth * 
                        blockHeight);
   CreatePattern();
   AddTexturesTogether();
}
...
void CreateBackgroundColour(Texture2D tex)
{
   ...
}

Image 1.3

At the moment we can’t see the result of the result of the function even though we have used ‘tex.Apply();’ after making changes. This for a very simple reason, we have forgot to set the texture variable to the ‘mainTexture’ variable of the and renderer of the material the quad is using.

This is very easy to fix since in the function the line should already be there but commented out. (if the line isn’t there for some reason add it (it will be in the code snipped below in bold). (See image 1.4).

Code:
...
void CreateBackgroundColour(Texture2D tex)
{
   ConvertColourToArray(tex.width *
                        tex.height);
   tex.SetPixels32(0, 0, tex.width,
                   tex.height, colour0Arr);
   tex.Apply();
   GetComponent<Renderer>().material.
                           mainTexture = tex;

}


Image 1.4

We now need to do one last thing. Set the background colour. At the moment, the colour is black since that’s the default when creating a new colour variable. All we have to do is click the variable and chose the desired colour from the colour picker. Or you can enter the bit values or enter the Hexadecimal value of your desired colour. I’m going with a light blue since it is a nice colour with good contrast with most bright colours. (if you want the precise colour I’m using the Hexadecimal value is '41CEFDFF'). (See image 1.5).

Image 1.5

This is the result you should have when in ‘Play Mode’. (See image 1.6).

Image 1.6: Resolution 256 by 256.

Great, part one is finished. We have laid down the foundations.


We have learnt how to:
  • Make a simple texture variable
  • Colour our texture with one block colour


In Part 2 we will create two new variables, one for the image we will be using in the top layer and an image which we will create and store a pattern on. We will learn how to divide the texture into simple cells, add the new image to the cells of the texture and fix any bugs that appear.


Go to Part 2, click here.

If you enjoyed this tutorial and would like me to add some extra content to it, like and share this tutorial on here and social media and leave a comment below. If you didn’t like this tutorial please leave a comment below saying why.

Wednesday 22 March 2017

Procedural Generation Tutorial Brick Noise Texture - Part 6 Extra Configurable Noise Type

Procedural Generation Tutorial Brick Noise Texture - Part 6 Extra


Before you start you should know these things:
  • Create Texture variables
  • Manipulate textures using SetPixels

You should have gone through and completed all the ‘Checker Board Texture’ and 'Brick Pattern Texture' tutorials before going any further. If you find yourself not understanding some of the terminology or code of the tutorial I would also recommend going through the previous tutorial to get up to speed. I will leave a link to it below to go through at your leisure.

http://joseph-easter.blogspot.com/2017/03/procedural-generation-tutorial-brick_15.html

If you follow this tutorial and find I am moving too fast or if you don’t know the things in the list above, I would recommend getting up to speed and then come back to this tutorial when you are ready.

With this tutorial if you want to convert this into JavaScript by all means do so but it may be easier for you to follow this in C# and stick with the language of the tutorial to make it easier.

PROJECT RESOURCES: At the bottom of the post there is a download link to a zip file. This files includes all files needed to follow Part 6 Extra and the completed project file of Part 6 Extra.

In this tutorial series, we will be adding to the brick pattern texture using code by adding noise to the texture image.


In this tutorial series, we will be adding to the brick pattern texture using code by adding noise to the texture image.

We will:
  • Explain the theory
  • Create a delegate
  • Create a delegate array
  • Store methods in said array
  • Make the UI more user friendly
  • Use delegate to store a function to call later
  • The extreme basics of delegates

Step 1: The theory


In today’s tutorial, we will cover how change our code to make it more configurable so we can easily change what type of Noise (1D, 2D or 3D) we use when creating the noise pattern. At the moment, in our code when we need to change the noise function from one 1D to 2D, we change it directly in our script and we have to wait for the code to compile. It would be a lot easier if we could just have one variable that can hold a functions for us and we can easily swap out one function for another as we need it based on another variable.

This is very quick to implement, and will save us time in the long run and will make it easier for the designers in your team (and the developers).

As a quick out line, we will create a type called a delegate in the ‘NoiseLibrary’ script called ‘NoiseLibraryDelegate’ and have it return a type ‘float’. We will also give it a few parameters to pass it. These will be the same parameters we pass ‘RandomValue1D’. This delegate will hold a reference to any one of our ‘RandomValue’ function we assign it.

Then we will create a public array of type ‘NoiseLibrary’ called ‘randomValueFunctions’ which will hold references to every ‘RandomValue’ function we have. We will order them by their dimensions (1D, 2D and 3D) for when configure them in the inspector later.

After this we will create a public integer variable called ‘noiseDimentions’ which will range between 1 to 3. This will have a range slider, because we only want it to be between values 1 to 3 to correspond to the dimensions of the noise (don’t worry about the array starting at ‘0’ we will sort this out when we cross that bridge).

Then in the ‘Noise’ script in ‘CreateNoise’ function we will create a tempory variable of type ‘NoiseLibraryDelegate’ called 'noiseDimentionType’ and assign it an element from the ‘randomValueFunctions’ array and chose an element using the ‘noiseDimentions’ variable. This will chose the reference to the ‘randomValueNoise’ function we need. Then when we set the pixel to the random colour intensity we replace ‘’ with ‘noiseDimentionType’.


Step 2: Creating the Delegate


First we need to create a delegate called ‘NoiseLibraryDelegate’ which will return a type ‘float’ and we will parse it a Vector3 called ‘point’ and a float called ‘patternAlternation’ speed. This delegate is like a variable but it holds functions instead. With a delegate though you can only assign it a function that has the same parameters that the delegate has. When a delegate is called, it carries out that function, it can hold multiple functions some times and the delegate can change the assigned function at runtime.

After this we will need to create a public static array of type ‘NoiseLibrary’ called ‘randomValueFunctions’. This will hold a reference to every ‘RandomValue’ function in each element. Essential it’s an array of functions, or function references. We will order them as follows ‘RandomValue1D’, ‘RandomValue2D’and ‘RandomValue3D’.


Code:


using UnityEngine;

public static float NoiseDelegate (Vector3 
point, float patternAlternationSpeed);

public static class NoiseLibrary()
{
   public static NoiseDelegate[] randomValueFunctions =
   {
      RandomValue1D,
      RandomValue2D,
      RandomValue3D
   };
   
   ...
   
   public static float RandomValue1D (Vector3 
point, float patternAlternationSpeed)
   {
      ...
   }
   
   public static float RandomValue2D (Vector3 
point, float patternAlternationSpeed)
   {
      ...
   }

   public static float RandomValue3D (Vector3 
point, float patternAlternationSpeed)
   {
      ...
   }
}

Step 3: Adding the configurations


We have the main bits set up. We need to do a few more things and we are done. We need a way to choose what noise method we will use. This needs to be easy to change in the inspector for both the designers and the developers. We will use this integer as the indexer for the ‘randomValueFunction’ array to get the correct ‘randomValueNoise’ function reference. We will put this in the ‘Noise’ class script Now you might be thinking ‘arrays start at zero, why don’t we set the range to zero to 2?’. We do this because we want it to be easier for the designer, and they won’t necessarily understand code or how an array works, and it’s more logical to think ‘1’ refers to 1D noise or the first function in this array. In other words we are making it more user friendly, but we will use some simple maths behind the scenes to make this work properly.


Code:


using UnityEngine;
using System.Collections;


public class Noise : MonoBehaviour
{
   ...
   [Range(1,3)]
   public int noiseDimentions = 3;
   ...
}






Now in the ‘CreateNoisePattern’ function we need to assign a function from the ‘randomValueFunction’ delegate array. We do this by declaring an instance of type ‘NoiseDelegate’ called ‘noiseDimention’ and assign it an element from the ‘randomValueFunction’ delegate array from the ‘NoiseLibrary’ class. We will use ‘noiseDimentions’ as an indexer be we will take away one from this to index the array at the correct element.

Code:

void CreateNoisePattern()
{
   NoiseDelegate noiseDimention = 
   NoiseLibrary.randomValueFunction
   [noiseDimentions - 1];
   float normalizer = 1f / resolutionW;
   WorldCoordinates();
   for (int w = 0; w < resolutionW; w++)
   {
      LeftAndRightSides(pointLL, pointLR,
                        pointUL, pointUR, 
                        w, normalizer);
      for (int h = 0; h < resolutionH; h++)
      {
         CalculatePoint(leftSide, rightSide,
                        h, normalizer);
         noiseTexture.SetPixel(w, h, 
              Color.grey * 
              noiseDimention(point
              patternAlternationSpeed));
      }
   }
   noiseTexture.Apply();
}

Now if we run our code this is what we get.

Resolution 236, patternAlternationSpeed 64.


If we look closely, our game object’s noise texture looks pretty similar when it’s set to 2D or 3D at the default position and rotation. The only way to tell it’s different is by looking at the hash value because it’s calculated (or hashed) an additional time when 3D is selected.



Resolution 256, patternAlternationSpeed 64.

However, when the object is rotated, this is no longer the case and the extra noise calculations can be seen. There is another layer of complexity to the texture’s noise pattern.



Resolution 256, patternAlternationSpeed 64, 
rotation X: 30, Y: -28, Z: 19 (for all objects in the image).



Great stuff, we can more quickly and easily change the noise value type in the inspector, generally making it more user friendly.

We have learnt how to:
  • Create a Delegate
  • What a delegate is capable of
  • A delegate can store methods
  • Those methods can be swapped in and out at runtime
  • Delegates can store multiple methods in the form of an array
  • Call a function from a delegate instance to return a value
  • Use a range slider on a public integer
  • Use said variable to make interface more user friendly
  • To set the method in a delegate by creating an instance of said delegate


This tutorial as an added on extra for Part 6. It is not essential but makes things a little more polished. I hope you enjoyed this tutorial as much as I had fun making it. If you enjoyed this and want more follow my blog, 
share it on social media and leave a comment below saying what you liked. If you didn’t like it or think it’s needs improving leave a comment below saying what and why. I have one new tutorial part out every Wednesday at 1PM (GMT) so stay tuned.

Keep an eye on my blog as I have more coming up soon, I might soon release an extra bit for this tutorial, and have a follow up for this as well.