当前位置: 首页 > news >正文

视点游动生成光照贴图

上一文生成的光照贴图有两个缺点。其一稀疏点需要插值,插值后彩色不均。
其二物体遮挡有黑洞。
如果把入射光起点(视点)放在目标物体附近,然后移动光线,估计会形成一个密集的无黑洞的图像。
在平面上视点游动生成光照贴图

void 平面纹理生成(vector<Sphere_GLSL> &spheres, std::vector<Triangle_GLSL> &triangles, int Triangle_n0, int Triangle_n1) {
	double* image = new double[WIDTH * HEIGHT * 4];
	memset(image, 0.0, sizeof(double) * WIDTH * HEIGHT * 4);

	MaxMin t0 = 计算MaxMin(triangles, Triangle_n0);
	MaxMin t1 = 计算MaxMin(triangles, Triangle_n1);
	float xmax, xmin;
	float ymax, ymin;
	float zmax, zmin;
	xmin = min(t0.xmin, t1.xmin);
	xmax = max(t0.xmax, t1.xmax);
	ymin = min(t0.ymin, t1.ymin);
	ymax = max(t0.ymax, t1.ymax);
	zmin = min(t0.zmin, t1.zmin);
	zmax = max(t0.zmax, t1.zmax);
	string xyz = "xy";
	if (xmax == xmin)xyz = "yz";
	else if (ymax == ymin)xyz = "xz";
	else if (zmax == zmin)xyz = "xy";
	else {
		printf("err\n");
		return;
	}
	// 平面的基本参数
	float w, h, r, imin, imax, jmin, jmax;
	if (xyz == "xy") {
		w = xmax - xmin, h = ymax - ymin;
		r = zmin;
		imin = ymin, imax = ymax, jmin = xmin, jmax = xmax;
	}
	else if (xyz == "yz") {
		w = ymax - ymin, h = zmax - zmin;
		r = xmax;
		imin = zmin, imax = zmax, jmin = ymin, jmax = ymax;
	}
	else if (xyz == "xz") {
		w = xmax - xmin, h = zmax - zmin;
		r = ymin;
			jmin = xmin, jmax = xmax;
			imin = zmin, imax = zmax;
	}
	else {
		printf("err !!!\n");
		return;
	}

	// 参数化的步长
	float xStep = w / WIDTH;
	float yStep = h / HEIGHT;

	std::vector<Ray> Raywh;
	for (int k = 0; k < SAMPLE; k++)
	{
		printf("\r%d", k);
		double* p = image;
		Raywh.clear();
		//平面纹理生成
		//以平面大一圈的位置为起点,向平面垂线的方向为射线
		//--------------------------------------------


		
		// 遍历表面
		for (float i = imin; i < imax; i += yStep) {
			for (float j = jmin; j < jmax; j += xStep) {
				//printf("%.1f\n", j);

				// 计算面外的点坐标
				double x = j;
				double y = i;
				double z = r + 0.01f;
				vec3 eye = vec3(x, y, z);
				vec3 coord = vec3(x, y, r);
				float 移动 = 0.01f;
				if (r > 0)移动 = -0.01f;
				if (xyz == "xy") {
					x = j, y = i, z = r + 移动;
					// MSAA
					x += (randf() - 0.5f) / double(WIDTH);
					y += (randf() - 0.5f) / double(HEIGHT);
					eye = vec3(x, y, z);
					coord = vec3(x, y, r);

				}
				else if (xyz == "yz") {
					x = r + 移动, y = j, z = i;
					y += (randf() - 0.5f) / double(WIDTH);
					z += (randf() - 0.5f) / double(HEIGHT);
					eye = vec3(x, y, z);
					coord = vec3(r, y, z);
				}
				else if (xyz == "xz") {
					x = j, y = r + 移动, z = i;

					x += (randf() - 0.5f) / double(WIDTH);
					z += (randf() - 0.5f) / double(HEIGHT);
					eye = vec3(x, y, z);
					coord = vec3(x, r, z);

				}

				

				// 计算光线投射方向
				vec3 direction = normalize(coord - eye);

				Ray ray;
				ray.startPoint = eye;
				ray.direction = direction;
				Raywh.push_back(ray);

			}
		}

		//--------------------------------------------
		std::vector<vec4> color;
		// 路径追踪
		pathTracing_GLSL_TSn(Raywh, color);
		int nc = 0;
		for (int i = 0; i < HEIGHT; i++)
		{
			for (int j = 0; j < WIDTH; j++)
			{
				// 生成光线
				vec4 color0 = color[nc++];

				color0 *= BRIGHTNESS;

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

	}
	
	//imshow(image);
	{
		double* p = image;

		for (int i = 0; i < HEIGHT; i++)
		{
			for (int j = 0; j < WIDTH; j++)
			{

				*p = clamp(pow(*p, 1.0f / 2.2f) * 255, 0.0, 255.0); p++; // R 通道
				*p = clamp(pow(*p, 1.0f / 2.2f) * 255, 0.0, 255.0); p++; // G 通道
				*p = clamp(pow(*p, 1.0f / 2.2f) * 255, 0.0, 255.0); p++; // B 通道
				*p = clamp(pow(*p, 1.0f / 2.2f) * 255, 0.0, 255.0); p++; // A 通道
			}
		}
	}
	char filename[256];
	sprintf_s(filename, "triangle0%d%d.png", Triangle_n0, Triangle_n1);
	imSave(image, WIDTH, HEIGHT, filename);


	delete image;
}

对比:左边是前面生成的,右边是这次生成的。
 

然后运行代码

球上要怎么处理,还没有想好,以后再写吧。

相关文章:

  • 3.21学习总结 Java字符串+Static关键字
  • AI Agent开发大全第一课-AI是什么以及如何使用AI
  • Unity代码中修改动画速度
  • Python 面向对象三大特性深度解析
  • C#与西门子PLC的六大通信库
  • VSCode中搜索插件显示“提取扩展时出错。Failed to fetch”问题解决!
  • java基础--序列化与反序列化的概念是什么?
  • 大数据学习(80)-数仓分层
  • Spring 三级缓存能不能解决循环依赖?
  • 概率预测之NGBoost(Natural Gradient Boosting)回归和分位数(Quantile Regression)回归
  • KNN算法
  • Spring Boot中接口数据字段为 Long 类型时,前端number精度丢失问题解决方案
  • Vue入门
  • 油候插件、idea、VsCode插件推荐(自用)
  • 申请使用受限权限
  • 深入解析:Nginx+Keepalived实现双机热备架构
  • 《汽车电器与电子技术》第四次作业
  • Prometheus Exporter系列-Postgres_Exporter一键部署
  • JavaScript基础-节点操作
  • StarRocks 升级注意事项
  • 昆明一学校门外小吃摊占满人行道,城管:会在重点时段加强巡查处置
  • 三星“七天机”质保期内屏幕漏液被要求自费维修,商家:系人为损坏
  • 2025中国品牌日上海践行活动启动,将建设品牌生态交互平台
  • 雇来的“妈妈”:为入狱雇主无偿带娃4年,没做好准备说再见
  • 洞天寻隐·学林纪丨玉洞桃源:仇英青绿山水画中的洞天与身体
  • 澎湃研究所“营商环境研究伙伴计划”启动