graphic design tool
git clone https://git.lucas.co/cce-designer.git
fix: sphere kernel colors are signed-normal — world-anchored, trackable
The sphere's default colors were absolute-value normal components
(0.35+|nx|, 0.45+|ny|, const blue): mirror-symmetric about every world
axis, landmark-free, and unlit (the scene pass is vertex-color
passthrough). On a circular silhouette that gradient gives no orbit cue,
so a world-stationary sphere perceptually reads as glued to the camera —
'the sphere rotates with the camera, the box does not' (box edges are hard
landmarks). Signed normals give every world direction its own hue, so the
colors are asymmetric and visibly track the world during an orbit.
Co-Authored-By: Claude Fable 5 <[email protected]>
default_project.json | 2 +-
nodes/sphere.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/default_project.json b/default_project.json
index 3add471..223e8c1 100644
--- a/default_project.json
+++ b/default_project.json
@@ -87,7 +87,7 @@
"name": "Code",
"label": "",
"type": "code",
- "default": "__kernel void process(__global const float* in_pos, __global const float* in_col, int in_count, __global float* out_pos, __global float* out_col, __global int* out_count, int max_vertices) {\n int id = get_global_id(0);\n if (id == 0) {\n float radius = chf(\"Radius\", 0.5f);\n float center_x = 0.0f;\n float center_y = 0.55f;\n float center_z = 0.0f;\n int lat_steps = 16;\n int lon_steps = 24;\n int count = 0;\n for (int lat = 0; lat < lat_steps; lat++) {\n float theta0 = 3.14159265f * (float)lat / (float)lat_steps;\n float theta1 = 3.14159265f * (float)(lat + 1) / (float)lat_steps;\n for (int lon = 0; lon < lon_steps; lon++) {\n float phi0 = 6.2831853f * (float)lon / (float)lon_steps;\n float phi1 = 6.2831853f * (float)(lon + 1) / (float)lon_steps;\n float x00 = radius * sin(theta0) * cos(phi0);\n float y00 = radius * cos(theta0);\n float z00 = radius * sin(theta0) * sin(phi0);\n float x10 = radius * sin(theta1) * cos(phi0);\n float y10 = radius * cos(theta1);\n float z10 = radius * sin(theta1) * sin(phi0);\n float x11 = radius * sin(theta1) * cos(phi1);\n float y11 = radius * cos(theta1);\n float z11 = radius * sin(theta1) * sin(phi1);\n float x01 = radius * sin(theta0) * cos(phi1);\n float y01 = radius * cos(theta0);\n float z01 = radius * sin(theta0) * sin(phi1);\n float px[6] = {x00, x10, x11, x00, x11, x01};\n float py[6] = {y00, y10, y11, y00, y11, y01};\n float pz[6] = {z00, z10, z11, z00, z11, z01};\n for (int v = 0; v < 6; v++) {\n int idx = count++;\n if (idx < max_vertices) {\n out_pos[idx * 3 + 0] = center_x + px[v];\n out_pos[idx * 3 + 1] = center_y + py[v];\n out_pos[idx * 3 + 2] = center_z + pz[v];\n float nx = px[v];\n float ny = py[v];\n float nz = pz[v];\n float len = sqrt(nx*nx + ny*ny + nz*nz);\n if (len > 0.0f) {\n nx /= len;\n ny /= len;\n nz /= len;\n }\n out_col[idx * 3 + 0] = 0.35f + fabs(nx) * 0.35f;\n out_col[idx * 3 + 1] = 0.45f + fabs(ny) * 0.35f;\n out_col[idx * 3 + 2] = 0.85f;\n }\n }\n }\n }\n *out_count = count;\n }\n}",
+ "default": "__kernel void process(__global const float* in_pos, __global const float* in_col, int in_count, __global float* out_pos, __global float* out_col, __global int* out_count, int max_vertices) {\n int id = get_global_id(0);\n if (id == 0) {\n float radius = chf(\"Radius\", 0.5f);\n float center_x = 0.0f;\n float center_y = 0.55f;\n float center_z = 0.0f;\n int lat_steps = 16;\n int lon_steps = 24;\n int count = 0;\n for (int lat = 0; lat < lat_steps; lat++) {\n float theta0 = 3.14159265f * (float)lat / (float)lat_steps;\n float theta1 = 3.14159265f * (float)(lat + 1) / (float)lat_steps;\n for (int lon = 0; lon < lon_steps; lon++) {\n float phi0 = 6.2831853f * (float)lon / (float)lon_steps;\n float phi1 = 6.2831853f * (float)(lon + 1) / (float)lon_steps;\n float x00 = radius * sin(theta0) * cos(phi0);\n float y00 = radius * cos(theta0);\n float z00 = radius * sin(theta0) * sin(phi0);\n float x10 = radius * sin(theta1) * cos(phi0);\n float y10 = radius * cos(theta1);\n float z10 = radius * sin(theta1) * sin(phi0);\n float x11 = radius * sin(theta1) * cos(phi1);\n float y11 = radius * cos(theta1);\n float z11 = radius * sin(theta1) * sin(phi1);\n float x01 = radius * sin(theta0) * cos(phi1);\n float y01 = radius * cos(theta0);\n float z01 = radius * sin(theta0) * sin(phi1);\n float px[6] = {x00, x10, x11, x00, x11, x01};\n float py[6] = {y00, y10, y11, y00, y11, y01};\n float pz[6] = {z00, z10, z11, z00, z11, z01};\n for (int v = 0; v < 6; v++) {\n int idx = count++;\n if (idx < max_vertices) {\n out_pos[idx * 3 + 0] = center_x + px[v];\n out_pos[idx * 3 + 1] = center_y + py[v];\n out_pos[idx * 3 + 2] = center_z + pz[v];\n float nx = px[v];\n float ny = py[v];\n float nz = pz[v];\n float len = sqrt(nx*nx + ny*ny + nz*nz);\n if (len > 0.0f) {\n nx /= len;\n ny /= len;\n nz /= len;\n }\n out_col[idx * 3 + 0] = 0.5f + nx * 0.5f;\n out_col[idx * 3 + 1] = 0.5f + ny * 0.5f;\n out_col[idx * 3 + 2] = 0.5f + nz * 0.5f;\n }\n }\n }\n }\n *out_count = count;\n }\n}",
"options": [],
"min": null,
"max": null,
diff --git a/nodes/sphere.json b/nodes/sphere.json
index 0a5409a..e92aa72 100644
--- a/nodes/sphere.json
+++ b/nodes/sphere.json
@@ -13,7 +13,7 @@
"params": [
{
"name": "Code",
- "default": "__kernel void process(__global const float* in_pos, __global const float* in_col, int in_count, __global float* out_pos, __global float* out_col, __global int* out_count, int max_vertices) {\n int id = get_global_id(0);\n if (id == 0) {\n float radius = chf(\"Radius\", 0.5f);\n float center_x = 0.0f;\n float center_y = 0.55f;\n float center_z = 0.0f;\n int lat_steps = 16;\n int lon_steps = 24;\n int count = 0;\n for (int lat = 0; lat < lat_steps; lat++) {\n float theta0 = 3.14159265f * (float)lat / (float)lat_steps;\n float theta1 = 3.14159265f * (float)(lat + 1) / (float)lat_steps;\n for (int lon = 0; lon < lon_steps; lon++) {\n float phi0 = 6.2831853f * (float)lon / (float)lon_steps;\n float phi1 = 6.2831853f * (float)(lon + 1) / (float)lon_steps;\n float x00 = radius * sin(theta0) * cos(phi0);\n float y00 = radius * cos(theta0);\n float z00 = radius * sin(theta0) * sin(phi0);\n float x10 = radius * sin(theta1) * cos(phi0);\n float y10 = radius * cos(theta1);\n float z10 = radius * sin(theta1) * sin(phi0);\n float x11 = radius * sin(theta1) * cos(phi1);\n float y11 = radius * cos(theta1);\n float z11 = radius * sin(theta1) * sin(phi1);\n float x01 = radius * sin(theta0) * cos(phi1);\n float y01 = radius * cos(theta0);\n float z01 = radius * sin(theta0) * sin(phi1);\n float px[6] = {x00, x10, x11, x00, x11, x01};\n float py[6] = {y00, y10, y11, y00, y11, y01};\n float pz[6] = {z00, z10, z11, z00, z11, z01};\n for (int v = 0; v < 6; v++) {\n int idx = count++;\n if (idx < max_vertices) {\n out_pos[idx * 3 + 0] = center_x + px[v];\n out_pos[idx * 3 + 1] = center_y + py[v];\n out_pos[idx * 3 + 2] = center_z + pz[v];\n float nx = px[v];\n float ny = py[v];\n float nz = pz[v];\n float len = sqrt(nx*nx + ny*ny + nz*nz);\n if (len > 0.0f) {\n nx /= len;\n ny /= len;\n nz /= len;\n }\n out_col[idx * 3 + 0] = 0.35f + fabs(nx) * 0.35f;\n out_col[idx * 3 + 1] = 0.45f + fabs(ny) * 0.35f;\n out_col[idx * 3 + 2] = 0.85f;\n }\n }\n }\n }\n *out_count = count;\n }\n}"
+ "default": "__kernel void process(__global const float* in_pos, __global const float* in_col, int in_count, __global float* out_pos, __global float* out_col, __global int* out_count, int max_vertices) {\n int id = get_global_id(0);\n if (id == 0) {\n float radius = chf(\"Radius\", 0.5f);\n float center_x = 0.0f;\n float center_y = 0.55f;\n float center_z = 0.0f;\n int lat_steps = 16;\n int lon_steps = 24;\n int count = 0;\n for (int lat = 0; lat < lat_steps; lat++) {\n float theta0 = 3.14159265f * (float)lat / (float)lat_steps;\n float theta1 = 3.14159265f * (float)(lat + 1) / (float)lat_steps;\n for (int lon = 0; lon < lon_steps; lon++) {\n float phi0 = 6.2831853f * (float)lon / (float)lon_steps;\n float phi1 = 6.2831853f * (float)(lon + 1) / (float)lon_steps;\n float x00 = radius * sin(theta0) * cos(phi0);\n float y00 = radius * cos(theta0);\n float z00 = radius * sin(theta0) * sin(phi0);\n float x10 = radius * sin(theta1) * cos(phi0);\n float y10 = radius * cos(theta1);\n float z10 = radius * sin(theta1) * sin(phi0);\n float x11 = radius * sin(theta1) * cos(phi1);\n float y11 = radius * cos(theta1);\n float z11 = radius * sin(theta1) * sin(phi1);\n float x01 = radius * sin(theta0) * cos(phi1);\n float y01 = radius * cos(theta0);\n float z01 = radius * sin(theta0) * sin(phi1);\n float px[6] = {x00, x10, x11, x00, x11, x01};\n float py[6] = {y00, y10, y11, y00, y11, y01};\n float pz[6] = {z00, z10, z11, z00, z11, z01};\n for (int v = 0; v < 6; v++) {\n int idx = count++;\n if (idx < max_vertices) {\n out_pos[idx * 3 + 0] = center_x + px[v];\n out_pos[idx * 3 + 1] = center_y + py[v];\n out_pos[idx * 3 + 2] = center_z + pz[v];\n float nx = px[v];\n float ny = py[v];\n float nz = pz[v];\n float len = sqrt(nx*nx + ny*ny + nz*nz);\n if (len > 0.0f) {\n nx /= len;\n ny /= len;\n nz /= len;\n }\n out_col[idx * 3 + 0] = 0.5f + nx * 0.5f;\n out_col[idx * 3 + 1] = 0.5f + ny * 0.5f;\n out_col[idx * 3 + 2] = 0.5f + nz * 0.5f;\n }\n }\n }\n }\n *out_count = count;\n }\n}"
}
],
"position": [4.0, 2.0]