其他分享
首页 > 其他分享> > 光线追踪学习:蒙特卡洛路径追踪的学习

光线追踪学习:蒙特卡洛路径追踪的学习

作者:互联网

光栅化与光线追踪

蒙特卡洛方法

伪代码

// 追踪一条光线
pathTracing(p)
{
	L = 0.0
	wi = random()	// 随机选择一个方向
	if(wi hit q)	// 射线 wi 击中 q 点
	{
		cosine = dot(nq, wi)	// q 点法向量 nq 和 wi 的夹角余弦值
		L += cosine * pathTracing(q) / PDF(wi)
	}

	return L
}

// 对一个像素投射 SPP 条光线
L = 0.0
for(i in SPP)
{
	wi = random()	// 随机选择一个方向
	if(wi hit q)	// 射线 wi 击中 q 点
	{
		L += pathTracing(q) / PDF(wi)
	}
}
L /= SPP
————————————————
版权声明:本文为CSDN博主「AkagiSenpai」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44176696/article/details/113418991

图像结果输出

void svpng(FILE* fp, unsigned w, unsigned h, const unsigned char* img, int alpha)

// 输出 SRC 数组中的数据到图像
void imshow(double* SRC)
{
    
    unsigned char* image = new unsigned char[WIDTH * HEIGHT * 3];// 图像buffer
    unsigned char* p = image;
    double* S = SRC;    // 源数据

    FILE* fp;
    fopen_s(&fp, "image.png", "wb");

    for (int i = 0; i < HEIGHT; i++)
    {
        for (int j = 0; j < WIDTH; j++)
        {
            *p++ = (unsigned char)clamp((*S++) * 255, 0.0, 255.0);  // R 通道
            *p++ = (unsigned char)clamp((*S++) * 255, 0.0, 255.0);  // G 通道
            *p++ = (unsigned char)clamp((*S++) * 255, 0.0, 255.0);  // B 通道
        }
    }

    svpng(fp, WIDTH, HEIGHT, image, 0);
}

投射光线

double* image = new double[WIDTH * HEIGHT * 3];
memset(image, 0.0, sizeof(double) * WIDTH * HEIGHT * 3);
double* p = image;//p作为图像指针
for (int i = 0; i < HEIGHT; i++)
{
    for (int j = 0; j < WIDTH; j++)
    {
        // 像素坐标转投影平面坐标
        double x = 2.0 * double(j) / double(WIDTH) - 1.0;
        double y = 2.0 * double(HEIGHT - i) / double(HEIGHT) - 1.0;

        vec3 coord = vec3(x, y, SCREEN_Z);          // 计算投影平面坐标
        vec3 direction = normalize(coord - EYE);    // 计算光线投射方向
        
        vec3 color = direction;

        *p = color.x; p++;  // R 通道
        *p = color.y; p++;  // G 通道
        *p = color.z; p++;  // B 通道
    }
}

imshow(image);

三角形与光线求交方式

求交计算

光线追踪程序:

球面随机向量

// 单位球内的随机向量
vec3 randomVec3()
{
    vec3 d;
    do
    {
        d = 2.0f * vec3(randf(), randf(), randf()) - vec3(1, 1, 1);
    } while (dot(d, d) > 1.0);
    return normalize(d);
}

// 法向半球随机向量
vec3 randomDirection(vec3 n)
{
    // 法向半球
    vec3 d;
    do
    {
        d = randomVec3();
    } while (dot(d, n) < 0.0f);
    return d;
}

// 法向半球随机向量
vec3 randomDirection(vec3 n)
{
    return normalize(randomVec3() + n);
}

开始路径追踪

绘制球体

在这里插入图片描述

镜面反射

折射

抗锯齿

标签:color,res,material,学习,vec3,double,蒙特卡洛,ray,追踪
来源: https://blog.csdn.net/wqdqwass/article/details/122503982