我正在尝试使用光线行进渲染球体网格。 SDF 函数如下所示:
float sq_layer(vec3 p, vec3 bounding_box_min, vec3 bounding_box_max)
{
float cell_size = 4.0 / 16.0;
vec3 p0 = clamp(p.xyz, bounding_box_min, bounding_box_max);
p0 = mod(p0, cell_size) - cell_size * 0.5f;
float d_pt = sphereSDF(vec3(p0.x, p0.y, p0.z), 0.05f)
return d_pt;
}
为了更相关,我尝试稍微更改代码:
float sq_layer(vec3 p, vec3 bounding_box_min, vec3 bounding_box_max)
{
vec3 cell_size = (bounding_box_max - bounding_box_min) / 4.0;
vec3 p0 = clamp(p.xyz, bounding_box_min, bounding_box_max);
p0 = mod(p0, cell_size) - cell_size * 0.5f;
float d_pt = boxSDF(p0, cell_size * 0.35);
return d_pt;
}
以您的方式夹紧坐标会导致您的 sdf 返回非常接近表面的恒定距离,因此您将用尽迭代,从而导致您看到的工件。
您想与边界框大小的框 sdf 相交,而不是夹紧:
float sq_layer(vec3 p, vec3 bounding_box_min, vec3 bounding_box_max)
{
float cell_size = 4.0 / 16.0;
vec3 p0 = mod(p, cell_size) - cell_size * 0.5f;
float d_pt = sphereSDF(p0, 0.05f);
// the following is just a simplified box sdf
vec3 bb_extents = (bounding_box_max - bounding_box_min) * .5;
vec3 bb_center = bounding_box_min + bb_extents;
vec3 bb_p = max(abs(p-bb_center)-bb_extents,0.);
float d_bb = max(max(bb_p.x,bb_p.y),bb_p.z);
// intersect "sphere-field" with bounding box
return max(d_pt,d_bb);
}