• Stars
    star
    130
  • Rank 271,754 (Top 6 %)
  • Language
    C#
  • Created over 6 years ago
  • Updated about 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A signed distance function generator running inside Unity

sdf-gen-unity

A signed distance function generator running inside Unity. An example result raymarched scene can be found here or here.

It lets the user make and combine distance functions to make interesting scenes, inside an intuitive editor such as Unity. It tries to optimize the code for specific known cases (for example, it tries to prevent using matrices when dealing with planes), but it is far from complete.

It also features a generic, dynamic raymarching renderer inside Unity's editor so that composing the final SDF is easy. However, because it is generic it is also very slow (unless using the optimized output code), so it uses an iterative approach to converge to the solution.

It can output GLSL and HLSL code.

As an example, it converts the following scene:

Into the following code:

const mat4 tr[45] = mat4[45](
	mat4(.999, .0, .055, .0, .0, 1.0, .0, .0, -.055, .0, .999, .0, -1.509, .14, .498, 1.0),
	mat4(.795, .934, 2.28, .0, -.491, 1.642, -1.25, .0, -1.401, -.045, 1.732, .0, -.397, -.911, -7.876, 1.0),
	mat4(.5, .0, .0, .0, .0, .137, -.104, .0, .0, .029, .489, .0, -.8, -.064, .867, 1.0),
	mat4(1.128, .386, .417, .0, -.926, .053, 1.543, .0, 1.235, -.313, .775, .0, -.769, -1.532, -2.843, 1.0),
	mat4(-1.008, .237, -1.253, .0, -1.259, .149, 1.228, .0, 1.027, .415, .275, .0, 4.273, -.714, -.96, 1.0),
	mat4(-1.633, -.219, .498, .0, .244, .173, 1.651, .0, -.964, .415, -.425, .0, 3.007, -.072, -3.193, 1.0),
	mat4(-.526, -.46, -.495, .0, -1.791, .161, -.242, .0, .411, .112, -1.689, .0, 5.514, .189, 1.112, 1.0),
	mat4(.788, .097, .425, .0, -.135, .792, .022, .0, -.418, -.073, .795, .0, 1.929, -6.665, -.972, 1.0),
	mat4(.203, .084, .048, .0, -.057, .293, -.032, .0, -.028, .013, .407, .0, -.895, .281, 1.418, 1.0),
	mat4(.149, .025, -.291, .0, .07, .222, .18, .0, .135, -.143, .228, .0, -.128, .448, .615, 1.0),
	mat4(.163, -.007, .238, .0, -.015, .102, .035, .0, -.23, -.012, .166, .0, -.815, .176, -.268, 1.0),
	mat4(1.68, -.01, .848, .0, -.871, .133, 1.509, .0, -.276, -.482, .4, .0, -5.624, -1.2, .976, 1.0),
	mat4(-1.288, -.085, -1.277, .0, -1.377, .184, 1.044, .0, .314, .457, -.658, .0, 2.367, .783, 2.615, 1.0),
	mat4(-.526, -.46, -.495, .0, -1.791, .161, -.242, .0, .411, .112, -1.689, .0, 1.346, .968, -.74, 1.0),
	mat4(.649, .468, -.157, .0, -1.578, .171, .798, .0, .862, -.04, 1.579, .0, .804, -1.56, 3.123, 1.0),
	mat4(-.446, -.32, 1.219, .0, -1.751, .078, -.321, .0, .016, -.369, -1.124, .0, -1.128, -.361, -6.142, 1.0),
	mat4(1.533, .154, .696, .0, -.87, .377, .718, .0, -.329, -.281, 1.342, .0, -4.104, -1.442, -.118, 1.0),
	mat4(1.853, -.102, -.211, .0, .221, -.014, 1.757, .0, -.392, -.489, -.008, .0, -1.772, -1.406, 6.376, 1.0),
	mat4(-.556, -.453, -.525, .0, -.17, -.141, 1.687, .0, -1.815, .152, .003, .0, -1.992, -.067, 6.05, 1.0),
	mat4(-.943, -.128, .043, .0, -.107, 1.049, .137, .0, -.059, .146, -.94, .0, 1.858, .33, -1.42, 1.0),
	mat4(.7, .065, .111, .0, -.117, .263, -.261, .0, -.161, .092, .671, .0, -1.761, -.553, -.067, 1.0),
	mat4(1.676, .466, 1.232, .0, -1.862, .058, 1.912, .0, 1.213, -.556, 1.231, .0, -3.822, -1.844, -6.583, 1.0),
	mat4(-1.467, .491, -1.337, .0, -1.788, .06, 1.971, .0, 1.549, .534, 1.009, .0, 6.023, -1.973, -.383, 1.0),
	mat4(-2.494, -.141, 1.034, .0, .951, .2, 2.324, .0, -.79, .686, -.467, .0, 6.624, -.322, -6.471, 1.0),
	mat4(-1.116, -.568, -1.242, .0, -2.513, .31, .163, .0, .432, .334, -2.263, .0, 7.905, .708, 4.921, 1.0),
	mat4(-.025, -.278, 1.937, .0, -.454, 1.573, .319, .0, -1.912, -.37, -.101, .0, .038, -4.893, -1.369, 1.0),
	mat4(.326, .111, .293, .0, -.106, .197, -.236, .0, -.365, .042, .33, .0, -1.141, -.145, -1.004, 1.0),
	mat4(1.01, .023, 1.506, .0, -1.623, .004, .939, .0, .032, -.499, .078, .0, -4.952, -.781, -2.879, 1.0),
	mat4(-1.354, .304, -.64, .0, -.774, .034, 1.62, .0, 1.106, .396, .35, .0, 2.953, -1.14, 2.649, 1.0),
	mat4(-1.462, -.104, 1.084, .0, .892, .238, 1.325, .0, -.851, .427, -.474, .0, 6.541, .212, -.951, 1.0),
	mat4(-1.166, -.349, -.663, .0, -1.442, .328, .007, .0, .463, .142, -1.648, .0, 3.098, 1.04, 2.74, 1.0),
	mat4(.024, .494, .28, .0, -1.723, -.028, .764, .0, .829, -.074, 1.579, .0, .498, -2.115, -.172, 1.0),
	mat4(.795, .0, -.714, .0, .302, 3.241, .336, .0, .647, -1.512, .721, .0, -.378, -3.143, .939, 1.0),
	mat4(.28, .504, 2.966, .0, -.047, 1.821, -.83, .0, -1.66, .033, .523, .0, 1.505, 4.294, -7.819, 1.0),
	mat4(.5, .0, .0, .0, .0, .137, -.104, .0, .0, .029, .489, .0, -.805, -.247, .582, 1.0),
	mat4(1.128, .386, .417, .0, -.926, .053, 1.543, .0, 1.235, -.313, .775, .0, -.769, -1.532, -2.843, 1.0),
	mat4(-1.008, .237, -1.253, .0, -1.259, .149, 1.228, .0, 1.027, .415, .275, .0, 4.273, -.714, -.96, 1.0),
	mat4(-1.633, -.219, .498, .0, .244, .173, 1.651, .0, -.964, .415, -.425, .0, 3.007, -.072, -3.193, 1.0),
	mat4(-.526, -.46, -.495, .0, -1.791, .161, -.242, .0, .411, .112, -1.689, .0, 5.514, .189, 1.112, 1.0),
	mat4(1.43, -.088, -1.481, .0, -.092, 1.769, -.567, .0, .828, .35, 2.494, .0, -1.382, -4.146, -2.058, 1.0),
	mat4(.461, .046, -.065, .0, -.193, .102, -.182, .0, -.02, .084, .259, .0, -.378, -.212, .663, 1.0),
	mat4(1.128, .386, .417, .0, -.926, .053, 1.543, .0, 1.235, -.313, .775, .0, -.769, -1.532, -2.843, 1.0),
	mat4(-1.008, .237, -1.253, .0, -1.259, .149, 1.228, .0, 1.027, .415, .275, .0, 4.057, -.994, -1.057, 1.0),
	mat4(-1.633, -.219, .498, .0, .244, .173, 1.651, .0, -.964, .415, -.425, .0, 3.007, -.072, -3.193, 1.0),
	mat4(-.526, -.46, -.495, .0, -1.791, .161, -.242, .0, .411, .112, -1.689, .0, 5.374, .102, 1.328, 1.0)
);


float sdf_generated(vec3 p)
{
	vec3 wsPos = vec3(.0,.0,.0);
	float stack[12];
	vec4 pStack[12];
	pStack[0] = vec4(p, 1.0);
	pStack[0] = (pStack[0] * vec4(1.0,.98,1.0,1.0));
	pStack[1] = pStack[0];
	pStack[2] = (tr[0] * pStack[1]);
	pStack[2].xz = pModPolar(pStack[2].xz , 8.0);
	pStack[3] = (tr[1] * pStack[2]);
	wsPos = (tr[2] * pStack[3]).xyz;
	stack[3] = fBox(wsPos);
	wsPos = (tr[3] * pStack[3]).xyz;
	stack[3] = max(stack[3],frPlane(wsPos));
	wsPos = (tr[4] * pStack[3]).xyz;
	stack[3] = max(stack[3],frPlane(wsPos));
	wsPos = (tr[5] * pStack[3]).xyz;
	stack[3] = max(stack[3],frPlane(wsPos));
	wsPos = (tr[6] * pStack[3]).xyz;
	stack[3] = max(stack[3],frPlane(wsPos));
	stack[2] = stack[3];
	pStack[4] = (tr[7] * pStack[1]);
	pStack[5] = pStack[4];
	pStack[6] = pStack[5];
	wsPos = (tr[8] * pStack[6]).xyz;
	stack[6] = fBox(wsPos);
	wsPos = (tr[9] * pStack[6]).xyz;
	stack[6] = min(stack[6],fBox(wsPos));
	wsPos = (tr[10] * pStack[5]).xyz;
	stack[5] = max(-stack[6],fBox(wsPos));
	wsPos = (tr[11] * pStack[4]).xyz;
	stack[4] = max(stack[5],frPlane(wsPos));
	wsPos = (tr[12] * pStack[4]).xyz;
	stack[4] = max(stack[4],frPlane(wsPos));
	wsPos = (tr[13] * pStack[4]).xyz;
	stack[4] = max(stack[4],frPlane(wsPos));
	wsPos = (tr[14] * pStack[4]).xyz;
	stack[4] = max(stack[4],frPlane(wsPos));
	wsPos = (tr[15] * pStack[4]).xyz;
	stack[4] = max(stack[4],frPlane(wsPos));
	wsPos = (tr[16] * pStack[4]).xyz;
	stack[4] = max(stack[4],frPlane(wsPos));
	wsPos = (tr[17] * pStack[4]).xyz;
	stack[4] = max(stack[4],frPlane(wsPos));
	wsPos = (tr[18] * pStack[4]).xyz;
	stack[4] = max(stack[4],frPlane(wsPos));
	stack[1] = min(stack[2],stack[4]);
	pStack[7] = (tr[19] * pStack[1]);
	pStack[7].xz = pModPolar(pStack[7].xz , 10.0);
	wsPos = (tr[20] * pStack[7]).xyz;
	stack[7] = fBox(wsPos);
	wsPos = (tr[21] * pStack[7]).xyz;
	stack[7] = max(stack[7],frPlane(wsPos));
	wsPos = (tr[22] * pStack[7]).xyz;
	stack[7] = max(stack[7],frPlane(wsPos));
	wsPos = (tr[23] * pStack[7]).xyz;
	stack[7] = max(stack[7],frPlane(wsPos));
	wsPos = (tr[24] * pStack[7]).xyz;
	stack[7] = max(stack[7],frPlane(wsPos));
	stack[1] = min(stack[1],stack[7]);
	pStack[8] = (tr[25] * pStack[1]);
	pStack[8].xz = pModPolar(pStack[8].xz , 5.0);
	wsPos = (tr[26] * pStack[8]).xyz;
	stack[8] = fBox(wsPos);
	wsPos = (tr[27] * pStack[8]).xyz;
	stack[8] = max(stack[8],frPlane(wsPos));
	wsPos = (tr[28] * pStack[8]).xyz;
	stack[8] = max(stack[8],frPlane(wsPos));
	wsPos = (tr[29] * pStack[8]).xyz;
	stack[8] = max(stack[8],frPlane(wsPos));
	wsPos = (tr[30] * pStack[8]).xyz;
	stack[8] = max(stack[8],frPlane(wsPos));
	wsPos = (tr[31] * pStack[8]).xyz;
	stack[8] = max(stack[8],frPlane(wsPos));
	stack[1] = min(stack[1],stack[8]);
	pStack[9] = (tr[32] * pStack[1]);
	pStack[9].xz = pModPolar(pStack[9].xz , 6.0);
	pStack[10] = (tr[33] * pStack[9]);
	wsPos = (tr[34] * pStack[10]).xyz;
	stack[10] = fBox(wsPos);
	wsPos = (tr[35] * pStack[10]).xyz;
	stack[10] = max(stack[10],frPlane(wsPos));
	wsPos = (tr[36] * pStack[10]).xyz;
	stack[10] = max(stack[10],frPlane(wsPos));
	wsPos = (tr[37] * pStack[10]).xyz;
	stack[10] = max(stack[10],frPlane(wsPos));
	wsPos = (tr[38] * pStack[10]).xyz;
	stack[10] = max(stack[10],frPlane(wsPos));
	stack[9] = stack[10];
	stack[1] = min(stack[1],stack[9]);
	pStack[11] = (tr[39] * pStack[1]);
	wsPos = (tr[40] * pStack[11]).xyz;
	stack[11] = fBox(wsPos);
	wsPos = (tr[41] * pStack[11]).xyz;
	stack[11] = max(stack[11],frPlane(wsPos));
	wsPos = (tr[42] * pStack[11]).xyz;
	stack[11] = max(stack[11],frPlane(wsPos));
	wsPos = (tr[43] * pStack[11]).xyz;
	stack[11] = max(stack[11],frPlane(wsPos));
	wsPos = (tr[44] * pStack[11]).xyz;
	stack[11] = max(stack[11],frPlane(wsPos));
	stack[1] = min(stack[1],stack[11]);
	stack[0] = max(stack[1],dot(pStack[0].xyz - vec3(1.24,.07,2.43), vec3(-.129,-.864,.486)));
	stack[0] = max(stack[0],dot(pStack[0].xyz - vec3(-.2,-1.41,1.48), vec3(.107,-.943,-.314)));
	return stack[0];
}

Another example scene:


float sdf(vec3 p)
{
	vec3 wsPos = vec3(.0,.0,.0);
	vec4 a0 = vec4(p, 1.0);
	a0.xz = abs(a0.xz) * vec2(-1.0,1.0);
	vec4 a1 = a0 - vec4(6.24,.0,2.5,.0);
	a1.xz = pModPolar(a1.xz , 4.0);
	float d1 = dot(a1.xyz - vec3(11.49,.0,.0), vec3(-1.0,.0,.0));
	vec4 a2 = a1 - vec4(11.02,2.15,7.28,.0);
	a2.z = domainRepeat1D(a2.z , 2.0);
	vec4 a3 = a2;
	wsPos = a3.xyz - vec3(-2.64,5.05,.0);
	float d3 = fBox(wsPos,vec3(.5,.5,.228));
	wsPos = a3.xyz - vec3(-2.275,5.05,.0);
	d3 = min(d3,fBox(wsPos,vec3(.383,.383,.175)));
	wsPos = a3.xyz - vec3(-2.64,6.97,.0);
	d3 = min(d3,fBox(wsPos,vec3(.5,.283,.111)));
	wsPos = a2.xyz - vec3(-1.28,6.38,.287);
	float d2 = max(-d3,fBox(wsPos,vec3(1.5,1.893,6.673)));
	d1 = min(d1,d2);
	vec4 a4 = a1 - vec4(9.18,-4.5,-.032,.0);
	a4.y = domainRepeat1D(a4.y , 4.5);
	vec4 a5 = a4;
	a5.z = domainRepeat1D(a5.z , 2.5);
	vec4 a6 = a5;
	a6.x = -a6.x;
	vec4 a7 = a6;
	vec4 a8 = a7 - vec4(.05,-.62,.0,.0);
	a8.xyz = rdZ(a8.xyz);
	wsPos = a8.xyz;
	float d8 = (fCylinder(wsPos, 1.398,1.361)*.75);
	wsPos = a8.xyz - vec3(.0,.152,.0);
	d8 = max(-d8,(fCylinder(wsPos, 1.434,.531)*.75));
	wsPos = a7.xyz - vec3(.786,.46,.0);
	float d7 = max(d8,fBox(wsPos,vec3(.523,.747,1.415)));
	vec4 a9 = a6;
	wsPos = a9.xyz - vec3(.47,1.953,.0);
	float d9 = fBox(wsPos,vec3(.5,.075,1.5));
	wsPos = a9.xyz - vec3(.58,2.03,.0);
	d9 = min(d9,fBox(wsPos,vec3(.5,.075,1.5)));
	vec4 a10 = a9 - vec4(.463,-.51,1.179,.0);
	a10.z = domainRepeat1D(a10.z , 2.35);
	wsPos = a10.xyz;
	float d10 = fBox(wsPos,vec3(.24,.033,.24));
	wsPos = a10.xyz - vec3(.0,-.093,.0);
	d10 = min(d10,fBox(wsPos,vec3(.24,.033,.24)));
	wsPos = a10.xyz - vec3(-2.8,-.03,.0);
	d10 = min(d10,fBox(wsPos,vec3(.25,.075,.25)));
	vec4 a11 = a10;
	a11.xz = pModPolar(a11.xz , 8.0);
	wsPos = a11.xyz - vec3(.002,-1.07,.0);
	float d11 = fBox(wsPos,vec3(.17,1.053,.424));
	d10 = min(d10,d11);
	d9 = min(d9,d10);
	vec4 a12 = a9 - vec4(-1.03,-.518,.0,.0);
	vec4 a13 = a12;
	a13.xyz = rdZ(a13.xyz);
	wsPos = (tr[0] * a13).xyz;
	float d13 = fCylinder(wsPos, 1.225,3.0);
	wsPos = a13.xyz;
	d13 = min(d13,fCylinder(wsPos, 1.094,2.061));
	wsPos = a12.xyz - vec3(.12,1.27,.0);
	float d12 = max(-d13,fBox(wsPos,vec3(1.5,1.355,1.551)));
	d9 = min(d9,d12);
	float d6 = min(d7,d9);
	vec4 a14 = a6 - vec4(.463,1.57,1.61,.0);
	wsPos = (tr[1] * a14).xyz;
	float d14 = fCylinder(wsPos, .105,.046);
	wsPos = (tr[2] * a14).xyz;
	d14 = min(d14,fCylinder(wsPos, .025,.582));
	d6 = min(d6,d14);
	float d5 = d6;
	float d4 = d5;
	d1 = min(d1,d4);
	float d0 = min(d1,dot(a0.xyz - vec3(.0,-2.0,.0), vec3(.0,1.0,.0)));
	d0 = min(d0, length(p - vec3(0.0, .35, .0)) - 1.5);
    d0 = min(d0, -(p.y - 11.15));
    return d0;
}