Skip to content

Instantly share code, notes, and snippets.

@ku6ryo
Last active November 10, 2021 10:15
Show Gist options
  • Select an option

  • Save ku6ryo/6597cf8be487b4d71a3536a27235389a to your computer and use it in GitHub Desktop.

Select an option

Save ku6ryo/6597cf8be487b4d71a3536a27235389a to your computer and use it in GitHub Desktop.
Voronoi3dWorldPos.shader
// This shader is written by refering the below articles.
// Expanded the 2D voronoi example shader to 3D use case.
// The base of the distance calculation is world position.
// So the voronoi pattern moves is an object moves.
// https://www.ronja-tutorials.com/post/028-voronoi-noise/
// https://www.ronja-tutorials.com/post/024-white-noise/
Shader "ku6ryo/Voronoi3dWorldPos" {
Properties {
_CellSize ("Cell Size", Range(0, 2)) = 2
}
SubShader {
Tags{ "RenderType"="Opaque" "Queue"="Geometry"}
CGPROGRAM
#pragma surface surf Standard fullforwardshadows
#pragma target 3.0
float _CellSize;
struct Input {
float3 worldPos;
};
float rand3dTo1d(float3 value, float3 dotDir = float3(12.9898, 78.233, 37.719)){
//make value smaller to avoid artefacts
float3 smallValue = sin(value);
//get scalar value from 3d vector
float random = dot(smallValue, dotDir);
//make value more random by making it bigger and then taking the factional part
random = frac(sin(random) * 143758.5453);
return random;
}
float3 rand3dTo3d(float3 value){
return float3(
rand3dTo1d(value, float3(12.989, 78.233, 37.719)),
rand3dTo1d(value, float3(39.346, 11.135, 83.155)),
rand3dTo1d(value, float3(73.156, 52.235, 09.151))
);
}
float2 voronoiNoise(float3 value){
float3 baseCell = floor(value);
float minDistToCell = 10;
float3 closestCell;
[unroll]
for(int x=-1; x<=1; x++){
[unroll]
for(int y=-1; y<=1; y++){
[unroll]
for(int z=-1; z<=1; z++){
float3 cell = baseCell + float3(x, y, z);
float3 cellPosition = cell + rand3dTo3d(cell);
float3 toCell = cellPosition - value;
float distToCell = length(toCell);
if(distToCell < minDistToCell){
minDistToCell = distToCell;
closestCell = cell;
}
}
}
}
float random = rand3dTo1d(closestCell);
return float2(minDistToCell, random);
}
void surf (Input i, inout SurfaceOutputStandard o) {
float3 value = i.worldPos.xyz / _CellSize;
float noise = voronoiNoise(value).y;
o.Albedo = noise;
}
ENDCG
}
FallBack "Standard"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment