Cliff Biffle avatar Cliff Biffle committed c54dc0d

Moved linearization onto the GPU. Now the CPU exclusively deals with values in camera-space, including when it computes normals. This improves surface reconstruction (by making the maximum Z-jump scale with distance). Performance seems somewhat improved, particularly on the triangle renderer. I'm not convinced that my method for projecting the normals out of camera-space is correct.

Comments (0)

Files changed (2)

 
 static const char *vertex_shader_source[] = {
   "const float halfFov = (57.0 / 180.0 * 3.14159265358) / 2.0;",
+  "vec3 kinect_unproject(vec3 point) {",
+  "  float linearZ = -325.616 / (point.z + -1084.61);",
+  "  vec2 angles = point.xy * halfFov;",
+  "  vec2 xyPrime = linearZ * sin(angles);",
+  "  return vec3(xyPrime, linearZ);"
+  "}",
+  
   "void main() {",
   // Undo the Kinect's perspective projection
+  "  float linearZ = -325.616 / (gl_Vertex.z + -1084.61);",
   "  vec2 angles = gl_Vertex.xy * halfFov;",
-  "  vec2 xyPrime = gl_Vertex.z * sin(angles);",
-  "  vec4 vertex = vec4(xyPrime, gl_Vertex.zw);",
+  "  vec2 xyPrime = linearZ * sin(angles);",
+  "  vec4 vertex = vec4(kinect_unproject(gl_Vertex.xyz), gl_Vertex.w);",
   "  gl_Position = gl_ModelViewProjectionMatrix * vertex;",
 
+  // Unproject the normal too
+  "  vec3 normalEnd = normalize(gl_Normal) + gl_Vertex.xyz;",
+  "  vec3 unprojectedNormalEnd = kinect_unproject(normalEnd);",
+  "  vec3 correctedNormal = unprojectedNormalEnd - vertex.xyz;",
+  
   // Compute the angle between the normal and the light
-  "  vec2 xyRatio = xyPrime / gl_Vertex.xy;"
-  "  vec3 correctedNormal = vec3(gl_Normal.xy * xyRatio, gl_Normal.z);",
   "  vec3 normal = normalize(gl_NormalMatrix * correctedNormal);",
   "  vec3 lightDir = normalize(vec3(gl_LightSource[0].position));",
   "  float NdotL = max(dot(normal, lightDir), 0.0);",
   glFrontFace(GL_CCW);
   glShadeModel(GL_SMOOTH);
   
-  GLfloat diffuseColor[4] = { 0.8f, 0.8f, 0.8f, 1.0f };
+  GLfloat diffuseColor[4] = { 1.f, 1.f, 1.f, 1.0f };
   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseColor);
 
-  GLfloat ambientColor[4] = { 0, 0, 0, 1 };
+  GLfloat ambientColor[4] = { 0.2f, 0.2f, 0.2f, 1 };
   glLightfv(GL_LIGHT0, GL_AMBIENT, ambientColor);
   
   GLfloat specularColor[4] = { 1, 1, 1, 1 };
   glLightfv(GL_LIGHT0, GL_SPECULAR, specularColor);
   
-  GLfloat globalAmbient[4] = { 0.1f, 0.1f, 0.1f, 1.0f };
+  GLfloat globalAmbient[4] = { 0.2f, 0.2f, 0.2f, 1.0f };
   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, globalAmbient);
   
   glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

KVRayFieldSpaceModel.m

   int vidx = 0;
   
   // Cast them rays
-  for (int y = 0; y < 480; y++) {
-    for (int x = 0; x < 640; x++, vidx++) {
-      uint16_t s = sample[vidx];
-      float z;
-      if (s < 2048) {
-        z = linearizationTable[s];
-      } else {
-        z = 0;
-      }
-      
-      rays[vidx].z = z;
-    }
-  }
-  
-  // Orient them normals
   for (int y = 0; y < 480 - 1; y++) {
-    vidx = 640 * y;
     for (int x = 0; x < 640 - 1; x++, vidx++) {
-      normals[vidx] = compute_normal(rays[vidx], rays[vidx + 640], rays[vidx + 1]);
+      rays[vidx].z = sample[vidx];
+      vec3f_t right = {
+        rays[vidx + 1].x,
+        rays[vidx + 1].y,
+        sample[vidx + 1],
+      };
+      vec3f_t down = {
+        rays[vidx + 640].x,
+        rays[vidx + 640].y,
+        sample[vidx + 640],
+      };
+      normals[vidx] = compute_normal(rays[vidx], down, right);
     }
   }
   
 }
 
 - (void) renderAsSolidWithOptions: (NSDictionary *) options {
-  float jump = 0.05f;
+  int jump = 2;
   
   glColor3f(1, 1, 1);
   glNormal3f(0, 0, 1);
   
   for (int y = 0; y < 480 - 1; y++) {
     BOOL inStrip = NO;
-    float lastDepth = rays[vidx].z;
+    int lastDepth = (int) rays[vidx].z;
     for (int x = 0; x < 640; x++, vidx++) {
       for (int step = 0; step < 640 * 2; step += 640) {
-        float z = rays[vidx + step].z;
-        float delta = z - lastDepth;
+        int z = (int) rays[vidx + step].z;
+        int delta = z - lastDepth;
         lastDepth = z;
         
-        if (delta < -jump || delta > jump || z == 0.f) {
+        if (delta < -jump || delta > jump || z == 0 || z == 2047) {
           if (inStrip) {
             glEnd();
             inStrip = NO;
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.