Topics for v2.x

Topics for v1.x

Distance fields

Using the shader node a lot of different effects can be created.

One method of creating spectacular scenes is using distance fields / raymarching. For example the Meta ice and To the road of ribbon scenes are created using this method. A good detailed description can be found in Rendering Worlds With Two Triangles and in Potatro, RayMarching and DistanceFields : a story of SphereTracing

The main shader loop in a distance fields shader looks like

float3 point = rayOrigin, rayDir;
float t = 0.0;
for (int stepNr=0; stepNr<NUMSTEPS; stepNr++)
{
	float dist = Dist(point);
	if (dist < 0.1)
		break;
	point = point + dist*rayDir;
	t += dist;
}

For distance function here is a few things you can try

float DistToPlane(float3 p, float3 normal, float dist)
{
	return dot(p,normal)-dist;
}
float DistToSphere(float3 p, float radius)
{
	return length(p) - radius;
}
float DistToCylinderY(float3 p, float radius)
{
	return length(float2(p.x, p.z)) - radius;
}
float DistToConeY(float3 p, float angle)
{
	return length(float2(p.x, p.z))*cos(angle) - abs(p.y)*sin(angle);
}
float DistToCube(float3 p,float3 size)
{
    return max(max(abs(p.x)-size.x, abs(p.y)-size.y), abs(p.z)-size.z);
}
float DistToRoundedCube(float3 p, float3 boxExtents, float rad )
{
	return length(max(abs(p)-box + float3(rad), 0.0 ))-rad;
}
float DistToTorus(float3 p, float radiusMin, float radiusMax)
{
	return length(float2(length(float2(p.x, p.z)-radiusMax, p.y))-radiusMin;
}

To create more interesting scenes the above functions can be combined in a vararity of ways

  • Union: min(distToObject1(p), distToObject2(p))
  • Intersection: max(distToObject1(p), distToObject2(p))
  • Inverse: -distToObject1(p)
  • Subtraction: max(distToObject1(p),-distToObject2(p))

Further reading