# How to create ‘Domain Warping’ with Unity

## Summary

I explain how to create an effect by using the method called ‘Domain Warping’. The ‘Domain Warping’ effect

## Samples

The sample project in GitHub:

The sample VR space in STYLY Gallery I published a sample VR space that has the boards with the domain-warping effect applied.

## What is ‘Domain Warping’?

‘Domain Warping’ is a way to render something like clouds or water by computing a certain type of noise, which is called fbm(Fractional Brownian motion). Domain warping Domain warping

## How ‘Domain Warping’ works

I explain how domain warping generates a pattern.

### Calculate the fbm associated with the pixel coordinate p

A cloud-like pattern is generated by calculating the fbm associated with the pixel coordinate p. fbm(p)

It can be described as a shader code like this:

```float2 p = i.uv * 8;
return fbm(p + 1.7);```

The visualizations of the X coordinate(p.x)  and the Y coordinate(p.y) are shown below. Visualization of p.x and p.y

### Calculate fbm(fbm(p))

By applying another fbm to fbm(p), the pattern is ‘distorted’ more and results in the shown below. Iterative application of fbm to the pixel coordinate p to generate a complicated pattern is called ‘Domain Warping’. fbm(fbm(p))

It can be described as a shader code like this:

```float2 p = i.uv * 8;
p = float2(fbm(p + 1.7), fbm( p + 9.2));
p = p * 8.0;
return fbm(p + 8.3);```

### Animate a domain warping

You can animate the pattern by adding ‘Time’ to the argument of the domain-warping function.

```float2 p = i.uv * 4;
p = float2(fbm(p + _Time.y), fbm(p));
p = p * 8.0;
return fbm(p);``` In the same way, I animated the domain-warping effect shown in this tutorial.

### Create a pattern by domain warping

Create the pattern shown below by using domain warping. Domain warping

### Apply the Mosaic effect

Apply the mosaic effect to the pattern created by domain warping. The mosaic effect

### Mask with a polka-dot pattern In order to improve visual impression, I increased the contrast by making the dot lager where the colour is bright and making the dot smaller where the colour is dark.

### Animate the pattern ~ Completion

Animate the pattern by add ‘Time’ to the argument of the fbm function. It completes the visual effect to create this time. Animate the pattern

## How to create it with Unity

I explain how to make this domain-warping effect by using Unity’s shader. Regarding the mouse operation, I assume Windows is used.

Firstly, select Create > Shader > Unlit Shader in the Project window to create a shader file. Open the created shader file and paste the below code in it.

```Shader "Unlit/DomainWarpingShader"
{
Properties
{
_GridNumber("Grid Number", Float) = 64.0
_EllipseSize("Ellipse Size", Float) = 1.0
_Speed("Speed", Float) = 1.0
_Fbm_ScaleFactor("Fbm Scale Factor", Vector) = (1.0, 1.0, 4.0, 4.0)
}
{
Tags { "RenderType"="Opaque" }
LOD 100

Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog

#include "UnityCG.cginc"

struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};

struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};

//////////////////////////////////////////////////////////////////////////////
float random(float2 st) {
return frac(sin(dot(st.xy,
float2(12.9898,78.233)))*
43758.5453123);
}

//////////////////////////////////////////////////////////////////////////////
// Based on Morgan McGuire @morgan3d
float noise (float2 st) {
float2 i = floor(st);
float2 f = frac(st);

// Four corners in 2D of a tile
float a = random(i);
float b = random(i + float2(1.0, 0.0));
float c = random(i + float2(0.0, 1.0));
float d = random(i + float2(1.0, 1.0));

float2 u = f * f * (3.0 - 2.0 * f);

return lerp(a, b, u.x) +
(c - a)* u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
}

//////////////////////////////////////////////////////////////////////////////
#define OCTAVES 6
float fbm (float2 st) {
// Initial values
float value = 0.0;
float amplitude = .5;
float frequency = 0.;
// Loop of octaves
for (int i = 0; i < OCTAVES; i++) {
value += amplitude * noise(st);
st *= 2.;
amplitude *= .5;
}
return value;
}

//////////////////////////////////////////////////////////////////////////////
// domain warping pattern
// based on : http://www.iquilezles.org/www/articles/warp/warp.htm
float pattern (float2 p, float4 scale_1, float scale_2, float4 add_1, float4 add_2) {
// first domain warping
float2 q = float2(
fbm( p + scale_1.x * add_1.xy ),
fbm( p + scale_1.y * add_1.zw )
);

// second domain warping
float2 r = float2(
fbm( p + scale_1.z * q + add_2.xy ),
fbm( p + scale_1.w * q + add_2.zw )
);

return fbm( p + scale_2 * r );
}

//////////////////////////////////////////////////////////////////////////////
float _EllipseSize;
float _GridNumber;

v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}

float2 remap(float In, float2 InMinMax, float2 OutMinMax)
{
return OutMinMax.x + (In - InMinMax.x) * (OutMinMax.y - OutMinMax.x) / (InMinMax.y - InMinMax.x);
}

float ellipse(float2 UV, float Size)
{
float d = length(2 * UV - 1);
return step(d, Size);
}

fixed2 posterize(fixed2 In, fixed Steps)
{
return floor(In * Steps) / Steps;
}

//////////////////////////////////////////////////////////////////////////////
float _Speed;
float4 _Fbm_ScaleFactor;
float _EllipseContrast;

fixed4 frag (v2f i) : SV_Target
{
#define TIME_1 (_Time.y * (-0.1) * _Speed)
#define TIME_2 (_Time.y * (-0.3) * _Speed)
#define TIME_3 (_Time.y * (0.15) * _Speed)
#define SIN_TIME_3 (4.0 * sin(TIME_3))

//#define ScaleFactor_1 float4(1.0, 1.0, 4.0, 4.0)
#define ScaleFactor_1 _Fbm_ScaleFactor
#define ScaleFactor_2 4.0
#define AddFactor_1 float4(TIME_1, TIME_2, 5.2, 1.3)
#define AddFactor_2 float4(SIN_TIME_3, 9.2, 9.3, 2.8)

#define GRID_N _GridNumber
#define UV_Repeat frac(i.uv * GRID_N)
#define UV_Posterized posterize(i.uv, GRID_N)

// get domain warping value

// remap value
domainWarping = remap(domainWarping, float2(0.39, 0.83), float2(0, 1));

return ellipse(UV_Repeat, domainWarping * _EllipseSize) * tex2D(_GradientTex, domainWarping);
}
ENDCG
}
}
}
```

### Create a material

Right-click the shader file and select Create >  Material. Create a material The material created

### Create a board object

I explain how to create a board object to attach the created material to. Create a Plane object. The Plane object created

### Assign the material to the board object

Drag the material into the created Plane object to assign. Assign the material to the Plane object.

The domain-warping effect has been applied to the board. It should look like the shown below. How it looks after the material is applied.

### Colour the domain-warping effect

Next, colour this domain-warping effect. You can colour this shader by specifying a gradation texture.  Assign the gradation texture to the material

By applying the texture, the pattern is coloured. It should look like the shown below. How it looks after applying a gradation texture

### How is it coloured?

As shown below, this domain-warping shader applies the colour on the left to the larger dots and the colour on the right to the smaller dots. Colour the pattern by using a gradation texture.