可用于确定每个像素对应对象的 ObjectId 请求。可以使用 Camera.SubmitRenderRequest 或 RenderPipeline.SubmitRenderRequest 提交,结果可以在 C# 中的 CPU 或着色器中的 GPU 上使用。
提交此渲染请求后,将填充 ObjectIdRequest._result 字段,并且 ObjectIdRequest._destination 中的每个像素将包含一个 32 位颜色,可以使用 ObjectIdResult.DecodeIdFromColor 将其解码为 32 位整数索引。然后,可以在 ObjectIdResult._idToObjectMapping 中查找此 32 位索引,以确定每个像素对应的对象。下面的 C# 代码示例演示了如何使用此渲染请求来确定每个像素对应的对象。
尽管没有内置功能可以在 GPU 上将对象 ID(ObjectIdResult._idToObjectMapping 中的索引)从颜色解码,但可以使用以下 HLSL 着色器函数来实现此目的: int decodeObjectIdInShader(float4 color) { return (int)(color.r * 255) + ((int)(color.g * 255) << 8) + ((int)(color.b * 255) << 16) + ((int)(color.a * 255) << 24); }
SRP 兼容性
此渲染请求目前在编辑器外部不受支持。
其他资源:Camera.SubmitRenderRequest、RenderPipeline.SubmitRenderRequest、ObjectIdResult。
using UnityEngine; using UnityEngine; using UnityEngine.Experimental.Rendering; using UnityEngine.Rendering;
// Snapshot containing the object at each pixel from the perspective of the camera. // The snapshot is taken when this class is constructed. class ObjectIdSnapshot { Texture2D m_ObjectIdTexture; Object[] m_IdToObjectMapping;
public ObjectIdSnapshot(Camera camera) { var cameraTargetTexture = camera.targetTexture; var renderTexture = new RenderTexture( width: cameraTargetTexture.width, height: cameraTargetTexture.height, colorFormat: GraphicsFormat.R8G8B8A8_UNorm, depthStencilFormat: GraphicsFormat.D32_SFloat);
var objectIdRequest = new ObjectIdRequest(destination: renderTexture); camera.SubmitRenderRequest(objectIdRequest); m_ObjectIdTexture = ConvertTexture(objectIdRequest.destination); m_IdToObjectMapping = objectIdRequest.result.idToObjectMapping; }
public GameObject GetGameObjectAtPixel(int x, int y) { var color = m_ObjectIdTexture.GetPixel(x, y); var id = ObjectIdResult.DecodeIdFromColor(color); var obj = m_IdToObjectMapping[id]; return GetParentGameObject(obj); }
static GameObject GetParentGameObject(Object obj) { if (obj is null) { return null; } if (obj is GameObject gameObject) { return gameObject; } if (obj is MonoBehaviour component) { return component.gameObject; } return null; }
static Texture2D ConvertTexture(RenderTexture renderTexture) { var previousActiveRenderTexture = RenderTexture.active; RenderTexture.active = renderTexture; var cpuTexture = new Texture2D(renderTexture.width, renderTexture.height, renderTexture.graphicsFormat, TextureCreationFlags.None); cpuTexture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0); cpuTexture.Apply(); RenderTexture.active = previousActiveRenderTexture; return cpuTexture; } }
destination | 存储请求渲染结果的 RenderTexture。可以解码此 RenderTexture 中的颜色以确定在每个像素处渲染的对象,首先使用 ObjectIdResult.DecodeIdFromColor 将颜色解码为索引,然后在此索引中查找 ObjectIdResult._idToObjectMapping。 |
face | 存储渲染结果的目标 Cubemap 面。 |
mipLevel | 存储渲染输出的目标 mipLevel。 |
result | 在提交并完成渲染请求后填充的结果字段,其中包含解释在 ObjectIdRequest._destination RenderTexture 中渲染的颜色编码对象 ID 所需的 ObjectIdResult._idToObjectMapping。 |
slice | 存储渲染输出的目标切片。 |