using a GPU for OpenGL on a remote machine seems tricky

The idea was to support systems which don't have GPU's. I think it is rare for cloud services to give you GPU access, because I don't think it's possible to share access to GPU's in the same way as CPU and other resources.

I am also dreaming of a website like shadertoy that let's you program game logic along side your shader.

I think, as eiffie said, one of the main appeals for such a CPU emulator would be to run glsl-style logic alongside the shader, so as to provide you with some state between frames.

Thanks @Syntopia, of course the code was never designed to be used directly. It was just a support layer behind the glsl that the programmer would never see. Here is an example of some C++ compiled from a GLSL shader. The main thing to notice is how vector swizzle .xyzw, .rgba .etc are serialized as permute() function calls:

float sdBox(vec3 p, vec3 b) {

vec3 d = abs(p) - b;

return min(max(d.permute(0), max(d.permute(1), d.permute(2))), 0.0f) + length(max(d, 0.0f));

}

float map(vec3 pos) {

float speed = 1.0f;

vec3 grid = floor(pos);

vec3 gmod = mod(grid, 2.0f);

vec3 rmod = mod(grid, 4.0f) - 2.0f;

float tm = fract(iGlobalTime * speed);

rmod *= cos(tm * PI) - 1.0f;

float g = floor(mod(iGlobalTime * speed, 3.0f));

if (g == 0.0f) {

if (gmod.permute(1) * gmod.permute(0) == 1.0f) {

pos[2] += rmod.permute(0) * rmod.permute(1) * 0.5f;

}

} else if (g == 1.0f) {

if (gmod.permute(1) * gmod.permute(2) == 1.0f) {

pos[0] += rmod.permute(1);

}

} else if (g == 2.0f) {

if (gmod.permute(2) == 0.0f) {

pos[1] += rmod.permute(2) * rmod.permute(0) * 0.5f;

}

}

grid = floor(pos);

pos = pos - grid;

pos = pos * 2.0f - 1.0f;

float len = 0.9f;

float d = sdBox(pos, vec3(len));

bool skip = false;

if (mod(grid.permute(0), 2.0f) == 0.0f && mod(grid.permute(1), 2.0f) == 0.0f) {

skip = true;

}

if (mod(grid.permute(0), 2.0f) == 0.0f && mod(grid.permute(2), 2.0f) == 0.0f) {

skip = true;

}

if (mod(grid.permute(1), 2.0f) == 0.0f && mod(grid.permute(2), 2.0f) == 1.0f) {

skip = true;

}

if (skip) {

d = 100.0f;

vec3 off = vec3(2.0f, 0.0f, 0.0f);

for (int i = 0; i < 3; ++i) {

float a = sdBox(pos + off, vec3(len));

float b = sdBox(pos - off, vec3(len));

d = min(d, min(a, b));

off = off.permute(2, 0, 1);

}

d *= 0.5f;

} else {

d *= 0.8f;

}

return d;

}

vec3 surfaceNormal(vec3 pos) {

vec3 delta = vec3(0.01f, 0.0f, 0.0f);

vec3 normal;

normal[0] = map(pos + delta.permute(0, 1, 2)) - map(pos - delta.permute(0, 1, 2));

normal[1] = map(pos + delta.permute(1, 0, 2)) - map(pos - delta.permute(1, 0, 2));

normal[2] = map(pos + delta.permute(2, 1, 0)) - map(pos - delta.permute(2, 1, 0));

return normalize(normal);

}

float aoc(vec3 origin, vec3 ray) {

float delta = 0.05f;

const int samples = 8;

float r = 0.0f;

for (int i = 1; i <= samples; ++i) {

float t = delta * float(i);

vec3 pos = origin + ray * t;

float dist = map(pos);

float len = abs(t - dist);

r += len * pow(2.0f, -float(i));

}

return r;

}

vec3 mainImage(vec2 uv) {

vec3 eye = normalize(vec3(uv, 1.0f - dot(uv, uv) * 0.33f));

vec3 origin = vec3(0.0f);

eye = eye * yrot(iGlobalTime) * xrot(iGlobalTime);

float speed = 0.5f;

float j = iGlobalTime * speed;

float f = fract(j);

float g = 1.0f - f;

f = f * f * g + (1.0f - g * g) * f;

f = f * 2.0f - 1.0f;

float a = floor(j) + f * floor(mod(j, 2.0f));

float b = floor(j) + f * floor(mod(j + 1.0f, 2.0f));

origin.permute(0) += 0.5f + a;

origin.permute(1) += 0.5f;

origin.permute(2) += 0.5f + b;

float t = 0.0f;

float d = 0.0f;

for (int i = 0; i < 32; ++i) {

vec3 pos = origin + eye * t;

d = map(pos);

t += d;

}

vec3 worldPos = origin + eye * t;

vec3 norm = surfaceNormal(worldPos);

float prod = max(0.0f, dot(norm, -eye));

float amb = 0.0f;

vec3 ref = reflect(eye, norm);

vec3 spec = vec3(0.0f);

prod = pow(1.0f - prod, 2.0f);

vec3 col = vec3(0.1f, 0.3f, 0.5f);

spec *= col;

col = mix(col, spec, prod);

float shade = pow(max(1.0f - amb, 0.0f), 4.0f);

float fog = 1.0f / (1.0f + t * t * 0.2f) / shade;

vec3 final = col;

final = mix(final, vec3(1.0f), fog);

fog = 1.0f / (1.0f + t * t * 0.1f);

return vec3(final * fog);

}

@marius any details about how your float fob thing worked?