void SetupPerFrameShaderConstants()
        {
            // When glossy reflections are OFF in the shader we set a constant color to use as indirect specular
            SphericalHarmonicsL2 ambientSH = RenderSettings.ambientProbe;
            Color linearGlossyEnvColor = new Color(ambientSH[0, 0], ambientSH[1, 0], ambientSH[2, 0]) * RenderSettings.reflectionIntensity;
            Color glossyEnvColor = CoreUtils.ConvertLinearToActiveColorSpace(linearGlossyEnvColor);
            Shader.SetGlobalVector(PerFrameBuffer._GlossyEnvironmentColor, glossyEnvColor);

            // Used when subtractive mode is selected
            Shader.SetGlobalVector(PerFrameBuffer._SubtractiveShadowColor, CoreUtils.ConvertSRGBToActiveColorSpace(RenderSettings.subtractiveShadowColor));
        }
        public void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorRT, RenderTargetIdentifier depthRT, Color backgroundColor, ClearFlag clearFlag = ClearFlag.None)
        {
            if (depthRT == BuiltinRenderTextureType.None || !m_DepthRenderBuffer)
            {
                SetRenderTarget(cmd, colorRT, backgroundColor, clearFlag);
                return;
            }

            int depthSlice = (m_IntermediateTextureArray) ? -1 : 0;

            CoreUtils.SetRenderTarget(cmd, colorRT, depthRT, clearFlag, CoreUtils.ConvertSRGBToActiveColorSpace(backgroundColor), 0, CubemapFace.Unknown, depthSlice);
        }
 /// <summary>
 /// Configure the pass before execution
 /// </summary>
 /// <param name="baseDescriptor">Current target descriptor</param>
 /// <param name="colorAttachmentHandle">Color attachment to render into</param>
 /// <param name="depthAttachmentHandle">Depth attachment to render into</param>
 /// <param name="clearFlag">Camera clear flag</param>
 /// <param name="clearColor">Camera clear color</param>
 /// <param name="configuration">Specific render configuration</param>
 public void Setup(
     RenderTextureDescriptor baseDescriptor,
     RenderTargetHandle colorAttachmentHandle,
     RenderTargetHandle depthAttachmentHandle,
     ClearFlag clearFlag,
     Color clearColor,
     RendererConfiguration configuration)
 {
     this.colorAttachmentHandle = colorAttachmentHandle;
     this.depthAttachmentHandle = depthAttachmentHandle;
     this.clearColor            = CoreUtils.ConvertSRGBToActiveColorSpace(clearColor);
     this.clearFlag             = clearFlag;
     descriptor = baseDescriptor;
     this.rendererConfiguration = configuration;
 }
Example #4
0
        public override void Execute(ScriptableRenderer renderer, ref ScriptableRenderContext context,
                                     ref CullResults cullResults,
                                     ref RenderingData renderingData)
        {
            CommandBuffer cmd = CommandBufferPool.Get(k_RenderOpaquesTag);

            using (new ProfilingSample(cmd, k_RenderOpaquesTag))
            {
                SetRenderTarget(cmd, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, clearFlag, CoreUtils.ConvertSRGBToActiveColorSpace(clearColor));

                // TODO: We need a proper way to handle multiple camera/ camera stack. Issue is: multiple cameras can share a same RT
                // (e.g, split screen games). However devs have to be dilligent with it and know when to clear/preserve color.
                // For now we make it consistent by resolving viewport with a RT until we can have a proper camera management system
                //if (colorAttachmentHandle == -1 && !cameraData.isDefaultViewport)
                //    cmd.SetViewport(camera.pixelRect);
                context.ExecuteCommandBuffer(cmd);
                cmd.Clear();

                Camera camera       = renderingData.cameraData.camera;
                var    drawSettings = CreateDrawRendererSettings(camera, SortFlags.CommonOpaque, rendererConfiguration, dynamicBatching);
                context.DrawRenderers(cullResults.visibleRenderers, ref drawSettings, opaqueFilterSettings);

                // Render objects that did not match any shader pass with error shader
                RenderObjectsWithError(renderer, ref context, ref cullResults, camera, opaqueFilterSettings, SortFlags.None);
            }
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
        public void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorRT, Color backgroundColor, ClearFlag clearFlag = ClearFlag.None)
        {
            int depthSlice = (m_IntermediateTextureArray) ? -1 : 0;

            CoreUtils.SetRenderTarget(cmd, colorRT, clearFlag, CoreUtils.ConvertSRGBToActiveColorSpace(backgroundColor), 0, CubemapFace.Unknown, depthSlice);
        }
Example #6
0
        internal void SetNativeRenderPassMRTAttachmentList(ScriptableRenderPass renderPass, ref CameraData cameraData, bool needCustomCameraColorClear, ClearFlag cameraClearFlag)
        {
            using (new ProfilingScope(null, Profiling.setMRTAttachmentsList))
            {
                int     currentPassIndex       = renderPass.renderPassQueueIndex;
                Hash128 currentPassHash        = m_PassIndexToPassHash[currentPassIndex];
                int[]   currentMergeablePasses = m_MergeableRenderPassesMap[currentPassHash];

                // Not the first pass
                if (currentMergeablePasses.First() != currentPassIndex)
                {
                    return;
                }

                m_RenderPassesAttachmentCount[currentPassHash] = 0;

                UpdateFinalStoreActions(currentMergeablePasses, cameraData);

                int  currentAttachmentIdx = 0;
                bool hasInput             = false;
                foreach (var passIdx in currentMergeablePasses)
                {
                    if (passIdx == -1)
                    {
                        break;
                    }
                    ScriptableRenderPass pass = m_ActiveRenderPassQueue[passIdx];

                    for (int i = 0; i < pass.m_ColorAttachmentIndices.Length; ++i)
                    {
                        pass.m_ColorAttachmentIndices[i] = -1;
                    }

                    for (int i = 0; i < pass.m_InputAttachmentIndices.Length; ++i)
                    {
                        pass.m_InputAttachmentIndices[i] = -1;
                    }

                    uint validColorBuffersCount = RenderingUtils.GetValidColorBufferCount(pass.colorAttachmentHandles);

                    for (int i = 0; i < validColorBuffersCount; ++i)
                    {
                        AttachmentDescriptor currentAttachmentDescriptor =
                            new AttachmentDescriptor(pass.renderTargetFormat[i] != GraphicsFormat.None ? pass.renderTargetFormat[i] : GetDefaultGraphicsFormat(cameraData));

                        var colorHandle = pass.overrideCameraTarget ? pass.colorAttachmentHandles[i] : m_CameraColorTarget.handle;

                        int existingAttachmentIndex = FindAttachmentDescriptorIndexInList(colorHandle.nameID, m_ActiveColorAttachmentDescriptors);

                        if (m_UseOptimizedStoreActions)
                        {
                            currentAttachmentDescriptor.storeAction = m_FinalColorStoreAction[i];
                        }

                        if (existingAttachmentIndex == -1)
                        {
                            // add a new attachment
                            m_ActiveColorAttachmentDescriptors[currentAttachmentIdx] = currentAttachmentDescriptor;
                            bool passHasClearColor = (pass.clearFlag & ClearFlag.Color) != 0;
                            m_ActiveColorAttachmentDescriptors[currentAttachmentIdx].ConfigureTarget(colorHandle.nameID, !passHasClearColor, true);

                            if (pass.colorAttachmentHandles[i] == m_CameraColorTarget.handle && needCustomCameraColorClear && (cameraClearFlag & ClearFlag.Color) != 0)
                            {
                                m_ActiveColorAttachmentDescriptors[currentAttachmentIdx].ConfigureClear(cameraData.backgroundColor, 1.0f, 0);
                            }
                            else if (passHasClearColor)
                            {
                                m_ActiveColorAttachmentDescriptors[currentAttachmentIdx].ConfigureClear(CoreUtils.ConvertSRGBToActiveColorSpace(pass.clearColor), 1.0f, 0);
                            }

                            pass.m_ColorAttachmentIndices[i] = currentAttachmentIdx;
                            currentAttachmentIdx++;
                            m_RenderPassesAttachmentCount[currentPassHash]++;
                        }
                        else
                        {
                            // attachment was already present
                            pass.m_ColorAttachmentIndices[i] = existingAttachmentIndex;
                        }
                    }

                    if (PassHasInputAttachments(pass))
                    {
                        hasInput = true;
                        SetupInputAttachmentIndices(pass);
                    }

                    // TODO: this is redundant and is being setup for each attachment. Needs to be done only once per mergeable pass list (we need to make sure mergeable passes use the same depth!)
                    m_ActiveDepthAttachmentDescriptor = new AttachmentDescriptor(SystemInfo.GetGraphicsFormat(DefaultFormat.DepthStencil));
                    bool passHasClearDepth = (cameraClearFlag & ClearFlag.DepthStencil) != 0;
                    m_ActiveDepthAttachmentDescriptor.ConfigureTarget(pass.overrideCameraTarget ? pass.depthAttachmentHandle.nameID : m_CameraDepthTarget.nameID, !passHasClearDepth, true);

                    if (passHasClearDepth)
                    {
                        m_ActiveDepthAttachmentDescriptor.ConfigureClear(Color.black, 1.0f, 0);
                    }

                    if (m_UseOptimizedStoreActions)
                    {
                        m_ActiveDepthAttachmentDescriptor.storeAction = m_FinalDepthStoreAction;
                    }
                }

                if (hasInput)
                {
                    SetupTransientInputAttachments(m_RenderPassesAttachmentCount[currentPassHash]);
                }
            }
        }
Example #7
0
        public override void Execute(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
                                     ref CullResults cullResults,
                                     ref RenderingData renderingData)
        {
            CommandBuffer cmd = CommandBufferPool.Get(k_RenderTransparentsTag);

            using (new ProfilingSample(cmd, k_RenderTransparentsTag))
            {
                SetRenderTarget(cmd, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store, clearFlag, CoreUtils.ConvertSRGBToActiveColorSpace(clearColor));
                context.ExecuteCommandBuffer(cmd);
                cmd.Clear();

                Camera camera       = renderingData.cameraData.camera;
                var    drawSettings = CreateDrawRendererSettings(camera, SortFlags.CommonTransparent, rendererConfiguration, dynamicBatching);
                context.DrawRenderers(cullResults.visibleRenderers, ref drawSettings, transparentFilterSettings);

                // Render objects that did not match any shader pass with error shader
                RenderObjectsWithError(renderer, ref context, ref cullResults, camera, transparentFilterSettings, SortFlags.None);
            }

            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
        internal void SetNativeRenderPassMRTAttachmentList(ScriptableRenderPass renderPass, ref CameraData cameraData, uint validColorBuffersCount, bool needCustomCameraColorClear, ClearFlag clearFlag)
        {
            using (new ProfilingScope(null, Profiling.setMRTAttachmentsList))
            {
                int     currentPassIndex       = renderPass.renderPassQueueIndex;
                Hash128 currentPassHash        = m_PassIndexToPassHash[currentPassIndex];
                int[]   currentMergeablePasses = m_MergeableRenderPassesMap[currentPassHash];

                // Not the first pass
                if (currentMergeablePasses.First() != currentPassIndex)
                {
                    return;
                }

                m_RenderPassesAttachmentCount[currentPassHash] = 0;

                int currentAttachmentIdx = 0;
                foreach (var passIdx in currentMergeablePasses)
                {
                    if (passIdx == -1)
                    {
                        break;
                    }
                    ScriptableRenderPass pass = m_ActiveRenderPassQueue[passIdx];

                    for (int i = 0; i < pass.m_InputAttachmentIndices.Length; ++i)
                    {
                        pass.m_InputAttachmentIndices[i] = -1;
                    }

                    // TODO: review the lastPassToBB logic to mak it work with merged passes
                    bool isLastPassToBB = false;

                    for (int i = 0; i < validColorBuffersCount; ++i)
                    {
                        AttachmentDescriptor currentAttachmentDescriptor =
                            new AttachmentDescriptor(pass.renderTargetFormat[i] != GraphicsFormat.None ? pass.renderTargetFormat[i] : GetDefaultGraphicsFormat(cameraData));

                        // if this is the current camera's last pass, also check if one of the RTs is the backbuffer (BuiltinRenderTextureType.CameraTarget)
                        isLastPassToBB |= pass.isLastPass && (pass.colorAttachments[i] == BuiltinRenderTextureType.CameraTarget);

                        int existingAttachmentIndex = FindAttachmentDescriptorIndexInList(currentAttachmentIdx,
                                                                                          currentAttachmentDescriptor, m_ActiveColorAttachmentDescriptors);

                        if (existingAttachmentIndex == -1)
                        {
                            // add a new attachment
                            m_ActiveColorAttachmentDescriptors[currentAttachmentIdx] = currentAttachmentDescriptor;

                            m_ActiveColorAttachmentDescriptors[currentAttachmentIdx].ConfigureTarget(pass.colorAttachments[i], (clearFlag & ClearFlag.Color) == 0, true);

                            if ((clearFlag & ClearFlag.Color) != 0)
                            {
                                var clearColor = (needCustomCameraColorClear && pass.colorAttachments[i] == m_CameraColorTarget) ? cameraData.camera.backgroundColor : renderPass.clearColor;
                                m_ActiveColorAttachmentDescriptors[currentAttachmentIdx].ConfigureClear(CoreUtils.ConvertSRGBToActiveColorSpace(clearColor), 1.0f, 0);
                            }

                            pass.m_InputAttachmentIndices[i] = currentAttachmentIdx;

                            currentAttachmentIdx++;
                            m_RenderPassesAttachmentCount[currentPassHash]++;
                        }
                        else
                        {
                            // attachment was already present
                            pass.m_InputAttachmentIndices[i] = existingAttachmentIndex;
                        }
                    }

                    // TODO: this is redundant and is being setup for each attachment. Needs to be done only once per mergeable pass list (we need to make sure mergeable passes use the same depth!)
                    m_ActiveDepthAttachmentDescriptor = new AttachmentDescriptor(GraphicsFormat.DepthAuto);
                    m_ActiveDepthAttachmentDescriptor.ConfigureTarget(pass.depthAttachment, (clearFlag & ClearFlag.DepthStencil) == 0, !isLastPassToBB);
                    if ((clearFlag & ClearFlag.DepthStencil) != 0)
                    {
                        m_ActiveDepthAttachmentDescriptor.ConfigureClear(Color.black, 1.0f, 0);
                    }
                }
            }
        }
Example #9
0
        void RenderOpaques(ref ScriptableRenderContext context, ref CullResults cullResults, ref CameraData cameraData, RendererConfiguration rendererConfiguration, bool dynamicBatching)
        {
            CommandBuffer cmd = CommandBufferPool.Get(k_RenderOpaquesTag);

            using (new ProfilingSample(cmd, k_SetupRenderTargetTag))
            {
                Camera    camera    = cameraData.camera;
                ClearFlag clearFlag = GetCameraClearFlag(camera);
                SetRenderTarget(cmd, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, clearFlag, CoreUtils.ConvertSRGBToActiveColorSpace(camera.backgroundColor));

                // If rendering to an intermediate RT we resolve viewport on blit due to offset not being supported
                // while rendering to a RT.
                if (colorAttachmentHandle == -1 && cameraData.isDefaultViewport)
                {
                    cmd.SetViewport(camera.pixelRect);
                }

                context.ExecuteCommandBuffer(cmd);
                cmd.Clear();

                var drawSettings = CreateDrawRendererSettings(camera, SortFlags.CommonOpaque, rendererConfiguration, dynamicBatching);
                context.DrawRenderers(cullResults.visibleRenderers, ref drawSettings, renderer.opaqueFilterSettings);

                // Render objects that did not match any shader pass with error shader
                RenderObjectsWithError(ref context, ref cullResults, camera, renderer.opaqueFilterSettings, SortFlags.None);

                if (camera.clearFlags == CameraClearFlags.Skybox)
                {
                    context.DrawSkybox(camera);
                }
            }
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
        private bool RenderShadows(ref CullResults cullResults, ref VisibleLight shadowLight, int shadowLightIndex, ref ScriptableRenderContext context, Color backgroundColor)
        {
            m_ShadowCasterCascadesCount = m_ShadowSettings.directionalLightCascadeCount;

            if (shadowLight.lightType == UnityEngine.LightType.Spot)
            {
                m_ShadowCasterCascadesCount = 1;
            }

            int shadowResolution = GetMaxTileResolutionInAtlas(m_ShadowSettings.shadowAtlasWidth, m_ShadowSettings.shadowAtlasHeight, m_ShadowCasterCascadesCount);

            Bounds bounds;

            if (!cullResults.GetShadowCasterBounds(shadowLightIndex, out bounds))
            {
                return(false);
            }

            float shadowNearPlane = m_Asset.ShadowNearOffset;

            Matrix4x4 view, proj;
            var       settings = new DrawShadowsSettings(cullResults, shadowLightIndex);
            bool      success  = false;

            var cmd = CommandBufferPool.Get("Prepare Shadowmap");
            RenderTextureDescriptor shadowmapDescriptor = new RenderTextureDescriptor(m_ShadowSettings.shadowAtlasWidth,
                                                                                      m_ShadowSettings.shadowAtlasHeight, m_ShadowSettings.shadowmapTextureFormat, kShadowBufferBits);

            shadowmapDescriptor.shadowSamplingMode = ShadowSamplingMode.CompareDepths;
            m_ShadowMapRT            = RenderTexture.GetTemporary(shadowmapDescriptor);
            m_ShadowMapRT.filterMode = FilterMode.Bilinear;
            m_ShadowMapRT.wrapMode   = TextureWrapMode.Clamp;

            // LightweightPipeline.SetRenderTarget is meant to be used with camera targets, not shadowmaps
            CoreUtils.SetRenderTarget(cmd, m_ShadowMapRT, ClearFlag.Depth, CoreUtils.ConvertSRGBToActiveColorSpace(backgroundColor));

            if (shadowLight.lightType == UnityEngine.LightType.Spot)
            {
                success = cullResults.ComputeSpotShadowMatricesAndCullingPrimitives(shadowLightIndex, out view, out proj,
                                                                                    out settings.splitData);

                if (success)
                {
                    SetupShadowCasterConstants(cmd, ref shadowLight, proj, shadowResolution);
                    SetupShadowSliceTransform(0, shadowResolution, proj, view);
                    RenderShadowSlice(cmd, ref context, 0, proj, view, settings);
                }
            }
            else if (shadowLight.lightType == UnityEngine.LightType.Directional)
            {
                for (int cascadeIdx = 0; cascadeIdx < m_ShadowCasterCascadesCount; ++cascadeIdx)
                {
                    success = cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(shadowLightIndex,
                                                                                               cascadeIdx, m_ShadowCasterCascadesCount, m_ShadowSettings.directionalLightCascades, shadowResolution, shadowNearPlane, out view, out proj,
                                                                                               out settings.splitData);

                    float cullingSphereRadius = settings.splitData.cullingSphere.w;
                    m_DirectionalShadowSplitDistances[cascadeIdx] = settings.splitData.cullingSphere;
                    m_DirectionalShadowSplitRadii[cascadeIdx]     = cullingSphereRadius * cullingSphereRadius;

                    if (!success)
                    {
                        break;
                    }

                    SetupShadowCasterConstants(cmd, ref shadowLight, proj, shadowResolution);
                    SetupShadowSliceTransform(cascadeIdx, shadowResolution, proj, view);
                    RenderShadowSlice(cmd, ref context, cascadeIdx, proj, view, settings);
                }
            }
            else
            {
                Debug.LogWarning("Only spot and directional shadow casters are supported in lightweight pipeline");
            }

            if (success)
            {
                SetupShadowReceiverConstants(cmd, shadowLight, ref context);
            }

            CommandBufferPool.Release(cmd);
            return(success);
        }