I think I have a case of the stupid, I'm planing on implementing some conservative depth rendering (conservative rendering in CPU gems) but I'm stuck at the most basic level: enlarging the triangle.

here is the state of affairs: http://nraynaud.github.io/webgcode/test_3D_conservative_rendering.html (the black triangle is the input, the red dots are the enlarged vertices, and the squares represent the sampling grid)

I'm using webgl with thee.js, I sent as attributes the 2 companion vertices of each vertex, and I'm trying to enlarge the triangles in the vertex shader. I am in the most stupid situation possible: I have an orthographic camera whose 'up' is the +Y axis, and the view extends towards -Z (basically I'm filming my feet and the top of the screen is +Y). I can't (I think, projective geometry is a bit mysterious) directly use the code from CPU gems, because it supposes a perspective camera (it computes the planes passing through the edges of the triangle and the eye point of the viewer, while there is no eye point in ortho).

here is what I tried:

' vec3 p1 = prevPoint, p2 = position, p3 = nextPoint;', ' if (!isFrontFacing(p1.xy, p2.xy, p3.xy)) {vec3 temp = p1;p1 = p3; p3 = temp;}', //move the vertex in 2D ' vec2 e1 = p2.xy - p1.xy;', ' vec2 e1Normal = normalize(vec2(e1.y, -e1.x));', ' vec2 e1Translate = e1Normal * length(hPixelWorld);', ' vec2 e2 = p3.xy - p2.xy;', ' vec2 e2Normal = normalize(vec2(e2.y, -e2.x));', ' vec2 e2Translate = e2Normal * length(hPixelWorld);',

I think this should give me 2 normals to the 2 edges adjacent to p2 (the considered vertex), both pointing inwards or outwards of the triangle, depending on my luck. Well, actually, depending on the considered vertex, I don't always get the normals pointing in the same direction (and not with a cons), and I have no explanation (I even tried to armor my code against vertex order with the isFrontFacing() at the top).

I tried some silly stuff, like computing all the 4 possibilities of normal directions and choosing the one that get me the furthest point from the centroid of the triangle, but I think I even botched the implementation of that, because some points are clearly not the furthest away from the center:

' vec3 possibilities[4];', ' vec2 centroid = ((p1+p2+p3)/3.0).xy;', ' possibilities[0] = translatePoint(p2.xy, +e1Translate, +e2Translate, e1, e2, centroid);', ' possibilities[1] = translatePoint(p2.xy, -e1Translate, +e2Translate, e1, e2, centroid);', ' possibilities[2] = translatePoint(p2.xy, -e1Translate, -e2Translate, e1, e2, centroid);', ' possibilities[3] = translatePoint(p2.xy, +e1Translate, -e2Translate, e1, e2, centroid);', ' vec3 currentBest = possibilities[0];', ' if (possibilities[1].z >= currentBest.z)', ' currentBest = possibilities[1];', ' if (possibilities[2].z >= currentBest.z)', ' currentBest = possibilities[2];', ' if (possibilities[3].z >= currentBest.z)', ' currentBest = possibilities[3];', ' vec2 resultPoint2D = currentBest.xy;',

here is isFrontFacing:

'bool isFrontFacing(vec2 p1, vec2 p2, vec2 p3) {', ' float a = cross2d(p2-p1, p2-p3);', ' return a > 0.0;', '}',

here is translatePoint:

// we are encoding the distance to centroid in z 'vec3 translatePoint(vec2 point, vec2 dir1, vec2 dir2, vec2 e1, vec2 e2, vec2 centroid) {', ' vec2 e1TranslatedPoint = point + dir1;', ' vec2 e2TranslatedPoint = point + dir2;', //http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect ' float u = cross2d(e2TranslatedPoint - e1TranslatedPoint, e2) / cross2d(e2, e1);', ' vec2 result = e1TranslatedPoint + u * e1;', ' float dist = length(result - centroid);', ' return vec3(result, dist);', '}',

and cross2D:

'float cross2d(vec2 v1, vec2 v2) {', ' return v1.x * v2.y - v1.y * v2.x; ', '}',

here is the complete code: https://github.com/nraynaud/webgcode/blob/01550668fdedba5ab61e2fbf5ed9917ca06b5e75/test_3D_conservative_rendering.html

We see that only one vertex is moved in the correct direction, for the 2 others, one of the edges normals was wrong.

Ok, so how do we offset a triangle when we are not a geometric moron?