我想"绕过"延迟照明的经典光量方法。
通常,当您想要影响点光源体积内的像素时,您可以简单地渲染球体网格。
我想尝试另一种方法来做到这一点,我的想法是渲染一个包含球体的立方体,立方体是"限制"因此,每个面部的中心都是球体的一个点。那么你只需要从你的角度知道哪个片段将成为圆圈的一部分(屏幕上的球体),如果你已经渲染了球体。
因此,主要问题是要知道哪些片段必须被丢弃。 我怎么能这样做: 进入片段着色器,我有我的"相机"世界坐标,我的碎片世界坐标,我的球体世界中心和我的球体半径。 因此,我有直线,其方向矢量由相机片段世界点建模。 我可以建立我的球体方程式。 最后我可以知道线是否与球体相交。
从我的观点来看是正确的,如果该线与球体相交,那么这个片段必须被视为一个突出显示的片段(如果我已经呈现的片段)换了一个球体?)
答案 0 :(得分:2)
因此检查“lenght(fragment-sphereCenter)< = sphereRadius”在这里并不意味着什么,因为片段不在球体上。
那又怎样?
灯光的标准延迟着色解决方案是渲染全屏四边形。渲染球体的目的是避免对光源效果之外的碎片进行一堆每片段计算。这意味着该球体的中心是光源,其半径表示源具有效果的最大距离。
因此片段的长度(即,从g-buffer数据重建,而不是由立方体产生的片段)到球体中心的长度非常相关。这是片段和光源之间的长度。如果它大于球体半径(AKA:光线的最大范围),那么你可以剔除片段。
或者你可以让你的光衰减计算做同样的工作。毕竟,为了使灯光看起来不像它们被裁剪,那个球体半径必须也与某种形式的光衰减一起使用。也就是说,当片段处于该距离时,光的衰减必须为0或者可忽略不计。
因此......如果您渲染球体,立方体或全屏四边形并不重要。您可以剔除碎片或让光衰减发挥作用。
但是,如果您希望通过在读取任何g-buffers之前丢弃片段来保存性能,则可以执行此操作。假设您可以访问FS中球体/立方体中心的相机空间位置:
将立方体片段的位置转换为相机空间。你可以通过反向转换gl_FragCoord
来做到这一点,但是将相机空间位置传递给片段着色器可能会更快。这不像你的VS正在做很多工作或任何事情。
由于相机空间位置在相机空间中,因此它已经表示从相机到场景的方向。所以现在,使用此方向执行光线/球体交叉的部分。也就是说,一旦计算出判别式就停止(避免使用昂贵的平方根)。判别式是:
float A = dot(cam_position, cam_position);
float B = -2 * (dot(cam_position, cam_sphere_center);
float C = (dot(cam_sphere_center, cam_sphere_center)) - (radius * radius)
float Discriminant = (B * B) - 4 * A * C;
如果判别式为负,则丢弃该片段。否则,做你平常的事情。