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

密集球光照贴图生成

现在来生成球光照贴图。

上一文的方法对于粗糙的物体是合适的,这个球上有镜面反射产生亮斑。
所以、这里准备以贴图坐标所对应球上点和视点连线为入射光,生成密集的球光照贴图。

双向生成密集球光照图

//以球上的点和视点为入射光,反面使用对称视点(双向)
void 球纹理生成球上点和视点为入射光(vector<Sphere_GLSL> &spheres, std::vector<Triangle_GLSL> &triangles, int Sphere_n) {
	double* image = new double[WIDTH * HEIGHT * 4];
	memset(image, 0.0, sizeof(double) * WIDTH * HEIGHT * 4);

	Sphere_GLSL *s1 = NULL;
	for (int i = 0; i < spheres.size(); i++)
	{
		if (spheres[i].Sphere_n == Sphere_n) {
			s1 = &spheres[i];
			break;
		}
	}
	MaxMin t0 = 计算MaxMin(spheres, Sphere_n);
	
	float zmax, zmin;
	zmin = t0.zmin;
	zmax = t0.zmax;		
	printf("zmin:%.2f\n", zmin);
	printf("zmax:%.2f\n", zmax);
	//反面视点
	vec3 eye = EYE; eye.z = -.9;// zmin - .2f;
	printf("eye.z:%.2f\n", eye.z);

	// 球体的基本参数
	float x0 = s1->O.x, y0 = s1->O.y, z0 = s1->O.z; // 球心坐标
	float r = s1->R; // 球的半径

	std::vector<Ray> Raywh;
	for (int k = 0; k < SAMPLE; k++)
	{
		if (k % 10 == 0)
			printf("\r%d", k);
		double* p = image;


		Raywh.clear();
		//生成入射光组-------------------------------------开始结束
		for (float u = 0; u < WIDTH; u++)
		{
			for (float w = 0; w < HEIGHT; w++)
			{

				float x, y, z;											  

				// 计算球体表面上的点坐标
				求xyz(x0, y0, z0, r, u, w, x, y, z);

				// MSAA
				if (k != SAMPLE - 1) {
					x += (randf() - 0.5f) / float(WIDTH);
					y += (randf() - 0.5f) / float(HEIGHT);
				}

				//以球上的点和视点为入射光
				vec3 direction;

				Ray ray;
				// 计算光线投射方向
				if (z>=s1->O.z)
				{//正面
					direction = normalize(vec3(x, y, z) - EYE);
					ray.startPoint = EYE;
					ray.direction = direction;

					Raywh.push_back(ray);
				}
				else {
					//反面
					direction = normalize(vec3(x, y, z) - eye);
					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 通道
			}
		}

	}printf("\n");
	//像素剪裁0-255
	powClamp0255(image, WIDTH*HEIGHT * 4);

	//保存图像
	char filename[256];
	sprintf_s(filename, "Sphere%d.png", Sphere_n);
	imSave(image, WIDTH, HEIGHT, filename);


}

 球1、2、3图:

然后运行opengl程序:

已经完成,后续应该把它制成OBJ,PLY文件,方便交流。

感谢观看!


http://www.kler.cn/a/598348.html

相关文章:

  • 什么情况下spring的事务会失效
  • 【WAF 安全实践】
  • 基于TCP/QT/C++的网络调试助手测试报告
  • 手机扫描仪 含PDF转word功能+OCR识别110种语言
  • 01_JavaScript
  • 深度学习之防止过拟合
  • 307 Temporary Redirect 解决办法 httpx
  • nebula graph传统使用Docker进行项目发版
  • 【笔记分享】NCS/Zephyr USB MSC实现方法介绍
  • 使用 Python 和 python-pptx 构建 Markdown 到 PowerPoint 转换器
  • 153页PPT华为市场管理全景:战略、逻辑、阶段与工具深度解析
  • 从扩展黎曼泽塔函数构造物质和时空的结构-3
  • 高性能缓存:使用 Redis 和本地内存缓存实战示例
  • Altium Designer数模电学习笔记
  • 常用数据库远程连接工具全解析:从入门到高效管理
  • 基于springboot的校园资料分享平台(048)
  • 设计模式之工厂模式的优缺点
  • Qt中通过QLabel实时显示图像
  • 【AI大模型】搭建本地大模型GPT-NeoX:详细步骤及常见问题处理
  • AI与自媒体的深度融合路径、场景与挑战