Vulkan Samples 阅读 -- Hardware Accelerated Ray Tracing(二)Reflections & Callable & Query

Ray Traced Reflections

prepare

  • createBottomLevelAccelerationStructure: 在本地创建模型底层加速结构信息
    • loadFromFile:加载模型
    • 创建两个VkDeviceOrHostAddressConstKHR,分别存放vbo和ibo的指针(deviceAddress)
      • vertexBufferDeviceAddress : getBufferDeviceAddress
      • indexBufferDeviceAddress: getBufferDeviceAddress
    • 创建加速结构
      • VkAccelerationStructureGeometryKHR
        • 参数数模型的一些基本属性
      • VkAccelerationStructureBuildGeometryInfoKHR: 几何信息
      • VkAccelerationStructureBuildSizesInfoKHR:Get size info
      • vkGetAccelerationStructureBuildSizesKHR
      • createAccelerationStructure: 创建加速结构buffer
        • VkBufferCreateInfo:特殊的参数
          • sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO
          • usage = VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR
        • vkCreateBuffer: 下面使用的参数结构体都使用加速结构相关参数
        • vkGetBufferMemoryRequirements
        • vkAllocateMemory
        • vkBindBufferMemory
        • VkAccelerationStructureCreateInfoKHR
        • vkCreateAccelerationStructureKHR: 创建加速结构
        • vkGetAccelerationStructureDeviceAddressKHR: AS device address
    • createScratchBuffer
      • 在构建底层加速结构的过程中创建一个小的scratch缓冲区
      • VkAccelerationStructureBuildGeometryInfoKHR:
      • VkAccelerationStructureBuildRangeInfoKHR
    • accelerationStructureFeatures.accelerationStructureHostCommands
        • vkBuildAccelerationStructuresKHR
        • createCommandBuffer
        • vkCmdBuildAccelerationStructuresKHR
        • flushCommandBuffer
    • deleteScratchBuffer
  • createTopLevelAccelerationStructure
    • 创建 top level 加速结构
    • VkAccelerationStructureInstanceKHR
    • createBuffer: for instance data
    • VkDeviceOrHostAddressConstKHR
    • getBufferDeviceAddress
    • VkAccelerationStructureGeometryKHR
    • VkAccelerationStructureBuildGeometryInfoKHR
    • VkAccelerationStructureBuildSizesInfoKHR
    • vkGetAccelerationStructureBuildSizesKHR
    • createAccelerationStructure()
    • createScratchBuffer ()
    • VkAccelerationStructureBuildGeometryInfoKHR
    • VkAccelerationStructureBuildGeometryInfoKHR
    • VkAccelerationStructureBuildRangeInfoKHR
    • accelerationStructureFeatures.accelerationStructureHostCommands
        • vkBuildAccelerationStructuresKHR
        • createCommandBuffer
        • vkCmdBuildAccelerationStructuresKHR
        • flushCommandBuffer
    • deleteScratchBuffer
    • instancesBuffer.destroy()
  • createStorageImage(): 存放光追渲染结果:
    - 释放image信息, 阴影教程里没有这部分
    - vkDestroyImageView
    - vkDestroyImage
    - vkFreeMemory
    - storageImage
    - VkImageCreateInfo image = vks::initializers::imageCreateInfo();
    - vkCreateImage
    - vkGetImageMemoryRequirements
    - vkAllocateMemory
    - vkBindImageMemory
    - VkImageViewCreateInfo
    - vkCreateImageView
    - createCommandBuffer
    - setImageLayout
    - flushCommandBuffer
  • createUniformBuffer
    • createBuffer
    • updateUniformBuffers
  • createRayTracingPipeline
    • VkDescriptorSetLayoutBinding:结构体
    • VkDescriptorSetLayoutCreateInfo:结构体
    • vkCreateDescriptorSetLayout
    • VkPipelineLayoutCreateInfo
    • vkCreatePipelineLayout
    • Setup ray tracing shader groups
      • VkPipelineShaderStageCreateInfo
      • Ray generation group
        • VkRayTracingShaderGroupCreateInfoKHR: 结构体,存放shader和其他配置信息
          • shader: raygen.rgen.spv
      • Miss group: 光追未命中
        • VkRayTracingShaderGroupCreateInfoKHR
        • shader: miss.rmiss.spv
      • Closest hit group: 光追命中
        • VkRayTracingShaderGroupCreateInfoKHR
        • shader: closesthit.rchit.spv
    • Create the ray tracing pipeline
      • VkRayTracingPipelineCreateInfoKHR:结构体
      • vkCreateRayTracingPipelinesKHR
  • createShaderBindingTable
    • 创建用于加速结构的 shader 绑定表(Shader Binding Tables)-(SBT)
    • vkGetRayTracingShaderGroupHandlesKHR
    • createShaderBindingTable:创建三个SBT
      • createBuffer: 创建SBT – raygen
        • 使用字段VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR
      • createBuffer: miss
      • createBuffer: hit
      • memcpy
      • memcpy
      • memcpy
  • createDescriptorSets
    • vkCreateDescriptorPool
    • vkAllocateDescriptorSets
    • writeDescriptorSet: Ray tracing result image
    • writeDescriptorSet: Uniform data
    • writeDescriptorSet: Scene vertex buffer
    • writeDescriptorSet: Scene index buffer
    • vkUpdateDescriptorSets
  • buildCommandBuffers
    • handleResize
      • createStorageImage
      • storageImageDescriptor
      • writeDescriptorSet
    • vkBeginCommandBuffer
    • 使用反射时,这里使用的pipe数增加,这里cmd的两次,应该是只反射一次,命令相同
      • vkCmdBindPipeline
      • vkCmdBindDescriptorSets
      • vkCmdBindPipeline
      • vkCmdBindDescriptorSets
    • vkCmdTraceRaysKHR
    • Copy ray tracing output to swap chain image
      • setImageLayout
      • setImageLayout
      • vkCmdCopyImage
      • setImageLayout
      • setImageLayout
    • vkEndCommandBuffer

render

  • draw
    • prepareFrame
    • vkQueueSubmit
    • submitFrame
  • updateUniformBuffers

shader

  • raygen.rgen:计算与顶层加速结构碰撞的点
	#version 460
	#extension GL_EXT_ray_tracing : require
	
	layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
	layout(binding = 1, set = 0, rgba8) uniform image2D image;
	layout(binding = 2, set = 0) uniform CameraProperties 
	{
		mat4 viewInverse;
		mat4 projInverse;
		vec4 lightPos;
	} cam;
	
	
	struct RayPayload {
		vec3 color;
		float distance;
		vec3 normal;
		float reflector;
	};
	//这里存储的结构是一个结构体
	layout(location = 0) rayPayloadEXT RayPayload rayPayload;
	//设置最大递归次数
	// Max. number of recursion is passed via a specialization constant
	layout (constant_id = 0) const int MAX_RECURSION = 0;
	
	void main() 
	{
		const vec2 pixelCenter = vec2(gl_LaunchIDEXT.xy) + vec2(0.5);
		const vec2 inUV = pixelCenter/vec2(gl_LaunchSizeEXT.xy);
		vec2 d = inUV * 2.0 - 1.0;
	
		vec4 origin = cam.viewInverse * vec4(0,0,0,1);
		vec4 target = cam.projInverse * vec4(d.x, d.y, 1, 1) ;
		vec4 direction = cam.viewInverse*vec4(normalize(target.xyz / target.w), 0);
		//判断是否透明的tag
		uint rayFlags = gl_RayFlagsOpaqueEXT;
		uint cullMask = 0xff;
		float tmin = 0.001;
		float tmax = 10000.0;
	
		vec3 color = vec3(0.0);
		//这里循环计算结果
		for (int i = 0; i < MAX_RECURSION; i++) {
			//计算反射值
			traceRayEXT(topLevelAS, rayFlags, cullMask, 0, 0, 0, origin.xyz, tmin, direction.xyz, tmax, 0);
			vec3 hitColor = rayPayload.color;
			//miss中将distance设置为-1, 因为miss证明光线未与模型hit,不需要反射, 直接获取背景色,跳出循环
			if (rayPayload.distance < 0.0f) {
				color += hitColor;
				break;
			} 
			//rayPayload.reflector = 1证明光线与模型hit,并且白色需要反射,修改光线方向继续反射步骤
			else if (rayPayload.reflector == 1.0f) {
				const vec4 hitPos = origin + direction * rayPayload.distance;
				origin.xyz = hitPos.xyz + rayPayload.normal * 0.001f;
				direction.xyz = reflect(direction.xyz, rayPayload.normal);
			}
			//其他情况直接赋值颜色即可。
			 else {
				color += hitColor;
				break;
			}
	
		}
	
		imageStore(image, ivec2(gl_LaunchIDEXT.xy), vec4(color, 0.0));
	}
	```
- miss.rmiss: 	

	```cpp
	#version 460
	#extension GL_EXT_ray_tracing : require
	
	struct RayPayload {
		vec3 color;
		float distance;
		vec3 normal;
		float reflector;
	};
	
	layout(location = 0) rayPayloadInEXT RayPayload rayPayload;
	
	void main()
	{
		//没有hit赋值背景色即可, 并设置distance = -1.0f, reflector = 0.0f;不进行反射
		// View-independent background gradient to simulate a basic sky background
		const vec3 gradientStart = vec3(0.5, 0.6, 1.0);
		const vec3 gradientEnd = vec3(1.0);
		vec3 unitDir = normalize(gl_WorldRayDirectionEXT);
		float t = 0.5 * (unitDir.y + 1.0);
		rayPayload.color = (1.0-t) * gradientStart + t * gradientEnd;
	
		rayPayload.distance = -1.0f;
		rayPayload.normal = vec3(0.0f);
		rayPayload.reflector = 0.0f;
	}
	```



- closesthit.rchit

```cpp
	#version 460
	#extension GL_EXT_ray_tracing : require
	#extension GL_EXT_nonuniform_qualifier : enable
	
	struct RayPayload {
		vec3 color;
		float distance;
		vec3 normal;
		float reflector;
	};
	
	layout(location = 0) rayPayloadInEXT RayPayload rayPayload;
	
	hitAttributeEXT vec3 attribs;
	
	layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
	layout(binding = 2, set = 0) uniform UBO 
	{
		mat4 viewInverse;
		mat4 projInverse;
		vec4 lightPos;
		int vertexSize;
	} ubo;
	layout(binding = 3, set = 0) buffer Vertices { vec4 v[]; } vertices;
	layout(binding = 4, set = 0) buffer Indices { uint i[]; } indices;
	
	struct Vertex
	{
	  vec3 pos;
	  vec3 normal;
	  vec2 uv;
	  vec4 color;
	  vec4 _pad0; 
	  vec4 _pad1;
	};
	
	Vertex unpack(uint index)
	{
		// Unpack the vertices from the SSBO using the glTF vertex structure
		// The multiplier is the size of the vertex divided by four float components (=16 bytes)
		const int m = ubo.vertexSize / 16;
	
		vec4 d0 = vertices.v[m * index + 0];
		vec4 d1 = vertices.v[m * index + 1];
		vec4 d2 = vertices.v[m * index + 2];
	
		Vertex v;
		v.pos = d0.xyz;
		v.normal = vec3(d0.w, d1.x, d1.y);
		v.color = vec4(d2.x, d2.y, d2.z, 1.0);
	
		return v;
	}
	
	void main()
	{
		ivec3 index = ivec3(indices.i[3 * gl_PrimitiveID], indices.i[3 * gl_PrimitiveID + 1], indices.i[3 * gl_PrimitiveID + 2]);
	
		Vertex v0 = unpack(index.x);
		Vertex v1 = unpack(index.y);
		Vertex v2 = unpack(index.z);
	
		// Interpolate normal
		const vec3 barycentricCoords = vec3(1.0f - attribs.x - attribs.y, attribs.x, attribs.y);
		vec3 normal = normalize(v0.normal * barycentricCoords.x + v1.normal * barycentricCoords.y + v2.normal * barycentricCoords.z);
	
		// Basic lighting
		vec3 lightVector = normalize(ubo.lightPos.xyz);
		float dot_product = max(dot(lightVector, normal), 0.6);
		rayPayload.color = v0.color.rgb * vec3(dot_product);
		//获取最大距离
		rayPayload.distance = gl_RayTmaxEXT;
		rayPayload.normal = normal;
		//如果模型的颜色是白色,开启反射
		// Objects with full white vertex color are treated as reflectors
		rayPayload.reflector = ((v0.color.r == 1.0f) && (v0.color.g == 1.0f) && (v0.color.b == 1.0f)) ? 1.0f : 0.0f; 
	}

小结

  反射是在光追Basic的基础上,通过循环增加渲染次数(反射)。 原理相同,丰富了miss和hit shader的用法。

Callable RayTracing

prepare

  • createBottomLevelAccelerationStructure: 在本地创建模型底层加速结构信息
    • 创建一个三角形的VBO和IBO
      • createBuffer: Transform buffer
      • createBuffer: Vertex buffer
      • createBuffer: Index buffer
    • 创建三个VkDeviceOrHostAddressConstKHR,分别存放tbo, vbo和ibo的指针(deviceAddress)
      • vertexBufferDeviceAddress : getBufferDeviceAddress
      • indexBufferDeviceAddress: getBufferDeviceAddress
      • -transformBufferDeviceAddress: getBufferDeviceAddress
    • 创建加速结构
      • VkAccelerationStructureGeometryKHR
        • 参数数模型的一些基本属性
      • VkAccelerationStructureBuildGeometryInfoKHR: 几何信息
      • VkAccelerationStructureBuildSizesInfoKHR:Get size info
      • vkGetAccelerationStructureBuildSizesKHR
      • createAccelerationStructure: 创建加速结构buffer
        • VkBufferCreateInfo:特殊的参数
          • sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO
          • usage = VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR
        • vkCreateBuffer: 下面使用的参数结构体都使用加速结构相关参数
        • vkGetBufferMemoryRequirements
        • vkAllocateMemory
        • vkBindBufferMemory
        • VkAccelerationStructureCreateInfoKHR
        • vkCreateAccelerationStructureKHR: 创建加速结构
        • vkGetAccelerationStructureDeviceAddressKHR: AS device address
    • createScratchBuffer
      • 在构建底层加速结构的过程中创建一个小的scratch缓冲区
      • VkAccelerationStructureBuildGeometryInfoKHR:
      • VkAccelerationStructureBuildRangeInfoKHR
    • accelerationStructureFeatures.accelerationStructureHostCommands
        • vkBuildAccelerationStructuresKHR
        • createCommandBuffer
        • vkCmdBuildAccelerationStructuresKHR
        • flushCommandBuffer
    • deleteScratchBuffer
  • createTopLevelAccelerationStructure
    • 创建 top level 加速结构
    • VkAccelerationStructureInstanceKHR
    • createBuffer: for instance data
    • VkDeviceOrHostAddressConstKHR
    • getBufferDeviceAddress
    • VkAccelerationStructureGeometryKHR
    • VkAccelerationStructureBuildGeometryInfoKHR
    • VkAccelerationStructureBuildSizesInfoKHR
    • vkGetAccelerationStructureBuildSizesKHR
    • createAccelerationStructure()
    • createScratchBuffer ()
    • VkAccelerationStructureBuildGeometryInfoKHR
    • VkAccelerationStructureBuildGeometryInfoKHR
    • VkAccelerationStructureBuildRangeInfoKHR
    • accelerationStructureFeatures.accelerationStructureHostCommands
        • vkBuildAccelerationStructuresKHR
        • createCommandBuffer
        • vkCmdBuildAccelerationStructuresKHR
        • flushCommandBuffer
    • deleteScratchBuffer
    • instancesBuffer.destroy()
  • createStorageImage(): 存放光追渲染结果:
    - 释放image信息, 阴影教程里没有这部分
    - vkDestroyImageView
    - vkDestroyImage
    - vkFreeMemory
    - storageImage
    - VkImageCreateInfo image = vks::initializers::imageCreateInfo();
    - vkCreateImage
    - vkGetImageMemoryRequirements
    - vkAllocateMemory
    - vkBindImageMemory
    - VkImageViewCreateInfo
    - vkCreateImageView
    - createCommandBuffer
    - setImageLayout
    - flushCommandBuffer
  • createUniformBuffer
    • createBuffer
    • updateUniformBuffers
  • createRayTracingPipeline
    • VkDescriptorSetLayoutBinding:结构体
    • VkDescriptorSetLayoutCreateInfo:结构体
    • vkCreateDescriptorSetLayout
    • VkPipelineLayoutCreateInfo
    • vkCreatePipelineLayout
    • Setup ray tracing shader groups
      • VkPipelineShaderStageCreateInfo
      • Ray generation group
        • VkRayTracingShaderGroupCreateInfoKHR: 结构体,存放shader和其他配置信息
          • shader: raygen.rgen.spv
      • Miss group: 光追未命中
        • VkRayTracingShaderGroupCreateInfoKHR
        • shader: miss.rmiss.spv
      • Closest hit group: 光追命中
        • VkRayTracingShaderGroupCreateInfoKHR
        • shader: closesthit.rchit.spv
      • Callable shader group: 这节重点
        • shaderStages.push_back(loadShader(getShadersPath() + “raytracingcallable/callable” + std::to_string(i+1) + “.rcall.spv”, VK_SHADER_STAGE_CALLABLE_BIT_KHR));
        • 这个shader没有在管线中
    • Create the ray tracing pipeline
      • VkRayTracingPipelineCreateInfoKHR:结构体
      • vkCreateRayTracingPipelinesKHR
  • createShaderBindingTable
    • 创建用于加速结构的 shader 绑定表(Shader Binding Tables)-(SBT)
    • vkGetRayTracingShaderGroupHandlesKHR
    • createShaderBindingTable:创建四个SBT
      • 最后一个是callable shader
      • createBuffer: 创建SBT – raygen
        • 使用字段VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR
      • createBuffer: miss
      • createBuffer: hit
        • createBuffer: callable
      • memcpy
      • memcpy
      • memcpy
      • memcpy
  • createDescriptorSets
    • vkCreateDescriptorPool
    • vkAllocateDescriptorSets
    • writeDescriptorSet: Ray tracing result image
    • writeDescriptorSet: Uniform data
    • writeDescriptorSet: Scene vertex buffer
    • writeDescriptorSet: Scene index buffer
    • vkUpdateDescriptorSets
  • buildCommandBuffers
    • handleResize
      • createStorageImage
      • storageImageDescriptor
      • writeDescriptorSet
    • vkBeginCommandBuffer
    • 使用反射时,这里使用的pipe数增加,这里cmd的两次,应该是只反射一次,命令相同
      • vkCmdBindPipeline
      • vkCmdBindDescriptorSets
      • vkCmdBindPipeline
      • vkCmdBindDescriptorSets
    • vkCmdTraceRaysKHR
    • Copy ray tracing output to swap chain image
      • setImageLayout
      • setImageLayout
      • vkCmdCopyImage
      • setImageLayout
      • setImageLayout
    • vkEndCommandBuffer

render

  • draw
    • prepareFrame
    • vkQueueSubmit
    • submitFrame
  • updateUniformBuffers

shader

  • raygen.rgen:正常渲染
  • miss.rmiss: 正常渲染
  • closesthit.rchit
	#version 460
	#extension GL_EXT_ray_tracing : require
	#extension GL_EXT_nonuniform_qualifier : enable
	
	layout(location = 0) rayPayloadInEXT vec3 hitValue;
	//注意这里返回一个callable数据
	layout(location = 0) callableDataEXT vec3 outColor;
	hitAttributeEXT vec3 attribs;
	
	layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
	
	void main()
	{
		// Execute the callable shader indexed by the current geometry being hit
		// For our sample this means that the first callable shader in the SBT is invoked for the first triangle, the second callable shader for the second triangle, etc.
		//待光线与面片相交,不直接返回该像素的颜色,而是调用callable函数,让callable shader 加工该命中像素的颜色,再输出。
		executeCallableEXT(gl_GeometryIndexEXT, 0);
	
		hitValue = outColor;
	}

  • callable1.rcall
	#version 460 core
	#extension GL_EXT_ray_tracing : enable
	layout(location = 0) callableDataInEXT vec3 outColor;
	
	void main()
	{
		//gl_LaunchIDEXT 当前像素坐标(不是uv)
	    // Generate a checker board pattern
		vec2 pos = vec2(gl_LaunchIDEXT / 8);
		//应该是奇数像素赋值白色,偶数像素赋值黑色
		outColor = vec3(mod(pos.x + mod(pos.y, 2.0), 2.0));
	}
  • callable2.rcall
	//这里单纯给了一个绿色作为颜色输出
	#version 460 core
	#extension GL_EXT_ray_tracing : enable
	//
	layout(location = 0) callableDataInEXT vec3 outColor;
	
	void main()
	{
	    outColor = vec3(0.0, 1.0, 0.0);
	}
  • callable3.rcall
	#version 460 core
	#extension GL_EXT_ray_tracing : enable
	
	layout(location = 0) callableDataInEXT vec3 outColor;
	
	void main()
	{
	    // Generate a line pattern
		vec2 pos = vec2(gl_LaunchIDEXT / 8);
		//奇数行白色,偶数行黑色
		outColor = vec3(mod(pos.y, 2.0));
	}

小结

  本节主要讲executeCallableEXT函数的使用方法。总结来说,感觉应该是为光追处理材质管线用的, 也可以做一些后处理。

Ray Query

prepare

  • loadAssets: 加载模型, 这里使用阴影小节模型
  • prepareUniformBuffers
    • createBuffer
    • updateLight
    • updateUniformBuffers
  • setupDescriptorSetLayout
    • descriptorSetLayoutBinding
    • vkCreateDescriptorSetLayout
    • vkCreatePipelineLayout
  • preparePipelines
    • pipelineCreateInfo
    • vkCreateGraphicsPipelines:这里绑定了正常管线的shader(VS\FS)
  • createBottomLevelAccelerationStructure: 在本地创建模型底层加速结构信息
    - vertexBufferDeviceAddress : getBufferDeviceAddress
    - indexBufferDeviceAddress: getBufferDeviceAddress
    • 创建加速结构
      • VkAccelerationStructureGeometryKHR
        • 参数数模型的一些基本属性
      • VkAccelerationStructureBuildGeometryInfoKHR: 几何信息
      • VkAccelerationStructureBuildSizesInfoKHR:Get size info
      • vkGetAccelerationStructureBuildSizesKHR
      • createAccelerationStructure: 创建加速结构buffer
        • VkBufferCreateInfo:特殊的参数
          • sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO
          • usage = VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR
        • vkCreateBuffer: 下面使用的参数结构体都使用加速结构相关参数
        • vkGetBufferMemoryRequirements
        • vkAllocateMemory
        • vkBindBufferMemory
        • VkAccelerationStructureCreateInfoKHR
        • vkCreateAccelerationStructureKHR: 创建加速结构
        • vkGetAccelerationStructureDeviceAddressKHR: AS device address
    • createScratchBuffer
      • 在构建底层加速结构的过程中创建一个小的scratch缓冲区
      • VkAccelerationStructureBuildGeometryInfoKHR:
      • VkAccelerationStructureBuildRangeInfoKHR
    • accelerationStructureFeatures.accelerationStructureHostCommands
        • vkBuildAccelerationStructuresKHR
        • createCommandBuffer
        • vkCmdBuildAccelerationStructuresKHR
        • flushCommandBuffer
    • deleteScratchBuffer
  • createTopLevelAccelerationStructure
    • 创建 top level 加速结构
    • VkAccelerationStructureInstanceKHR
    • createBuffer: for instance data
    • VkDeviceOrHostAddressConstKHR
    • getBufferDeviceAddress
    • VkAccelerationStructureGeometryKHR
    • VkAccelerationStructureBuildGeometryInfoKHR
    • VkAccelerationStructureBuildSizesInfoKHR
    • vkGetAccelerationStructureBuildSizesKHR
    • createAccelerationStructure()
    • createScratchBuffer ()
    • VkAccelerationStructureBuildGeometryInfoKHR
    • VkAccelerationStructureBuildGeometryInfoKHR
    • VkAccelerationStructureBuildRangeInfoKHR
    • accelerationStructureFeatures.accelerationStructureHostCommands
        • vkBuildAccelerationStructuresKHR
        • createCommandBuffer
        • vkCmdBuildAccelerationStructuresKHR
        • flushCommandBuffer
    • deleteScratchBuffer
    • instancesBuffer.destroy()
  • setupDescriptorPool: 这里没有创建StorageImage
    • vkCreateDescriptorPool
  • setupDescriptorSets
    • vkAllocateDescriptorSets
    • VkWriteDescriptorSetAccelerationStructureKHR
      • 注意这个表示,是正常管线与光追管线的桥梁
    • writeDescriptorSets
    • vkUpdateDescriptorSets
  • buildCommandBuffers
    • commandBufferBeginInfo
    • loop
      • vkBeginCommandBuffer
      • vkCmdBeginRenderPass
      • vkCmdSetViewport
      • vkCmdSetScissor
      • vkCmdBindDescriptorSets
      • vkCmdBindPipeline
      • drawUI
      • vkCmdEndRenderPass
      • vkEndCommandBuffer

render

  • draw
    • prepareFrame
    • vkQueueSubmit
    • submitFrame
  • updateLight
  • updateUniformBuffers

shader

  • VS:正常渲染
  • FS:
	#version 460
	#extension GL_EXT_ray_tracing : enable
	#extension GL_EXT_ray_query : enable
	//管线初始化的时候,设置了模型的加速结构,管线可以使用该标识引用加速结构
	layout (binding = 2, set = 0) uniform accelerationStructureEXT topLevelAS;
	
	layout (location = 0) in vec3 inNormal;
	layout (location = 1) in vec3 inColor;
	layout (location = 2) in vec3 inViewVec;
	layout (location = 3) in vec3 inLightVec;
	layout (location = 4) in vec3 inWorldPos;
	
	layout (location = 0) out vec4 outFragColor;
	
	#define ambient 0.1
	
	void main() 
	{	
		vec3 N = normalize(inNormal);
		vec3 L = normalize(inLightVec);
		vec3 V = normalize(inViewVec);
		vec3 R = normalize(-reflect(L, N));
		vec3 diffuse = max(dot(N, L), ambient) * inColor;
		//首先进行正常的光照计算
		outFragColor = vec4(diffuse, 1.0);
		//准备rayQuery实例
		rayQueryEXT rayQuery;
		//inWorldPos点向L方向发射光线
		rayQueryInitializeEXT(rayQuery, topLevelAS, gl_RayFlagsTerminateOnFirstHitEXT, 0xFF, inWorldPos, 0.01, L, 1000.0);
		//等该查询完成
		// Start the ray traversal, rayQueryProceedEXT returns false if the traversal is complete
		while (rayQueryProceedEXT(rayQuery)) { }
		//如果管线与场景中模型有交点,即有阴影存在
		// If the intersection has hit a triangle, the fragment is shadowed
		if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT ) {
			outFragColor *= 0.1;
		}
	}

小结

  本节主要讲,正常管线如何使用加速结构。使用场景会很多。与之前的raytracingshadows程序做了比较,该节程序在4K屏(3840*2160)中1200+FPS, 而raytracingshadows程序只有500+FPS。 初步估计(猜测): closesthit虽然做了cullMask,剔除的顶点依然少于FS。所以碰撞检测的次数比FS多很多。后续复习时再深入分析一下原因。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值