CommandBuffer.BuildRayTracingAccelerationStructure
Declaration
public void BuildRayTracingAccelerationStructure(Rendering.RayTracingAccelerationStructure accelerationStructure);public void BuildRayTracingAccelerationStructure(Rendering.RayTracingAccelerationStructure accelerationStructure, Vector3 relativeOrigin);public void BuildRayTracingAccelerationStructure(Rendering.RayTracingAccelerationStructure accelerationStructure, Rendering.RayTracingAccelerationStructure.BuildSettings buildSettings);Параметры
| Параметр | Описание |
|---|---|
| accelerationStructure | RayTracingAccelerationStructure для создания. |
| relativeOrigin | Относительное происхождение экземпляров трассирования лучей. Значение по умолчанию — Vector3.zero. Чтобы использовать трассирование лучей относительно камеры, установите этот параметр на положение камеры. |
| buildSettings | BuildSettings для использования. |
Описание
Добавляет команду для построения RayTracingAccelerationStructure для использования в отправке трассирования лучей или при использовании встроенного трассирования лучей (запросы на лучи).
Чтобы убедиться, что структура ускорения обновлена, вызовите этот метод перед использованием структуры ускорения в шейдерах с трассированием лучей (например, перед вызовом CommandBuffer.DispatchRays) или при использовании встроенного трассирования лучей. В следующем примере метод PositionRandomInstances использует отправку вычисления шейдера для изменения позиций экземпляров сетки в мировом пространстве, после чего RayTracingAccelerationStructure восстанавливается.
using UnityEngine; using UnityEngine.Rendering;
public class RayTracingInstanceManager : MonoBehaviour { public Mesh instanceMesh; public Material instanceMaterial; public int maxInstanceCount = 1024;
public Vector3 spawnBounds = new Vector3(10f, 0f, 10f); public ComputeShader positioningShader; public RayTracingShader rayTracingShader;
private RayTracingAccelerationStructure rtas; private GraphicsBuffer instanceBuffer; private GraphicsBuffer countBuffer; private CommandBuffer cmd; private RenderTexture rayTracingOutput; private uint cameraWidth = 0; private uint cameraHeight = 0;
void Start() { InitializeRayTracing(); UpdateRaytracingWorld(); }
void InitializeRayTracing() { // Create command buffer cmd = new CommandBuffer(); cmd.name = "Ray Tracing Indirect Setup";
// Set up acceleration structure var settings = new RayTracingAccelerationStructure.Settings { managementMode = RayTracingAccelerationStructure.ManagementMode.Manual, layerMask = -1 }; rtas = new RayTracingAccelerationStructure(settings);
// Create buffers instanceBuffer = new GraphicsBuffer( GraphicsBuffer.Target.Structured, maxInstanceCount, System.Runtime.InteropServices.Marshal.SizeOf(typeof(Matrix4x4)) );
countBuffer = new GraphicsBuffer( GraphicsBuffer.Target.IndirectArguments, 1, sizeof(int) ); }
void CreateResources() { if (cameraWidth != Camera.main.pixelWidth || cameraHeight != Camera.main.pixelHeight) { if (rayTracingOutput != null) rayTracingOutput.Release();
rayTracingOutput = new RenderTexture(Camera.main.pixelWidth, Camera.main.pixelHeight, 0, RenderTextureFormat.ARGBHalf); rayTracingOutput.enableRandomWrite = true; rayTracingOutput.Create();
cameraWidth = (uint)Camera.main.pixelWidth; cameraHeight = (uint)Camera.main.pixelHeight; } }
void PositionRandomInstances() { if (positioningShader == null) { Debug.LogError("Error: Compute shader is missing. Assign a compute shader to the positioningShader property."); return; }
// Add instances indirectly RayTracingMeshInstanceConfig meshConfig = new RayTracingMeshInstanceConfig(); meshConfig.mesh = instanceMesh; meshConfig.material = instanceMaterial; meshConfig.enableTriangleCulling = false; meshConfig.lightProbeUsage = LightProbeUsage.Off; meshConfig.layer = -1;
rtas.AddInstancesIndirect(meshConfig, instanceBuffer, maxInstanceCount, countBuffer, 0);
// Upload data to buffers cmd.SetBufferData(countBuffer, new int[] { 0, maxInstanceCount });
// Generate random instance positions on GPU using a compute shader. cmd.SetComputeVectorParam(positioningShader, "SpawnBounds", spawnBounds); cmd.SetComputeBufferParam(positioningShader, 0, "InstanceMatrices", instanceBuffer); cmd.SetComputeIntParam(positioningShader, "TotalInstanceCount", maxInstanceCount);
int threadGroups = (maxInstanceCount + 64 - 1) / 64; cmd.DispatchCompute(positioningShader, 0, threadGroups, 1, 1); }
void UpdateRaytracingWorld() { if (instanceMesh == null || instanceMaterial == null) { Debug.LogError("Error: Mesh or material is missing. Assign a mesh to the instanceMesh property and a material to the instanceMaterial property."); return; }
// Clear previous instances rtas.ClearInstances();
PositionRandomInstances();
// Build acceleration structure from the indirect instances. cmd.BuildRayTracingAccelerationStructure(rtas);
// The command buffer will be executed in the next OnRenderImage }
void Update() { // Example: Update structure when space is pressed if (Input.GetKeyDown(KeyCode.Space)) { UpdateRaytracingWorld(); } }
[ImageEffectOpaque] void OnRenderImage(RenderTexture src, RenderTexture dest) { if (!SystemInfo.supportsRayTracing || !rayTracingShader) { Debug.LogWarning("Warning: The Ray Tracing API is not supported by this GPU or by the current graphics API."); Graphics.Blit(src, dest); return; }
CreateResources();
cmd.SetRayTracingShaderPass(rayTracingShader, "Test");
// Input cmd.SetRayTracingAccelerationStructure(rayTracingShader, Shader.PropertyToID("g_AccelStruct"), rtas); cmd.SetRayTracingMatrixParam(rayTracingShader, Shader.PropertyToID("g_InvViewMatrix"), Camera.main.cameraToWorldMatrix); cmd.SetGlobalVector(Shader.PropertyToID("g_CameraPos"), Camera.main.transform.position);
// Output cmd.SetRayTracingTextureParam(rayTracingShader, Shader.PropertyToID("g_Output"), rayTracingOutput);
// Execute the raytracing shader cmd.DispatchRays(rayTracingShader, "MainRayGenShader", cameraWidth, cameraHeight, 1);
// Execute command buffer Graphics.ExecuteCommandBuffer(cmd); cmd.Clear();
Graphics.Blit(rayTracingOutput, dest); }
void OnDisable() { // Cleanup if (instanceBuffer != null) { instanceBuffer.Release(); instanceBuffer = null; }
if (countBuffer != null) { countBuffer.Release(); countBuffer = null; }
if (rtas != null) { rtas.Dispose(); rtas = null; }
if (cmd != null) { cmd.Release(); cmd = null; }
if (rayTracingOutput != null) { rayTracingOutput.Release(); rayTracingOutput = null; } } }
Дополнительные ресурсы: ,SetRayTracingAccelerationStructure,, ,SetGlobalRayTracingAccelerationStructure,, ,DispatchRays,, ,RayTracingAccelerationStructure.Build,.