protected override void Execute(CustomPassContext ctx)
    {
        if (!render || bakingCamera == null ||
            ctx.hdCamera.camera == bakingCamera)
        {
            return;
        }

        bakingCamera.TryGetCullingParameters(out var cullingParams);

        cullingParams.cullingOptions = CullingOptions.ShadowCasters;

        // Assign the custom culling result to the context
        // so it'll be used for the following operations
        cullingResultField.SetValueDirect(__makeref(ctx), ctx.renderContext.Cull(ref cullingParams));
        var overrideDepthTest = new RenderStateBlock(RenderStateMask.Depth)
        {
            depthState = new DepthState(true, CompareFunction.LessEqual)
        };

        // Sync baking camera aspect ratio with RT (see https://github.com/alelievr/HDRP-Custom-Passes/issues/24)
        bakingCamera.aspect    = ctx.hdCamera.camera.aspect;
        bakingCamera.pixelRect = ctx.hdCamera.camera.pixelRect;

        // Depth
        if (depthTexture != null)
        {
            SyncRenderTextureAspect(depthTexture, ctx.hdCamera.camera);
            CoreUtils.SetRenderTarget(ctx.cmd, depthTexture, ClearFlag.Depth);
            CustomPassUtils.RenderDepthFromCamera(ctx, bakingCamera, bakingCamera.cullingMask, overrideRenderState: overrideDepthTest);
        }

        // ctx.hdCamera.camera.pixelRect = oldRect;
    }
예제 #2
0
    void GenerateGaussianMips(CustomPassContext ctx)
    {
        RTHandle source = (targetColorBuffer == TargetBuffer.Camera) ? ctx.cameraColorBuffer : ctx.customColorBuffer.Value;

        // Save the non blurred color into a copy if the mask is enabled:
        if (useMask)
        {
            ctx.cmd.CopyTexture(source, colorCopy);
        }

        var targetBuffer = (useMask) ? downSampleBuffer : source;

        CustomPassUtils.GaussianBlur(ctx, source, targetBuffer, blurBuffer, radius: radius);

        if (useMask)
        {
            // Merge the non blur copy and the blurred version using the mask buffers
            using (new ProfilingScope(ctx.cmd, new ProfilingSampler("Compose Mask Blur")))
            {
                var compositingProperties = new MaterialPropertyBlock();

                compositingProperties.SetFloat(ShaderID._Radius, radius / 4f); // The blur is 4 pixel wide in the shader
                compositingProperties.SetTexture(ShaderID._Source, downSampleBuffer);
                compositingProperties.SetTexture(ShaderID._ColorBufferCopy, colorCopy);
                compositingProperties.SetTexture(ShaderID._Mask, maskBuffer);
                compositingProperties.SetTexture(ShaderID._MaskDepth, maskDepthBuffer);
                compositingProperties.SetFloat(ShaderID._InvertMask, invertMask ? 1 : 0);
                SetViewPortSize(ctx.cmd, compositingProperties, source);
                HDUtils.DrawFullScreen(ctx.cmd, compositeMaterial, source, compositingProperties, shaderPassId: 0); // Do not forget the shaderPassId: ! or it won't work
            }
        }
    }
예제 #3
0
    protected override void Execute(CustomPassContext ctx)
    {
        // Disable it for scene view because it's horrible
        if (ctx.hdCamera.camera.cameraType == CameraType.SceneView)
        {
            return;
        }

        var currentCam = ctx.hdCamera.camera;

        // Copy settings of our current camera
        foregroundCamera.transform.SetPositionAndRotation(currentCam.transform.position, currentCam.transform.rotation);
        foregroundCamera.CopyFrom(ctx.hdCamera.camera);
        // Make sure the camera is disabled, we don't want it to render anything.
        foregroundCamera.enabled     = false;
        foregroundCamera.fieldOfView = fov;
        foregroundCamera.cullingMask = foregroundMask;

        var depthTestOverride = new RenderStateBlock(RenderStateMask.Depth)
        {
            depthState = new DepthState(true, CompareFunction.LessEqual),
        };

        CustomPassUtils.RenderFromCamera(ctx, foregroundCamera, ctx.cameraColorBuffer, ctx.cameraDepthBuffer, ClearFlag.None, foregroundMask, overrideRenderState: depthTestOverride);
    }
예제 #4
0
    protected override void Execute(CustomPassContext ctx)
    {
        // Disable it for scene view because it's horrible
        if (ctx.hdCamera.camera.cameraType == CameraType.SceneView)
        {
            return;
        }

        var currentCam = ctx.hdCamera.camera;

        // Copy settings of our current camera
        foregroundCamera.transform.SetPositionAndRotation(currentCam.transform.position, currentCam.transform.rotation);
        foregroundCamera.CopyFrom(ctx.hdCamera.camera);
        // Make sure the camera is disabled, we don't want it to render anything.
        foregroundCamera.enabled     = false;
        foregroundCamera.fieldOfView = fov;
        foregroundCamera.cullingMask = foregroundMask;

        var depthTestOverride = new RenderStateBlock(RenderStateMask.Depth)
        {
            depthState = new DepthState(false, CompareFunction.Always),
        };

        // TODO: Nuke the depth in the after depth and normal injection point
        // Override depth to 0 (avoid artifacts with screen-space effects)
        ctx.cmd.SetRenderTarget(trueDepthBuffer, 0, CubemapFace.Unknown, 0); // TODO: make it work in VR
        CustomPassUtils.RenderFromCamera(ctx, foregroundCamera, null, null, ClearFlag.None, foregroundMask, overrideMaterial: depthClearMaterial, overrideMaterialIndex: 0);
        // Render the object color
        CustomPassUtils.RenderFromCamera(ctx, foregroundCamera, ctx.cameraColorBuffer, ctx.cameraDepthBuffer, ClearFlag.None, foregroundMask, overrideRenderState: depthTestOverride);
    }
예제 #5
0
    protected override void Execute(CustomPassContext ctx)
    {
        float radius = 8.0f;

        // make radius screen size dependent to have blur size consistent accross dimensions.
        radius *= ctx.cameraColorBuffer.rtHandleProperties.rtHandleScale.x;
        CustomPassUtils.GaussianBlur(
            ctx, ctx.cameraColorBuffer, ctx.cameraColorBuffer, halfResTarget,
            new Vector4(0.5f, 0.5f, 0, 0), new Vector4(0.5f, 0.5f, 0, 0),
            4, radius / 2, 0, 0, true
            );
        CustomPassUtils.GaussianBlur(
            ctx, ctx.cameraColorBuffer, ctx.cameraColorBuffer, halfResTarget,
            new Vector4(0.5f, 0.5f, 0.5f, 0), new Vector4(0.5f, 0.5f, 0.5f, 0),
            16, radius, 0, 0, false
            );
        CustomPassUtils.GaussianBlur(
            ctx, ctx.cameraColorBuffer, ctx.cameraColorBuffer, ctx.customColorBuffer.Value,
            new Vector4(0.5f, 0.5f, 0.5f, 0.5f), new Vector4(0.5f, 0.5f, 0.5f, 0.5f),
            16, radius * 2, 0, 0, false
            );
        CustomPassUtils.GaussianBlur(
            ctx, ctx.cameraColorBuffer, ctx.cameraColorBuffer, ctx.customColorBuffer.Value,
            new Vector4(0.5f, 0.5f, 0, 0.5f), new Vector4(0.5f, 0.5f, 0, 0.5f),
            64, radius * 4, 0, 0, true
            );
    }
예제 #6
0
        // Tell if we need to show a warning for rendering opaque object and we're in deferred.
        bool ShowOpaqueObjectWarning()
        {
            if (HDRenderPipeline.currentAsset == null)
            {
                return(false);
            }

            // Only opaque objects are concerned
            RenderQueueRange currentRange = CustomPassUtils.GetRenderQueueRangeFromRenderQueueType((CustomPass.RenderQueueType)m_RenderQueue.intValue);
            var  allOpaque = HDRenderQueue.k_RenderQueue_AllOpaque;
            bool customPassQueueContainsOpaqueObjects = currentRange.upperBound >= allOpaque.lowerBound && currentRange.lowerBound <= allOpaque.upperBound;

            if (!customPassQueueContainsOpaqueObjects)
            {
                return(false);
            }

            // Only Deferred rendering
            if (HDRenderPipeline.currentAsset.currentPlatformRenderPipelineSettings.supportedLitShaderMode != RenderPipelineSettings.SupportedLitShaderMode.DeferredOnly)
            {
                return(false);
            }

            return(true);
        }
예제 #7
0
    // This function is called from the custom post process at the before post process injection point, just after TAA
    public void RenderVideoObjects(CommandBuffer cmd)
    {
        // Fix depth buffer jittering
        if (fixDepthBufferJittering)
        {
            using (new ProfilingScope(cmd, new ProfilingSampler("Render Depth Buffer without jittering")))
            {
                // We need to re-render everything to get the non-jittered depth buffer :/
                CoreUtils.SetRenderTarget(cmd, videoDepthBuffer);
                CoreUtils.ClearRenderTarget(cmd, ClearFlag.Depth, Color.black);
                var tags   = new ShaderTagId[] { new ShaderTagId("DepthForwardOnly"), new ShaderTagId("DepthOnly") };
                var result = new RendererListDesc(tags, context.cullingResults, context.hdCamera.camera)
                {
                    rendererConfiguration      = PerObjectData.None,
                    renderQueueRange           = RenderQueueRange.all,
                    sortingCriteria            = SortingCriteria.CommonOpaque,
                    excludeObjectMotionVectors = false,
                    layerMask = fixDepthBufferJitteringMask,
                    // stateBlock = overrideRenderState,
                };
                CoreUtils.DrawRendererList(context.renderContext, context.cmd, RendererList.Create(result));
            }
        }

        // TODO: add an option to render the "frame" objects in the unjittered depth-buffer to avoid flickering
        CoreUtils.SetRenderTarget(cmd, videoColorBuffer, fixDepthBufferJittering ? videoDepthBuffer : context.cameraDepthBuffer, ClearFlag.Color);
        var renderState = new RenderStateBlock(RenderStateMask.Depth)
        {
            depthState = new DepthState(false, CompareFunction.LessEqual)
        };

        CustomPassUtils.DrawRenderers(context, videoObjectMask, overrideRenderState: renderState);
    }
예제 #8
0
    protected override void Execute(CustomPassContext ctx)
    {
        var resXRadius = xRadius * ctx.cameraColorBuffer.rtHandleProperties.rtHandleScale.x;
        var resYRadius = yRadius * ctx.cameraColorBuffer.rtHandleProperties.rtHandleScale.y;

        CustomPassUtils.VerticalGaussianBlur(ctx, ctx.cameraColorBuffer, temp, sampleCount, resYRadius);
        CustomPassUtils.HorizontalGaussianBlur(ctx, temp, ctx.cameraColorBuffer, sampleCount, resXRadius);
    }
예제 #9
0
    protected override void Execute(CustomPassContext ctx)
    {
        if (!render || ctx.hdCamera.camera == bakingCamera || bakingCamera == null || ctx.hdCamera.camera.cameraType == CameraType.SceneView)
        {
            return;
        }

        if (depthTexture == null && normalTexture == null && tangentTexture == null)
        {
            return;
        }



        // We need to be careful about the aspect ratio of render textures when doing the culling, otherwise it could result in objects poping:
        if (depthTexture != null)
        {
            bakingCamera.aspect = Mathf.Max(bakingCamera.aspect, depthTexture.width / (float)depthTexture.height);
        }
        if (normalTexture != null)
        {
            bakingCamera.aspect = Mathf.Max(bakingCamera.aspect, normalTexture.width / (float)normalTexture.height);
        }
        if (tangentTexture != null)
        {
            bakingCamera.aspect = Mathf.Max(bakingCamera.aspect, tangentTexture.width / (float)tangentTexture.height);
        }
        bakingCamera.TryGetCullingParameters(out var cullingParams);
        cullingParams.cullingOptions = CullingOptions.None;

        // Assign the custom culling result to the context
        // so it'll be used for the following operations
        ctx.cullingResults = ctx.renderContext.Cull(ref cullingParams);
        var overrideDepthTest = new RenderStateBlock(RenderStateMask.Depth)
        {
            depthState = new DepthState(true, CompareFunction.LessEqual)
        };

        // Depth
        if (depthTexture != null)
        {
            CustomPassUtils.RenderDepthFromCamera(ctx, bakingCamera, depthTexture, ClearFlag.Depth, bakingCamera.cullingMask, overrideRenderState: overrideDepthTest);
        }

        // Normal
        if (normalTexture != null)
        {
            CustomPassUtils.RenderNormalFromCamera(ctx, bakingCamera, normalTexture, ClearFlag.All, bakingCamera.cullingMask, overrideRenderState: overrideDepthTest);
        }

        // Tangent
        if (tangentTexture != null)
        {
            CustomPassUtils.RenderTangentFromCamera(ctx, bakingCamera, tangentTexture, ClearFlag.All, bakingCamera.cullingMask, overrideRenderState: overrideDepthTest);
        }
    }
예제 #10
0
    protected override void Execute(CustomPassContext ctx)
    {
        // This pass doesn't work with scene views
        if (ctx.hdCamera.camera.cameraType == CameraType.SceneView)
        {
            return;
        }

        CustomPassUtils.GaussianBlur(ctx, ctx.cameraColorBuffer, ctx.cameraColorBuffer, downSampleBuffer, radius: blurRadius);

        CoreUtils.SetRenderTarget(ctx.cmd, ctx.cameraColorBuffer, ctx.customDepthBuffer.Value, ClearFlag.DepthStencil, Color.clear);
        CustomPassUtils.DrawRenderers(ctx, uiLayer, RenderQueueType.Transparent, sorting: SortingCriteria.CommonOpaque);
    }
예제 #11
0
        protected override void Execute(CustomPassContext customPassContext)
        {
            if (targetLayer.value > 0)
            {
                CoreUtils.SetRenderTarget(customPassContext.cmd, rtBuffer);
                CustomPassUtils.DrawRenderers(customPassContext, targetLayer);
            }

            customPassContext.propertyBlock.SetTexture(BUFFER_TEXTURE, rtBuffer);
            ShaderProperty(customPassContext.propertyBlock);

            CoreUtils.SetRenderTarget(customPassContext.cmd, customPassContext.cameraColorBuffer);
            CoreUtils.DrawFullScreen(customPassContext.cmd, material, customPassContext.propertyBlock, shaderPassId: 0);
        }
예제 #12
0
    protected override void Execute(CustomPassContext ctx)
    {
        // Render meshes we want to outline in the outline buffer
        CoreUtils.SetRenderTarget(ctx.cmd, outlineBuffer, ClearFlag.Color);
        CustomPassUtils.DrawRenderers(ctx, outlineLayer);

        // Setup outline effect properties
        ctx.propertyBlock.SetColor("_OutlineColor", outlineColor);
        ctx.propertyBlock.SetTexture("_OutlineBuffer", outlineBuffer);
        ctx.propertyBlock.SetFloat("_Threshold", Mathf.Max(0.000001f, threshold * 0.01f));

        // Render the outline as a fullscreen alpha-blended pass on top of the camera color
        CoreUtils.DrawFullScreen(ctx.cmd, fullscreenOutline, ctx.cameraColorBuffer, shaderPassId: 0, properties: ctx.propertyBlock);
    }
예제 #13
0
    protected override void Execute(CustomPassContext ctx)
    {
        // Top right
        CustomPassUtils.Copy(
            ctx, ctx.cameraColorBuffer, ctx.customColorBuffer.Value,
            new Vector4(0.5f, 0.5f, 0.5f, 0.5f), new Vector4(0.5f, 0.5f, 0, 0),
            0, 0
            );
        CustomPassUtils.Copy(
            ctx, ctx.customColorBuffer.Value, ctx.cameraColorBuffer,
            new Vector4(0.5f, 0.5f, 0, 0), new Vector4(0.25f, 0.25f, 0.75f, 0.75f),
            0, 0
            );

        // Bottom left
        CustomPassUtils.Copy(
            ctx, ctx.cameraColorBuffer, halfResTarget,
            new Vector4(0.5f, 0.5f, 0.0f, 0.5f), new Vector4(0.5f, 0.5f, 0, 0),
            0, 0
            );
        CustomPassUtils.Copy(
            ctx, halfResTarget, ctx.cameraColorBuffer,
            new Vector4(0.5f, 0.5f, 0, 0), new Vector4(0.25f, 0.25f, 0.5f, 0.5f),
            0, 0
            );

        // Bottom right
        CustomPassUtils.Copy(
            ctx, ctx.cameraColorBuffer, ctx.customColorBuffer.Value,
            new Vector4(0.5f, 0.5f, 0.0f, 0.0f), new Vector4(0.5f, 0.5f, 0, 0),
            0, 0
            );
        CustomPassUtils.Copy(
            ctx, ctx.customColorBuffer.Value, ctx.cameraColorBuffer,
            new Vector4(0.5f, 0.5f, 0, 0), new Vector4(0.25f, 0.25f, 0.75f, 0.5f),
            0, 0
            );

        // top left
        CustomPassUtils.Copy(
            ctx, ctx.cameraColorBuffer, halfResTarget,
            new Vector4(0.5f, 0.5f, 0.5f, 0.0f), new Vector4(0.5f, 0.5f, 0, 0),
            0, 1
            );
        CustomPassUtils.Copy(
            ctx, halfResTarget, ctx.cameraColorBuffer,
            new Vector4(0.5f, 0.5f, 0, 0), new Vector4(0.25f, 0.25f, 0.5f, 0.75f),
            1, 0
            );
    }
예제 #14
0
    protected override void Execute(CustomPassContext ctx)
    {
        if (compositingMaterial == null)
        {
            Debug.LogError("Failed to load Liquid Pass Shaders");
            return;
        }

        CustomPassUtils.DrawRenderers(ctx, layerMask);

        // Blur the custom buffer:
        var resRadius = radius * ctx.cameraColorBuffer.rtHandleProperties.rtHandleScale.x;

        CustomPassUtils.GaussianBlur(ctx, ctx.customColorBuffer.Value, ctx.customColorBuffer.Value, blurBuffer, 25, resRadius);

        HandmadeFullscreenShaderGraphPass(ctx);
    }
예제 #15
0
    protected override void Execute(CustomPassContext ctx)
    {
        AllocateMaskBuffersIfNeeded();

        if (compositeMaterial != null && radius > 0)
        {
            if (useMask)
            {
                CoreUtils.SetRenderTarget(ctx.cmd, maskBuffer, maskDepthBuffer, ClearFlag.All);
                CustomPassUtils.DrawRenderers(ctx, maskLayer, overrideRenderState: new RenderStateBlock(RenderStateMask.Depth)
                {
                    depthState = new DepthState(true, CompareFunction.LessEqual)
                });
                // DrawMaskObjects(renderContext, cmd, hdCamera, cullingResult);
            }

            GenerateGaussianMips(ctx);
        }
    }
예제 #16
0
    protected override void Execute(CustomPassContext ctx)
    {
        if (!render || ctx.hdCamera.camera == bakingCamera || bakingCamera == null)
        {
            return;
        }

        bakingCamera.TryGetCullingParameters(out var cullingParams);

        cullingParams.cullingOptions = CullingOptions.ShadowCasters;

        // Assign the custom culling result to the context
        // so it'll be used for the following operations
        cullingResultField.SetValueDirect(__makeref(ctx), ctx.renderContext.Cull(ref cullingParams));

        // Depth
        if (depthTexture != null)
        {
            var overrideDepthTest = new RenderStateBlock(RenderStateMask.Depth)
            {
                depthState = new DepthState(true, CompareFunction.LessEqual)
            };
            CoreUtils.SetRenderTarget(ctx.cmd, depthTexture, ClearFlag.Depth);
            CustomPassUtils.RenderDepthFromCamera(ctx, bakingCamera, bakingCamera.cullingMask, overrideRenderState: overrideDepthTest);
        }

        // Normal
        if (normalTexture != null)
        {
            CoreUtils.SetRenderTarget(ctx.cmd, normalTexture, normalTexture.depthBuffer, ClearFlag.Depth);
            CustomPassUtils.RenderNormalFromCamera(ctx, bakingCamera, bakingCamera.cullingMask);
        }

        // Tangent
        if (tangentTexture != null)
        {
            CoreUtils.SetRenderTarget(ctx.cmd, tangentTexture, tangentTexture.depthBuffer, ClearFlag.Depth);
            CustomPassUtils.RenderTangentFromCamera(ctx, bakingCamera, bakingCamera.cullingMask);
        }
    }
예제 #17
0
    protected override void Execute(CustomPassContext ctx)
    {
        // This pass doesn't work with scene views
        if (ctx.hdCamera.camera.cameraType == CameraType.SceneView)
        {
            return;
        }

        CustomPassUtils.GaussianBlur(ctx, ctx.cameraColorBuffer, ctx.cameraColorBuffer, downSampleBuffer, radius: blurRadius);

        ShaderTagId[] litForwardTags = { HDShaderPassNames.s_ForwardOnlyName, HDShaderPassNames.s_ForwardName, HDShaderPassNames.s_SRPDefaultUnlitName };

        var result = new RendererListDesc(litForwardTags, ctx.cullingResults, ctx.hdCamera.camera)
        {
            rendererConfiguration      = PerObjectData.None,
            renderQueueRange           = RenderQueueRange.transparent,
            sortingCriteria            = SortingCriteria.CommonTransparent,
            excludeObjectMotionVectors = false,
            layerMask = uiLayer,
        };

        CoreUtils.DrawRendererList(ctx.renderContext, ctx.cmd, RendererList.Create(result));
    }
    protected override void Execute(CustomPassContext ctx)
    {
        CoreUtils.SetRenderTarget(ctx.cmd, temp, ClearFlag.Color);

        RenderStateBlock overrideDepth = new RenderStateBlock(RenderStateMask.Depth)
        {
            depthState = new DepthState(true, CompareFunction.LessEqual)
        };

        using (new CustomPassUtils.DisableSinglePassRendering(ctx))
        {
            using (new CustomPassUtils.OverrideCameraRendering(ctx, override1))
            {
                CustomPassUtils.DrawRenderers(ctx, overrideMask1a, overrideRenderState: overrideDepth);
                using (new CustomPassUtils.OverrideCameraRendering(ctx, override2))
                {
                    CustomPassUtils.DrawRenderers(ctx, overrideMask2);
                }
                CustomPassUtils.DrawRenderers(ctx, overrideMask1b);
            }
        }

        CustomPassUtils.Copy(ctx, temp, ctx.cameraColorBuffer, CustomPassUtils.fullScreenScaleBias, new Vector4(0.5f, 0.5f, 0.0f, 0.0f));
    }
예제 #19
0
    protected override void Execute(CustomPassContext ctx)
    {
        if (customCamera0 == null || customCamera1 == null || customCamera2 == null || customCamera3 == null || customCamera4 == null)
        {
            return;
        }

        // Render from camera 0
        // Internal API, can't be tested right now
        // using (new HDRenderPipeline.OverrideCameraRendering(ctx.cmd, customCamera0))
        // {
        //     CoreUtils.SetRenderTarget(ctx.cmd, temp, ClearFlag.Color);
        //     CustomPassUtils.DrawRenderers(ctx, -1);
        // }
        // CustomPassUtils.Copy(
        //     ctx, temp, ctx.cameraColorBuffer,
        //     CustomPassUtils.fullScreenScaleBias,
        //     new Vector4(.5f, .5f, 0f, 0f)
        // );

        RenderStateBlock overrideDepth = new RenderStateBlock(RenderStateMask.Depth)
        {
            depthState = new DepthState(true, CompareFunction.LessEqual)
        };

        // Render from camera 1
        CustomPassUtils.RenderFromCamera(ctx, customCamera1, temp, ctx.customDepthBuffer.Value, ClearFlag.All, -1, overrideRenderState: overrideDepth);
        CustomPassUtils.Copy(
            ctx, temp, ctx.cameraColorBuffer,
            CustomPassUtils.fullScreenScaleBias,
            new Vector4(.5f, .5f, .5f, 0f)
            );

        // Render from camera 4 (at same position than the test camera but uses a different FoV)
        // And with the camera depth buffer (which already contains opaque objects)
        CustomPassUtils.RenderFromCamera(ctx, customCamera4, ctx.cameraColorBuffer, ctx.cameraDepthBuffer, ClearFlag.None, customCamera4.cullingMask, overrideRenderState: overrideDepth);

        // Render from camera 3 using different buffers
        CustomPassUtils.RenderDepthFromCamera(ctx, customCamera3, temp, ctx.customDepthBuffer.Value, ClearFlag.All, -1);
        CustomPassUtils.Copy(
            ctx, temp, ctx.cameraColorBuffer,
            CustomPassUtils.fullScreenScaleBias,
            new Vector4(.25f, .25f, .5f, .5f)
            );

        CustomPassUtils.RenderNormalFromCamera(ctx, customCamera3, temp, ctx.customDepthBuffer.Value, ClearFlag.All, -1);
        CustomPassUtils.Copy(
            ctx, temp, ctx.cameraColorBuffer,
            CustomPassUtils.fullScreenScaleBias,
            new Vector4(.25f, .25f, .75f, .5f)
            );

        CustomPassUtils.RenderTangentFromCamera(ctx, customCamera3, temp, ctx.customDepthBuffer.Value, ClearFlag.All, -1);
        CustomPassUtils.Copy(
            ctx, temp, ctx.cameraColorBuffer,
            CustomPassUtils.fullScreenScaleBias,
            new Vector4(.25f, .25f, .5f, .75f)
            );

        // Render from camera 2 in an half res buffer
        CustomPassUtils.RenderFromCamera(ctx, customCamera2, halfResColor, halfResDepth, ClearFlag.All, -1, overrideRenderState: overrideDepth);
        CustomPassUtils.Copy(
            ctx, halfResColor, ctx.cameraColorBuffer,
            CustomPassUtils.fullScreenScaleBias,
            new Vector4(.25f, .25f, .75f, .75f)
            );
    }