Skip to content

Instantly share code, notes, and snippets.

@hecomi
Created March 7, 2023 15:31
Show Gist options
  • Save hecomi/a3230323390aa8d4b975f2d72a822c93 to your computer and use it in GitHub Desktop.
Save hecomi/a3230323390aa8d4b975f2d72a822c93 to your computer and use it in GitHub Desktop.
Create a distance function using ChatGPT API
const https = require('https');
const apiKey = require('./secret.js').key;
const input = process.argv.length > 2 ? process.argv[2] : 'sphere';
const options = {
hostname: 'api.openai.com',
port: 443,
path: '/v1/chat/completions',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + apiKey,
},
};
const data = {
model: 'gpt-3.5-turbo',
messages: [
{
'role': 'system',
'content': `
Generate a distance function for raymarching.
The code is written in HLSL (for Unity), not GLSL.
Be careful to match the number of arguments given to functions.
Some Unity built-in parameters like _Time are given.
The name of the distance function should be DistanceFunction.
The other function names should also be Pascal case.
The single float3 variable named "pos" is passed as input to the function.
There must be no natural language in the response. Just output only HLSL code.
There should be no comments in the code.
The following functions are included:
float Rand(float2 seed)
{
return frac(sin(dot(seed, float2(12.9898, 78.233))) * 43758.5453);
}
inline float Mod(float a, float b)
{
return frac(abs(a / b)) * abs(b);
}
inline float2 Mod(float2 a, float2 b)
{
return frac(abs(a / b)) * abs(b);
}
inline float3 Mod(float3 a, float3 b)
{
return frac(abs(a / b)) * abs(b);
}
inline float SmoothMin(float d1, float d2, float k)
{
float h = exp(-k * d1) + exp(-k * d2);
return -log(h) / k;
}
inline float Repeat(float pos, float span)
{
return Mod(pos, span) - span * 0.5;
}
inline float2 Repeat(float2 pos, float2 span)
{
return Mod(pos, span) - span * 0.5;
}
inline float3 Repeat(float3 pos, float3 span)
{
return Mod(pos, span) - span * 0.5;
}
inline float3 Rotate(float3 p, float angle, float3 axis)
{
float3 a = normalize(axis);
float s = sin(angle);
float c = cos(angle);
float r = 1.0 - c;
float3x3 m = float3x3(
a.x * a.x * r + c,
a.y * a.x * r + a.z * s,
a.z * a.x * r - a.y * s,
a.x * a.y * r - a.z * s,
a.y * a.y * r + c,
a.z * a.y * r + a.x * s,
a.x * a.z * r + a.y * s,
a.y * a.z * r - a.x * s,
a.z * a.z * r + c
);
return mul(m, p);
}
inline float3 TwistY(float3 p, float power)
{
float s = sin(power * p.y);
float c = cos(power * p.y);
float3x3 m = float3x3(
c, 0.0, -s,
0.0, 1.0, 0.0,
s, 0.0, c
);
return mul(m, p);
}
inline float3 TwistX(float3 p, float power)
{
float s = sin(power * p.y);
float c = cos(power * p.y);
float3x3 m = float3x3(
1.0, 0.0, 0.0,
0.0, c, s,
0.0, -s, c
);
return mul(m, p);
}
inline float3 TwistZ(float3 p, float power)
{
float s = sin(power * p.y);
float c = cos(power * p.y);
float3x3 m = float3x3(
c, s, 0.0,
-s, c, 0.0,
0.0, 0.0, 1.0
);
return mul(m, p);
}
inline float Sphere(float3 pos, float radius)
{
return length(pos) - radius;
}
inline float RoundBox(float3 pos, float3 size, float round)
{
float3 d = abs(pos) - size;
return length(max(abs(pos) - size, 0.0)) - round
+ min(max(d.x, max(d.y, d.z)), 0.0);
}
inline float Box(float3 pos, float3 size)
{
float3 d = abs(pos) - size;
return length(max(abs(pos) - size, 0.0))
+ min(max(d.x, max(d.y, d.z)), 0.0);
}
inline float Torus(float3 pos, float2 radius)
{
float2 r = float2(length(pos.xy) - radius.x, pos.z);
return length(r) - radius.y;
}
inline float Plane(float3 pos, float3 dir)
{
return dot(pos, dir);
}
inline float Cylinder(float3 pos, float2 r)
{
float2 d = abs(float2(length(pos.xy), pos.z)) - r;
return min(max(d.x, d.y), 0.0) + length(max(d, 0.0)) - 0.1;
}
inline float HexagonalPrismX(float3 pos, float2 h)
{
float3 p = abs(pos);
return max(
p.x - h.y,
max(
(p.z * 0.866025 + p.y * 0.5),
p.y
) - h.x
);
}
inline float HexagonalPrismY(float3 pos, float2 h)
{
float3 p = abs(pos);
return max(
p.y - h.y,
max(
(p.z * 0.866025 + p.x * 0.5),
p.x
) - h.x
);
}
inline float HexagonalPrismZ(float3 pos, float2 h)
{
float3 p = abs(pos);
return max(
p.z - h.y,
max(
(p.x * 0.866025 + p.y * 0.5),
p.y
) - h.x
);
}
`
},
{
'role': 'user',
'content': 'sphere with 1.0m radius',
},
{
'role': 'assistant',
'content': `
inline float DistanceFunction(float3 pos)
{
return Sphere(pos, 1.0);
}
`
},
{
'role': 'user',
'content': 'morphing from sphere to many cubes',
},
{
'role': 'assistant',
'content': `
inline float DistanceFunction(float3 pos)
{
float t = _Time.x;
float a = 6 * PI * t;
float s = pow(sin(a), 2.0);
float d1 = Sphere(pos, 0.75);
float d2 = RoundBox(
Repeat(pos, 0.2),
0.1 - 0.1 * s,
0.1 / length(pos * 2.0));
return lerp(d1, d2, s);
}
`
},
{
'role': 'user',
'content': input,
},
],
};
const req = https.request(options, res => {
let body = [];
res.on('data', chunk => body.push(chunk));
res.on('end', () => {
const output = Buffer.concat(body).toString();
var json = JSON.parse(output);
console.log(json.choices[0].message.content);
})
});
req.on('error', e => {
console.error(e);
});
req.write(JSON.stringify(data));
req.end();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment