BlinkScript in Nuke is a powerful way to create custom GPU-accelerated tools, and here’s a fun example: BugSwarm. This script simulates a swarm of tiny bugs flying randomly inside a defined area, adding life and motion to a shot without the need for external particle plugins.
This blink script works only Nuke 16 and above!!
Why It’s Interesting
- It’s a great example of how BlinkScript can mimic particle systems inside Nuke.
- The math is lightweight, meaning it runs fast on the GPU.
- Parameters are fully customizable, making it easy to adjust the mood—from a slow drifting swarm to chaotic buzzing.
Creative Uses
- Add background detail to an outdoor shot.
- Simulate gnats, flies, or tiny floating debris.
- Combine with glow or color shifts for surreal or magical effects.
Full Code
// BugSwarm: Simulates bugs flying randomly in a bounded area
kernel BugSwarm : ImageComputationKernel<ePixelWise>
{
Image<eWrite, eAccessPoint> dst;
param:
int nBugs;
float2 center;
float areaRadius;
float bugSize;
float time;
int seed;
float speed;
float turbulence;
float brightness;
void define() {
defineParam(nBugs, "NumBugs", 80);
defineParam(center, "SwarmCenter", float2(400.0f, 400.0f), eParamProxyScale);
defineParam(areaRadius, "SwarmRadius", 150.0f, eParamProxyScale);
defineParam(bugSize, "BugSize", 4.0f, eParamProxyScale);
defineParam(time, "Time", 0.0f);
defineParam(seed, "Seed", 777);
defineParam(speed, "FlySpeed", 40.0f);
defineParam(turbulence, "Turbulence", 20.0f);
defineParam(brightness, "Brightness", 1.5f);
}
inline float randF(int s) {
s = (s << 13) ^ s;
return (1.0f - ((s * (s * s * 15731 + 789221) + 1376312589)
& 0x7fffffff) / 1073741824.0f);
}
inline float falloff(float2 pos, float2 c, float size) {
float d = length(pos - c);
return exp(-(d * d) / (size * size));
}
// Bug colour: dark with slight highlight
inline float3 bugColour(float flicker) {
float3 dark = float3(0.05f, 0.05f, 0.05f);
float3 highlight = float3(0.2f, 0.2f, 0.1f);
return dark + highlight * flicker;
}
void process(int2 pos) {
float2 uv = float2(pos.x, pos.y);
float3 finalCol = float3(0.0f);
for (int i = 0; i < nBugs; i++) {
int pSeed = seed + i * 71;
// Each bug gets its own orbit radius + speed
float orbitR = areaRadius * (0.4f + 0.6f * randF(pSeed + 33));
float orbitSpeed = speed * (0.5f + randF(pSeed + 44));
// Bug moves in circular + noisy path
float angle = time * orbitSpeed * 0.01f + randF(pSeed + 55) * 6.28318f;
float2 posBug = center + float2(cos(angle), sin(angle)) * orbitR;
// Add turbulence jitter
posBug += float2(
sin(time * 3.1f + i) * turbulence,
cos(time * 2.3f + i * 1.3f) * turbulence
) * 0.2f;
// Wing flicker
float flicker = 0.5f + 0.5f * sin(time * 15.0f + i);
// Colour + fade
float3 col = bugColour(flicker);
float density = falloff(uv, posBug, bugSize);
finalCol += col * density;
}
finalCol *= brightness;
SampleType(dst) result(0.0f);
result[0] = finalCol.x;
result[1] = finalCol.y;
result[2] = finalCol.z;
dst() = result;
}
};
