天天看點

圖形API學習工程(15):重構頂點資料相關代碼,實作渲染多個mesh目标明确重構方向實作效果後續的發展與問題

工程GIT位址:https://gitee.com/yaksue/yaksue-graphics

目标

“頂點緩沖”最初是在《圖形API學習工程(5):圖形管線&頂點緩沖》進行了引入,不過當時沒有好的封裝,這讓後續新内容的添加會導緻較多的代碼的調整。例如:

  • 當着色器所需的頂點資料的布局變化時:我需要改動現有的頂點資料與之比對;還需要改動各個圖形API版本中關于頂點資料布局的代碼。
  • 如果未來一個mesh将送往多個管線中,而他們的頂點資料布局不一樣,則一個mesh應該對應多個頂點緩沖。

本篇的目标是重構代碼來解決這些問題。另外為了能确定代碼結構沒問題,我将實驗是否能設定多份頂點緩沖并調用多個DrawCall來實作渲染多個mesh。

明确重構方向

1. 頂點資料布局

首先要明确的是 “頂點資料布局” 的概念,我這裡指的是着色器中“每個頂點所攜帶的屬性”:

圖形API學習工程(15):重構頂點資料相關代碼,實作渲染多個mesh目标明确重構方向實作效果後續的發展與問題

可以明白:

  • 當管線中的shader确定下來之後,頂點資料布局也随之确定下來。也就是說,管線隻能有一個頂點資料布局。

是以接下來的重構方向之一是,将頂點資料布局放到“管線”對象中。同時以一個統一的方式指定它們。

2. 模型資料

如果一個mesh将被送到多個管線渲染且它們的頂點資料布局不一樣,則實際上需要多個頂點緩沖。

可以明白:

  • “模型”和頂點緩沖應該是一對多的關系。每個布局都有其比對的 頂點緩沖 。

是以,我決定将模型資料抽象出來,并提供接口,讓其為每一個管線都生成其比對的頂點緩沖(精确上講,不需要為每個管線都設定,因為管線之間的頂點資料布局有可能重複,此處待後續更複雜的重構)

實作

詳見代碼改動:

圖形API學習工程(15):重構頂點資料相關代碼,實作渲染多個mesh目标明确重構方向實作效果後續的發展與問題
  • 藍色部分是對頂點資料布局相關代碼進行重構。
  • 紅色部分是抽象出“模型資料”的概念,作為測試讓其實作渲染多個mesh。

其中需要注意的是,我将頂點的屬性種類以以enum來指定:

enum VertexInputAttributeType
{
	VIA_POSITION,	//頂點位置
	VIA_NORMAL,		//頂點法線
	VIA_COLOR,		//頂點顔色
	VIA_TEXCOORD,	//貼圖UV坐标
};
           

而關于每一種屬性的占位是多少,目前是寫死的:

//描述一個頂點屬性
struct VertexInputAttributeDescription
{
	VertexInputAttributeType Type;	//種類
	unsigned int Float32Cout;		//這個屬性有多少個Float
	VertexInputAttributeDescription(VertexInputAttributeType InType)
	{
		Type = InType;

		//在此依照種類對Float32Cout做自動的設定:
		switch (Type)
		{
		case VIA_POSITION:
			Float32Cout = 3;	//XYZ三個方向
			break;
		case VIA_NORMAL:
			Float32Cout = 3;	//XYZ三個方向
			break;
		case VIA_COLOR:
			Float32Cout = 4;	//RGBA四個通道
			break;
		case VIA_TEXCOORD:
			Float32Cout = 2;	//UV兩個方向
			break;
		default:
			break;
		}
	}
};
           

這樣,我便可以用它來指定頂點屬性的布局了:

//作為測試的圖形管線資料:
GraphicsPipelineInfo Info;
//shader檔案:
Info.VertexShaderFile = "TestShader_vs";
Info.PixelShaderFile = "TestShader_ps";
//頂點屬性:
Info.VertexInputAttributeTypes.push_back(VIA_POSITION);	//位置
Info.VertexInputAttributeTypes.push_back(VIA_NORMAL);	//法線
Info.VertexInputAttributeTypes.push_back(VIA_TEXCOORD);	//貼圖UV
           

随後各個圖形API将根據這一資訊來“布置”自己的管線(詳見代碼)。而模型也知道了該如何提供自己的頂點資料來比對這個布局。

其實理論上,頂點屬性應該是“沒有具體含義”的,其含義應該被展現在shader算法中。我這裡顯式的賦予其“含義”僅僅是為了使用上更容易并讓代碼可讀性更高。不過,這也和HLSL語義對應了起來。(關于HLSL語義的意義詳細見官方文檔,目前我還沒有較深的了解)

效果

圖形API學習工程(15):重構頂點資料相關代碼,實作渲染多個mesh目标明确重構方向實作效果後續的發展與問題
圖形API學習工程(15):重構頂點資料相關代碼,實作渲染多個mesh目标明确重構方向實作效果後續的發展與問題
圖形API學習工程(15):重構頂點資料相關代碼,實作渲染多個mesh目标明确重構方向實作效果後續的發展與問題
圖形API學習工程(15):重構頂點資料相關代碼,實作渲染多個mesh目标明确重構方向實作效果後續的發展與問題

後續的發展與問題

  • 模型應該根據頂點布局來生成對應的頂點緩沖,而不是管線,因為管線可能存在相同頂點布局的情況,此時則會造成頂點緩沖資料的重複
  • Vulkan畫面颠倒問題待修正
  • 随後需要對管線相關代碼進行重構,支援多個UniformBuffer/貼圖,支援多個管線。

繼續閱讀