首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >vsg-使用 Phong 光照渲染管线

vsg-使用 Phong 光照渲染管线

原创
作者头像
kdyonly
发布2025-12-09 22:24:16
发布2025-12-09 22:24:16
600
举报
文章被收录于专栏:个人编程笔记个人编程笔记

vsg 中已经内置了基于Phong光照模型构建渲染管线,无需自己写shader就可以实现对应的渲染效果。

这里通过从glb中获取对应的节点,节点中包含三维数据,顶点,法线,颜色等等,去构建vsg的渲染节点。

1.创建一个Phone模型的渲染管线;

2.填充默认材质;

3.填充顶点,法线,颜色等数据;

4.绘制命令;

5.最后将得到的vsg节点,添加到vsg的场景树中进行渲染。

参考代码:

代码语言:c
复制
/// <summary>
/// 从场景节点创建VSG节点,使用vsg phone着色器
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
vsg::ref_ptr<vsg::Group> BimMainWindow::CreateVsgNodeFromSceneNodeByPhong(const std::shared_ptr<Bim::Scene::Node>& node)
{
	auto scenegraph = vsg::Group::create();

	auto sharedObjects = vsg::SharedObjects::create();
    //1.创建一个Phone模型的渲染管线;
	auto shaderSet = vsg::createPhongShaderSet(m_vsgOptions);
	auto graphicsPipelineConfig = vsg::GraphicsPipelineConfigurator::create(shaderSet);
    //2.填充默认材质;
	auto mat = vsg::PhongMaterialValue::create();
	mat->value().diffuse.set(1.0f, 1.0f, 1.0f, 1.0f);
	mat->value().specular.set(1.0f, 1.0f, 1.0f, 1.0f); // red specular highlight
	graphicsPipelineConfig->assignDescriptor("material", mat);
	
	
	if (node->model)
	{
		for (auto& geometry : node->model->geometries)
		{
			if (geometry->mesh)
			{
				auto& mesh = geometry->mesh;
				//顶点
				static_assert(sizeof(vsg::vec3) == 3 * sizeof(float));
				size_t numVertices = mesh->vertices.size() / 3;
				auto vertices = vsg::vec3Array::create(numVertices);
				std::memcpy(vertices->data(), mesh->vertices.data(), mesh->vertices.size() * sizeof(float));
				//法向量
				vsg::ref_ptr<vsg::vec3Array> normals = nullptr;
				if (!mesh->normals.empty()) {
					size_t numNormals = mesh->normals.size() / 3;
					normals = vsg::vec3Array::create(numNormals);
					std::memcpy(normals->data(), mesh->normals.data(), mesh->normals.size() * sizeof(float));
				}
				//顶点颜色
				vsg::ref_ptr<vsg::vec4Array> colors = nullptr;
				if (!mesh->colors.empty()) {
					size_t numColors = mesh->colors.size() / 4;
					colors = vsg::vec4Array::create(numColors);
					std::memcpy(colors->data(), mesh->colors.data(), mesh->colors.size() * sizeof(float));
				}
                //3.填充顶点,法线,颜色等数据;
				vsg::DataList vertexArrays;
				graphicsPipelineConfig->assignArray(vertexArrays, "vsg_Vertex", VK_VERTEX_INPUT_RATE_VERTEX, vertices);
				if (normals) {
					graphicsPipelineConfig->assignArray(vertexArrays, "vsg_Normal", VK_VERTEX_INPUT_RATE_VERTEX, normals);
				}
				//graphicsPipelineConfig->assignArray(vertexArrays, "vsg_TexCoord0", VK_VERTEX_INPUT_RATE_VERTEX, texcoords);
				graphicsPipelineConfig->assignArray(vertexArrays, "vsg_Color", VK_VERTEX_INPUT_RATE_INSTANCE, colors);

				//索引
				auto indices = vsg::uintArray::create(mesh->indices.size());
				std::copy(mesh->indices.begin(), mesh->indices.end(), indices->begin());

				// 4.绘制命令
				auto drawCommands = vsg::Commands::create();
				drawCommands->addChild(vsg::BindVertexBuffers::create(graphicsPipelineConfig->baseAttributeBinding, vertexArrays));
				drawCommands->addChild(vsg::BindIndexBuffer::create(indices));
				drawCommands->addChild(vsg::DrawIndexed::create(indices->size(), 1, 0, 0, 0));

				if (sharedObjects) sharedObjects->share(vertexArrays);
				if (sharedObjects) sharedObjects->share(indices);

				if (sharedObjects)
				{
					sharedObjects->share(drawCommands->children);
					sharedObjects->share(drawCommands);
				}
				// share the pipeline config and initialize it if it's unique
				if (sharedObjects)
					sharedObjects->share(graphicsPipelineConfig, [](auto gpc) { gpc->init(); });
				else
					graphicsPipelineConfig->init();
				auto stateGroup = vsg::StateGroup::create();
				graphicsPipelineConfig->copyTo(stateGroup, sharedObjects);
				// set up model transformation node
				/*auto transform = vsg::MatrixTransform::create();
				transform->subgraphRequiresLocalFrustum = false;*/
				auto transform = vsg::MatrixTransform::create();
				transform->setValue("guid", "Transform_" + node->guid);
				if (node->localMatrix.isZero())
				{
					transform->matrix = vsg::dmat4(); // 单位阵
				}
				else
				{
					transform->matrix = vsg::dmat4(node->localMatrix.data());
				}
				stateGroup->addChild(drawCommands);
				if (sharedObjects)
				{
					sharedObjects->share(stateGroup);
				}
				transform->addChild(stateGroup);
				if (sharedObjects)
				{
					sharedObjects->share(transform);
				}
				scenegraph->addChild(transform);
			}
		}
	}
	return scenegraph;
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档