简体   繁体   English

使用3个位置和法线进行光线追踪来插值三角形曲面的最佳方法

[英]Best way to interpolate triangle surface using 3 positions and normals for ray tracing

I am working on conventional Whitted ray tracing, and trying to interpolate surface of hitted triangle as if it was convex instead of flat. 我正在研究传统的Whitted光线追踪,并尝试插入击中三角形的表面,好像它是凸面而不是平面。 The idea is to treat triangle as a parametric surface s(u,v) once the barycentric coordinates (u,v) of hit point p are known. 一旦撞击点p的重心坐标(u,v)已知,则想法是将三角形视为参数曲面s(u,v) This surface equation should be calculated using triangle's positions p0, p1, p2 and normals n0, n1, n2 . 应使用三角形的位置p0, p1, p2和法线n0, n1, n2计算该表面方程。 The hit point itself is calculated as 命中点本身计算为

p = (1-u-v)*p0 + u*p1 + v*p2;

I have found three different solutions till now. 到目前为止我找到了三种不同的解决方案

Solution 1. Projection 解决方案1.投影

The first solution I came to. 我来的第一个解决方案。 It is to project hit point on planes that come through each of vertexes p0, p1, p2 perpendicular to corresponding normals, and then interpolate the result. 它是在垂直于相应法线的每个顶点p0, p1, p2平面上投射命中点,然后插入结果。

vec3 r0 = p0 + dot( p0 - p, n0 ) * n0;
vec3 r1 = p1 + dot( p1 - p, n1 ) * n1;
vec3 r2 = p2 + dot( p2 - p, n2 ) * n2;
p = (1-u-v)*r0 + u*r1 + v*r2;

Solution 2. Curvature 解决方案2.曲率

Suggested in a paper of Takashi Nagata "Simple local interpolation of surfaces using normal vectors" and discussed in question "Local interpolation of surfaces using normal vectors", but it seems to be overcomplicated and not very fast for real-time ray tracing (unless you precompute all necessary coefficients). 建议在Takashi Nagata的文章“使用法向矢量对表面进行简单局部插值”并在问题“使用法向量的局部插值表面”中进行了讨论,但它似乎过于复杂并且对于实时光线追踪而言并不是非常快(除非你预先计算所有必要的系数)。 Triangle here is treated as a surface of the second order. 这里的三角形被视为二阶曲面。

Solution 3. Bezier curves 解决方案3.贝塞尔曲线

This solution is inspired by Brett Hale's answer. 这个解决方案的灵感来自Brett Hale的回答。 It is about using some interpolation of the higher order, cubic Bezier curves in my case. 它是关于在我的情况下使用高阶,三次贝塞尔曲线的一些插值。 Eg, for an edge p0p1 Bezier curve should look like 例如,对于边缘p0p1贝塞尔曲线应该看起来像

B(t) = (1-t)^3*p0 + 3(1-t)^2*t*(p0+n0*adj) + 3*(1-t)*t^2*(p1+n1*adj) + t^3*p1,

where adj is some adjustment parameter. 其中adj是一些调整参数。

Computing Bezier curves for edges p0p1 and p0p2 and interpolating them gives the final code: 计算边缘p0p1p0p2贝塞尔曲线并对它们进行插值给出最终代码:

float u1 = 1 - u;
float v1 = 1 - v;
vec3 b1 = u1*u1*(3-2*u1)*p0 + u*u*(3-2*u)*p1 + 3*u*u1*(u1*n0 + u*n1)*adj;
vec3 b2 = v1*v1*(3-2*v1)*p0 + v*v*(3-2*v)*p2 + 3*v*v1*(v1*n0 + v*n2)*adj;
float w = abs(u-v) < 0.0001 ? 0.5 : ( 1 + (u-v)/(u+v) ) * 0.5;
p = (1-w)*b1 + w*b2;

Alternatively, one can interpolate between three edges: 或者,可以在三条边之间进行插值:

float u1 = 1.0 - u;
float v1 = 1.0 - v;
float w = abs(u-v) < 0.0001 ? 0.5 : ( 1 + (u-v)/(u+v) ) * 0.5;
float w1 = 1.0 - w;
vec3 b1 = u1*u1*(3-2*u1)*p0 + u*u*(3-2*u)*p1 + 3*u*u1*( u1*n0 + u*n1 )*adj;
vec3 b2 = v1*v1*(3-2*v1)*p0 + v*v*(3-2*v)*p2 + 3*v*v1*( v1*n0 + v*n2 )*adj;
vec3 b0 = w1*w1*(3-2*w1)*p1 + w*w*(3-2*w)*p2 + 3*w*w1*( w1*n1 + w*n2 )*adj;
p = (1-u-v)*b0 + u*b1 + v*b2;

Maybe I messed something in code above, but this option does not seem to be very robust inside shader. 也许我在上面的代码中弄乱了一些东西,但是这个选项在着色器中看起来并不是很强大。

PS The intention is to get more correct origins for shadow rays when they are casted from low-poly models. PS目的是为阴影射线从低多边形模型铸造时获得更正确的起源。 Here you can find the resulted images from test scene. 在这里,您可以找到测试场景中的结果图像。 Big white numbers indicates number of solution (zero for original image). 大的白色数字表示解决方案的数量(原始图像为零)。

PPS I still wonder if there is another efficient solution which can give better result. PPS我仍然想知道是否有另一种有效的解决方案可以提供更好的结果。

Keeping triangles 'flat' has many benefits and simplifies several stages required during rendering. 保持三角形“平坦”具有许多优点,并简化了渲染过程中所需的几个阶段。 Approximating a higher order surface on the other hand introduces quite significant tracing overhead and requires adjustments to your BVH structure. 另一方面,近似高阶曲面会引入相当大的跟踪开销,需要调整BVH结构。

When the geometry is being treated as a collection of facets on the other hand, the shading information can still be interpolated to achieve smooth shading while still being very efficient to process. 另一方面,当几何体被视为一个面的集合时,仍然可以插入着色信息以实现平滑的着色,同时仍然非常有效地处理。

There are adaptive tessellation techniques which approximate the limit surface ( OpenSubdiv is a great example). 有自适应曲面细分技术接近极限曲面( OpenSubdiv是一个很好的例子)。 Pixar's Photorealistic RenderMan has a long history using subdivision surfaces. 皮克斯的真实感渲染人使用细分曲面有着悠久的历史。 When they switched their rendering algorithm to path tracing, they've also introduced a pretessellation step for their subdivision surfaces. 当他们将渲染算法切换到路径跟踪时,他们还为其细分曲面引入了预拼接步骤。 This stage is executed right before rendering begins and builds an adaptive triangulated approximation of the limit surface. 此阶段在渲染开始之前执行,并构建极限曲面的自适应三角近似。 This seems to be more efficient to trace and tends to use less resources, especially for the high-quality assets used in this industry. 这似乎更有效地跟踪并倾向于使用更少的资源,特别是对于该行业中使用的高质量资产。

So, to answer your question. 所以,回答你的问题。 I think the most efficient way to achieve what you're after is to use an adaptive subdivision scheme which spits out triangles instead of tracing against a higher order surface. 我认为实现你所追求的最有效的方法是使用自适应细分方案,该方案吐出三角形而不是追踪更高阶的表面。

Dan Sunday describes an algorithm that calculates the barycentric coordinates on the triangle once the ray-plane intersection has been calculated. Dan Sunday描述了一种算法 ,该算法在计算出光线平面交点后计算三角形上的重心坐标。 The point lies inside the triangle if: 如果出现以
(s >= 0) && (t >= 0) && (s + t <= 1)

You can then use, say, n(s, t) = nu * s + nv * t + nw * (1 - s - t) to interpolate a normal, as well as the point of intersection, though n(s, t) will not, in general, be normalized, even if (nu, nv, nw) are. 然后你可以使用n(s, t) = nu * s + nv * t + nw * (1 - s - t)来插值法线,以及交点,尽管n(s, t)不会,一般来说,进行标准化,即使(nu, nv, nw)是。 You might find higher order interpolation necessary. 您可能会发现需要更高阶的插值。 PN-triangles were a similar hack for visual appeal rather than mathematical precision. PN三角形是一种类似于视觉吸引力而非数学精确度的黑客。 For example, true rational quadratic Bezier triangles can describe conic sections. 例如,真正的有理二次Bezier三角形可以描述圆锥截面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM