Procedural Generation Tutorial Brick Texture - Part 4 of 4
The end result of the full tutorial.
At the end of Part 4 we will have produced this (See image 1).
Image 1
Before you start you should know these things:
You should have gone through and completed ‘Part 3’ of this tutorial 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/2016/11/procedural-generation-tutorial-brick_51.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 4 and the completed project file of Part 4.
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 4 and the completed project file of Part 4.
In this tutorial series, we will be creating a simple brick texture using code, a slight variation from the simple checker board pattern. We will learn some more programming principals.
We will:
- Recode the brick function creating the right-side brick
- Create a switch statement
- Tidy up code by putting left and right brick in separate functions
Step 1:- Theory
Step 2:- Demonstrating SetPixels32
Code:
void Start()
{
...
CreatePattern();
}
void CreateMortarColour(Texture2D tex)
{
...
//GetComponent<Renderer>().material.
mainTexture = tex;
}
Code:
void DrawHalfBrick()
{
}
...
void CreatePattern()
{
...
if (((i + j) % 2) == 1)
{
DrawHalfBrick();
mainTexture.SetPixels32(i * blockWidth, j
* blockHeight, blockWidth,
blockHeight, colour0Arr);
}
else
{
DrawHalfBrick();
mainTexture.SetPixels32(i * blockWidth, j
* blockHeight, blockWidth,
blockHeight, colour1Arr);
}
...
}
Code:
public Color32 [] tempBrickPixels;
...
void DrawHalfBrick()
{
tempBrickPixels =
leftBrickTexture.GetPixels32();
}
Figure 1.0
Step 3:- Making the function more reusable
Code:
void DrawHalfBrick()
{
Color32 [] tempBrickPixels =
leftBrickTexture.GetPixels32();
}
Code:
void DrawHalfBrick(Texture2D fromTexture)
{
Color32 [] tempBrickPixels =
fromTexture.GetPixels32();
}
...
void CreatePattern()
{
...
if (((i + j) % 2) == 1)
{
DrawHalfBrick(leftBrickTexture);
//mainTexture.SetPixels32(
i * blockWidth,
j * blockHeight,
blockWidth, blockHeight,
colour1Arr);
}
...
}
Code:
void DrawHalfBrick(Texture2D fromTexture)
{
Color32 [] tempBrickPixels =
fromTexture.GetPixels32();
mainTexture.SetPixels32(i * blockWidth,
j * blockWidth, blockWidth,
blockHeight, colour1Arr);
}
Code:
void DrawHalfBrick(Texture2D fromTexture,
Texture2D toTexture)
{
Color32 [] tempBrickPixels =
fromTexture.GetPixels32();
toTexture.SetPixels32(i * blockWidth,
j * blockWidth, blockWidth,
blockHeight, colour1Arr);
}
...void CreatePattern()
{
...
if (((i + j)))
{
DrawHalfBrick(leftBrickTexture,
mainTexture);
//mainTexture.SetPixels(i * blockWidth,
j * blockHeight,
blockWidth,
blockHeight,
colour0Arr);
}
...
}
Next, we need to parse a few more variables to our function. We need to parse the ‘i’ and ‘j’ values that ‘SetPIxels32’ uses in this line. This is because ‘i’ and ‘j’ are out of context and variables that have no value in this function. In the for loop they are temporary variables that only exist in that function. This is a very simple fix, we add two more parse variable parameters to the function, ‘i’ and ‘j’ both as integers.
Code:
void DrawHalfBrick(Texture2D fromTexture,
Texture2D toTexture,
int i, int j)
{
Color32 [] tempBrickPixels =
fromTexture.GetPixels32();
toTexture.SetPixels32(i * blockWidth,
j * blockWidth, blockWidth,
blockHeight, colour1Arr);
}
...
void CreatePattern()
{
...
if (((i + j)))
{
DrawHalfBrick(leftBrickTexture,
mainTexture, i, j);
//mainTexture.SetPixels(i * blockWidth,
j * blockHeight,
blockWidth,
blockHeight,
colour0Arr);
}
...
}
Code:
void DrawHalfBrick(Texture2D fromTexture,
Texture2D toTexture,
int i, int j)
{
Color32 [] tempBrickPixels =
fromTexture.GetPixels32();
toTexture.SetPixels32(i * blockWidth,
j * blockWidth, blockWidth,
blockHeight, tempBrickPixels);
}
Figure 1.1: I set the texture size to 16 by 16, blockWidth
and blockHeight to 4 and bricksX to 2, and bricksY to 4.
Code:
void CreatePattern()
{
...
if (((i + j)))
{
DrawHalfBrick(leftBrickTexture,
mainTexture, i, j);
//mainTexture.SetPixels(i * blockWidth,
j * blockHeight,
blockWidth,
blockHeight,
colour0Arr);
}
else
{
DrawHalfBrick(rightBrickTexture,
mainTexture, i, j);
//mainTexture.SetPixels(i * blockWidth,
j * blockHeight,
blockWidth,
blockHeight,
colour1Arr);
}
...
}
Figure 1.2
Step 5:- Fixing a few bugs
Figure 1.2.5
Code:
void SetMainTextureSize()
{
...
SetBlockSize(brickTexWidth,
brickTexHeight);
}
void SetBlockSize(int w, int h)
{
blockWidth = w;
blockHeight = h;
}
Code:
void Start()
{
...
//ConvertBricksToSquares(bricksX, bricksY);
...
}...
void SetMainTextureSize()
{
mainTexture = new Texture2D(mainTexWidth,
mainTexHeight);
ConvertBricksToSquares(bricksX, brickY);
...
}
Figure 1.4: (L) tex resolution 128 x 128, bricksX 8, bricksY 16, mortar thickness width and height 2. (R) tex resolution 64 x 64, bricksX 2, bricksY 4, mortar thickness width and height 1.
We have learnt how to:
- Write and use a switch statement
- Perform a task based on a given switch statement case
No comments:
Post a Comment