我想我有一个愚蠢的案例,我正在实施一些保守的深度渲染(conservative rendering in CPU gems),但我仍然坚持最基本的水平:扩大三角形。
这是事态: http://nraynaud.github.io/webgcode/test_3D_conservative_rendering.html (黑色三角形是输入,红色圆点是放大的顶点,方块代表采样网格)
我正在使用带有the.js的webgl,我将每个顶点的2个伴随顶点作为属性发送,并且我试图放大顶点着色器中的三角形。我处于最愚蠢的境地:我有一台正相机,其中有一个' up'是+ Y轴,视图向-Z延伸(基本上我拍摄我的脚,屏幕顶部是+ Y)。我不能(我认为,投影几何有点神秘)直接使用来自CPU宝石的代码,因为它假设一个透视相机(它计算穿过三角形边缘和观察者眼点的平面) ,虽然在正交中没有观点。
这是我试过的:
' 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);',
我认为这应该给我2个法线到p2(被考虑的顶点)附近的2个边缘,两个都指向三角形的内部或外部,这取决于我的运气。好吧,实际上,根据所考虑的顶点,我不总是让法线指向相同的方向(而不是缺点),我没有解释(我甚至尝试用顶点顺序装备我的代码顶部的isFrontFacing()。
我尝试了一些愚蠢的东西,比如计算法线方向的所有4种可能性,并选择让我从三角形的质心中获得最远点的那种,但我认为我甚至拙劣地执行了这个,因为有些点是显然不是距离中心最远的地方:
' 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;',
这里是isFrontFacing:
'bool isFrontFacing(vec2 p1, vec2 p2, vec2 p3) {',
' float a = cross2d(p2-p1, p2-p3);',
' return a > 0.0;',
'}',
这里是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);',
'}',
和cross2D:
'float cross2d(vec2 v1, vec2 v2) {',
' return v1.x * v2.y - v1.y * v2.x; ',
'}',
我们看到只有一个顶点在正确的方向上移动,对于另外两个顶点,其中一个边缘法线错误。
好的,那么当我们不是几何白痴时,我们如何抵消三角形呢?