Forum Replies Created
-
AuthorPosts
-
其实我觉得还有一个地方不对,就是光源经过镜子反射打到墙上的高光没有显示出来,这是因为光追的时候是从墙上发出随机采样光线打到镜子,然后反射出来的时候很小概率能够打到光源,因此就没有这个效果
tall box的左侧面比较暗,可能是你的eval函数没有判断dotProduct(wo,N)?这样在这个面采样光源直接光照的时候,会返回错误的值
最近我思考并实现了一下naive pure specular。
首先根据课件上Diffuse的fr的推导,把材质换成pure Specular,考虑最简单的只有一束Li入射的情况,那么渲染方程就变成Lo = fr * Li * costhetai, 如果wo是wi的反射方向,则根据能量守恒,fr = 1 / costhetai,如果wo是其他方向,根据pure Specular的性质,Li应该全部被反射到Lr(反射方向)去,因此理论上fr 应该 = 0。但由于实际工程实现的时候,对光源采样的wo很难是wr,因此考虑采用Blinn-Phong模型的NdotH去调节,NdotH = pow(N*H, n),最后fr = NdotH / costhetai。当然物理中并不会存在pure specular,所以fr最好再乘上ks,或者菲涅尔项。
然后对于pure specular的点的采样方向,我每次采样的都是反射方向,此时设置pdf = 1.0f,效果如附件,感觉tall box反射光源打到墙面的部分效果不是很好,欢迎大佬指正。当然我觉得pure specular最真实也最贴近物理实际的,应该是microfacet,粗糙度为0的时候,所以实现了microfacet,specular也就实现了
Attachments:
You must be logged in to view attached files.void rst::rasterizer::set_pixel(const Eigen::Vector3f& point, const Eigen::Vector3f& color)
{
//old index: auto ind = point.y() + point.x() * width;
if (point.x() < 0 || point.x() >= width ||
point.y() < 0 || point.y() >= height) return;
auto ind = (height-point.y())*width + point.x();
// if out of range, return
if (ind >= width * height) return;
frame_buf[ind] = color;
}
闪退是因为在set_pixel计算ind的时候,超出屏幕外的三角形边上的点对应的ind会大于或者等于width * weight,而frame_buf的大小为width * weight,所以会发生数组访问越界错误,加上这个判断即可This post has received 2 votes up. -
AuthorPosts