浏览代码

Initial support for XR and RenderPass

Basic use case using prototype engine code living in Hg graphics/srp/xr-renderpass-sandbox.  Works with single pass double-wide.

Engine handles connecting CameraTarget to VR device texture.

Remaining work:
* Support stereo instancing
* Support transient textures
/RenderPassXR_Sandbox
robbiesri 7 年前
当前提交
6232ca29
共有 1 个文件被更改,包括 62 次插入91 次删除
  1. 153
      Assets/ScriptableRenderPipeline/BasicRenderPipeline/BasicRenderPipeline.cs

153
Assets/ScriptableRenderPipeline/BasicRenderPipeline/BasicRenderPipeline.cs


}
}
public struct RenderInfo
{
public bool useIntermediateBlit;
public RenderPassAttachment m_Color;
public RenderPassAttachment m_Depth;
}
bool useIntermediateBlit;
RenderInfo renderInfo;
private void SetupRenderPassAttachments()
{
renderInfo.m_Color = new RenderPassAttachment(RenderTextureFormat.ARGB32);
renderInfo.m_Depth = new RenderPassAttachment(RenderTextureFormat.Depth);
renderInfo.m_Color.Clear(new Color(0.0f, 0.0f, 0.0f, 0.0f), 1.0f, 0);
renderInfo.m_Depth.Clear(new Color(), 1.0f, 0);
}
useIntermediateBlit = false;
renderInfo.useIntermediateBlit = false;
SetupRenderPassAttachments();
useIntermediateBlit = useIntermediate;
renderInfo.useIntermediateBlit = useIntermediate;
SetupRenderPassAttachments();
BasicRendering.Render(renderContext, cameras, useIntermediateBlit);
BasicRendering.Render(renderContext, cameras, ref renderInfo);
}
}

static void ConfigureAndBindIntermediateRenderTarget(ScriptableRenderContext context, Camera cam, bool stereoEnabled, out RenderTargetIdentifier intermediateRTID, out bool isRTTexArray)
{
var intermediateRT = Shader.PropertyToID("_IntermediateTarget");
intermediateRTID = new RenderTargetIdentifier(intermediateRT);
isRTTexArray = false;
var bindIntermediateRTCmd = CommandBufferPool.Get("Bind intermediate RT");
if (stereoEnabled)
{
RenderTextureDescriptor vrDesc = XRSettings.eyeTextureDesc;
vrDesc.depthBufferBits = 24;
if (vrDesc.dimension == TextureDimension.Tex2DArray)
isRTTexArray = true;
bindIntermediateRTCmd.GetTemporaryRT(intermediateRT, vrDesc, FilterMode.Point);
}
else
{
int w = cam.pixelWidth;
int h = cam.pixelHeight;
bindIntermediateRTCmd.GetTemporaryRT(intermediateRT, w, h, 24, FilterMode.Point, RenderTextureFormat.Default, RenderTextureReadWrite.Default, 1, true);
}
if (isRTTexArray)
bindIntermediateRTCmd.SetRenderTarget(intermediateRTID, 0, CubemapFace.Unknown, -1); // depthSlice == -1 => bind all slices
else
bindIntermediateRTCmd.SetRenderTarget(intermediateRTID);
context.ExecuteCommandBuffer(bindIntermediateRTCmd);
CommandBufferPool.Release(bindIntermediateRTCmd);
}
static void BlitFromIntermediateToCameraTarget(ScriptableRenderContext context, RenderTargetIdentifier intermediateRTID, bool isRTTexArray)
{
var blitIntermediateRTCmd = CommandBufferPool.Get("Copy intermediate RT to default RT");
if (isRTTexArray)
{
// Currently, Blit does not allow specification of a slice in a texture array.
// It can use the CurrentActive render texture's bound slices, so we use that
// as a temporary workaround.
blitIntermediateRTCmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget, 0, CubemapFace.Unknown, -1);
blitIntermediateRTCmd.Blit(intermediateRTID, BuiltinRenderTextureType.CurrentActive);
}
else
blitIntermediateRTCmd.Blit(intermediateRTID, BuiltinRenderTextureType.CameraTarget);
context.ExecuteCommandBuffer(blitIntermediateRTCmd);
CommandBufferPool.Release(blitIntermediateRTCmd);
}
public static void Render(ScriptableRenderContext context, IEnumerable<Camera> cameras, bool useIntermediateBlitPath)
public static void Render(ScriptableRenderContext context, IEnumerable<Camera> cameras, ref RenderInfo renderInfo)
{
bool stereoEnabled = XRSettings.isDeviceActive;

// Setup camera for rendering (sets render target, view/projection matrices and other
// per-camera built-in shader variables).
// If stereo is enabled, we also configure stereo matrices, viewports, and XR device render targets
// We still need this for RenderPass
// Draws in-between [Start|Stop]MultiEye are stereo-ized by engine
if (stereoEnabled)
context.StartMultiEye(camera);
// This is honestly crazy code to write. We should be getting explicit targets
// whether it be backbuffer, camera target texture, or VR device active texture
renderInfo.m_Color.BindSurface(BuiltinRenderTextureType.CameraTarget, false, true);
renderInfo.m_Depth.BindSurface(BuiltinRenderTextureType.Depth, false, false);
RenderTargetIdentifier intermediateRTID = new RenderTargetIdentifier(BuiltinRenderTextureType.CurrentActive);
bool isIntermediateRTTexArray = false;
if (useIntermediateBlitPath)
// Setup global lighting shader variables
SetupLightShaderVariables(cull.visibleLights, context);
int renderPassWidth = camera.pixelWidth;
int renderPassHeight = camera.pixelHeight;
if (stereoEnabled)
ConfigureAndBindIntermediateRenderTarget(context, camera, stereoEnabled, out intermediateRTID, out isIntermediateRTTexArray);
RenderTextureDescriptor xrDesc = XRSettings.eyeTextureDesc;
renderPassWidth = xrDesc.width;
renderPassHeight = xrDesc.height;
// clear depth buffer
var cmd = CommandBufferPool.Get();
cmd.ClearRenderTarget(true, false, Color.black);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
// Setup global lighting shader variables
SetupLightShaderVariables(cull.visibleLights, context);
if (stereoEnabled)
{
// Should this be integrated into RenderPass?
context.StartMultiEye(camera);
}
// Draw opaque objects using BasicPass shader pass
var settings = new DrawRendererSettings(cull, camera, new ShaderPassName("BasicPass"));
settings.sorting.flags = SortFlags.CommonOpaque;
settings.inputFilter.SetQueuesOpaque();
context.DrawRenderers(ref settings);
using (RenderPass rp = new RenderPass(context, renderPassWidth, renderPassHeight, 1, new[] { renderInfo.m_Color }, renderInfo.m_Depth, stereoEnabled))
{
// Draw skybox
context.DrawSkybox(camera);
using (new RenderPass.SubPass(rp, new[] { renderInfo.m_Color }, null))
{
// Draw opaque objects using BasicPass shader pass
var settings = new DrawRendererSettings(cull, camera, new ShaderPassName("BasicPass"));
settings.sorting.flags = SortFlags.CommonOpaque;
settings.inputFilter.SetQueuesOpaque();
context.DrawRenderers(ref settings);
// Draw transparent objects using BasicPass shader pass
settings.sorting.flags = SortFlags.CommonTransparent;
settings.inputFilter.SetQueuesTransparent();
context.DrawRenderers(ref settings);
// Draw skybox
context.DrawSkybox(camera);
if (useIntermediateBlitPath)
{
BlitFromIntermediateToCameraTarget(context, intermediateRTID, isIntermediateRTTexArray);
// Draw transparent objects using BasicPass shader pass
settings.sorting.flags = SortFlags.CommonTransparent;
settings.inputFilter.SetQueuesTransparent();
context.DrawRenderers(ref settings);
}
// StereoEndRender will reset state on the camera to pre-Stereo settings,
// and invoke XR based events/callbacks.
// StereoEndRender will reset state on the camera to pre-Stereo settings,
// and invoke XR based events/callbacks.
context.StereoEndRender(camera);
}

正在加载...
取消
保存