Ejemplo n.º 1
0
 // --------------------------------------------------------------------
 void ReleaseOcclusionTextures()
 {
     m_textureHandlingBuffer.ReleaseTemporaryRT(m_directLightOcclusionMapId);
     m_textureHandlingBuffer.ReleaseTemporaryRT(m_directLightShadowMapId);
     m_textureHandlingBuffer.ReleaseTemporaryRT(m_directLightDummyTextureId);
     m_textureHandlingBuffer.ReleaseTemporaryRT(m_directLightDepthTextureId);
     L2DLRenderHelpers.ExecuteBuffer(m_context, m_textureHandlingBuffer);
 }
Ejemplo n.º 2
0
    // --------------------------------------------------------------------
    public void Render(ScriptableRenderContext context, Camera camera, L2DLDirectLights directLights)
    {
        if (!m_directLightData.Enabled)
        {
            return;
        }

        m_context = context;
        m_camera  = camera;

        // Encapsulate in frame debugger
        L2DLRenderHelpers.BeginSample(m_context, m_directLightRenderingBuffer);
        {
            CoreUtils.SetRenderTarget(m_clearBuffer, L2DLPipelineData.s_cameraDirectLightResultTextureId, L2DLPipelineData.s_cameraDepthTextureId, ClearFlag.Color);
            L2DLRenderHelpers.ExecuteBuffer(m_context, m_clearBuffer);

            // Directional Lights
            L2DLRenderHelpers.BeginSample(m_context, m_directionalLightsBuffer);
            foreach (L2DLDirectionalLight directionalLight in directLights.m_directionalLights)
            {
                GetOcclusionTextures((int)directionalLight.ShadowMapSize); // Probably don't need to do this every time?
                RenderOcclusionMapForLight(directionalLight);
                RunDirectionalLightOcclusionMapTrace(directionalLight);
                RunDirectionalLightRendering(directionalLight);
                ReleaseOcclusionTextures();
            }
            L2DLRenderHelpers.EndSample(m_context, m_directionalLightsBuffer);

            // Point Lights
            L2DLRenderHelpers.BeginSample(m_context, m_pointLightsBuffer);
            foreach (L2DLPointLight pointLight in directLights.m_pointLights)
            {
                GetOcclusionTextures((int)pointLight.ShadowMapSize);
                RenderOcclusionMapForLight(pointLight);
                RunPointLightOcclusionMapTrace(pointLight);
                RunPointLightRendering(pointLight);
                ReleaseOcclusionTextures();
            }
            L2DLRenderHelpers.EndSample(m_context, m_pointLightsBuffer);

            // Spot Lights
            L2DLRenderHelpers.BeginSample(m_context, m_spotLightsBuffer);
            foreach (L2DLSpotLight spotLight in directLights.m_spotLights)
            {
                GetOcclusionTextures((int)spotLight.ShadowMapSize);
                RenderOcclusionMapForLight(spotLight);
                RunSpotLightOcclusionMapTrace(spotLight);
                RunSpotLightRendering(spotLight);
                ReleaseOcclusionTextures();
            }
            L2DLRenderHelpers.EndSample(m_context, m_spotLightsBuffer);

            // Reset
            m_context.SetupCameraProperties(m_camera);
        }
        L2DLRenderHelpers.EndSample(m_context, m_directLightRenderingBuffer);
    }
Ejemplo n.º 3
0
 public void CalculateShadowMap(ScriptableRenderContext _context, CommandBuffer _buffer, L2DLDirectionalLight _directionalLight, L2DLDirectLightData _data, RenderTargetIdentifier i_occlusionMap, RenderTargetIdentifier o_shadowMap)
 {
     // Here we run the code that calculates the shadow map using standard rendering...
     _buffer.SetGlobalTexture("_OcclusionMap", i_occlusionMap);
     _buffer.SetGlobalInt("_SamplesPerPixel", m_samplesPerPixel);
     _buffer.SetGlobalFloat("_WorldDistPerStep", _directionalLight.Height / m_samplesPerPixel);
     _buffer.Blit(i_occlusionMap, o_shadowMap, DirectionalShadowMapRenderMaterial);
     L2DLRenderHelpers.ExecuteBuffer(_context, _buffer);
 }
Ejemplo n.º 4
0
    // --------------------------------------------------------------------
    void RunDirectionalLightRendering(L2DLDirectionalLight directionalLight)
    {
        SetupCommonLightRenderingProperties(m_directionalLightRenderingBuffer, directionalLight);

        m_directionalLightRenderingBuffer.SetRenderTarget(new RenderTargetIdentifier[] { L2DLPipelineData.s_cameraDirectLightResultTextureId, L2DLPipelineData.s_cameraEmissionTextureId }, L2DLPipelineData.s_cameraFakeDepthTextureId);
        m_directionalLightRenderingBuffer.Blit(null, BuiltinRenderTextureType.CurrentActive, DirectionalLightPassMaterial);

        L2DLRenderHelpers.ExecuteBuffer(m_context, m_directionalLightRenderingBuffer);
    }
Ejemplo n.º 5
0
 // --------------------------------------------------------------------
 void ReleaseTextures()
 {
     m_textureHandlerBuffer.ReleaseTemporaryRT(L2DLPipelineData.s_cameraColorTextureId);
     m_textureHandlerBuffer.ReleaseTemporaryRT(L2DLPipelineData.s_cameraEmissionTextureId);
     m_textureHandlerBuffer.ReleaseTemporaryRT(L2DLPipelineData.s_cameraOcclusionTextureId);
     m_textureHandlerBuffer.ReleaseTemporaryRT(L2DLPipelineData.s_cameraAdditionalDataTextureId);
     m_textureHandlerBuffer.ReleaseTemporaryRT(L2DLPipelineData.s_cameraDepthTextureId);
     m_textureHandlerBuffer.ReleaseTemporaryRT(L2DLPipelineData.s_cameraFakeDepthTextureId);
     m_textureHandlerBuffer.ReleaseTemporaryRT(L2DLPipelineData.s_cameraDirectLightResultTextureId);
     m_textureHandlerBuffer.ReleaseTemporaryRT(L2DLPipelineData.s_cameraIndirectLightResultTextureId);
     L2DLRenderHelpers.ExecuteBuffer(m_context, m_textureHandlerBuffer);
 }
Ejemplo n.º 6
0
    // --------------------------------------------------------------------
    void RunPointLightRendering(L2DLPointLight pointLight)
    {
        SetupCommonLightRenderingProperties(m_pointLightRenderingBuffer, pointLight);
        m_pointLightRenderingBuffer.SetGlobalFloat("_lightAttenuation", 1f / Mathf.Max(pointLight.Range * pointLight.Range, 0.00001f));
        m_pointLightRenderingBuffer.SetGlobalVector("_lightPosition", pointLight.transform.position);

        m_pointLightRenderingBuffer.SetGlobalFloat("_maxIntensityOutput", pointLight.MaxIntensityOutput);

        m_pointLightRenderingBuffer.SetRenderTarget(new RenderTargetIdentifier[] { L2DLPipelineData.s_cameraDirectLightResultTextureId, L2DLPipelineData.s_cameraEmissionTextureId }, L2DLPipelineData.s_cameraFakeDepthTextureId);
        m_pointLightRenderingBuffer.Blit(null, BuiltinRenderTextureType.CurrentActive, PointLightPassMaterial);

        L2DLRenderHelpers.ExecuteBuffer(m_context, m_pointLightRenderingBuffer);
    }
Ejemplo n.º 7
0
    // Textures
    // --------------------------------------------------------------------
    void GetOcclusionTextures(int _size)
    {
        RenderTextureDescriptor mapDescriptor = new RenderTextureDescriptor(_size, _size, RenderTextureFormat.ARGBHalf)
        {
            useMipMap         = m_directLightData.ShadowMapCalculator.OcclusionMapGenerateMips,
            autoGenerateMips  = m_directLightData.ShadowMapCalculator.OcclusionMapGenerateMips,
            enableRandomWrite = m_directLightData.ShadowMapCalculator.OcclusionMapRandomAccess,
        };

        m_textureHandlingBuffer.GetTemporaryRT(m_directLightOcclusionMapId, mapDescriptor, m_directLightData.ShadowMapCalculator.OcclusionMapFilterMode);
        m_textureHandlingBuffer.GetTemporaryRT(m_directLightShadowMapId, mapDescriptor, m_directLightData.ShadowMapCalculator.OcclusionMapFilterMode);
        m_textureHandlingBuffer.GetTemporaryRT(m_directLightDummyTextureId, _size, _size, 0, FilterMode.Bilinear, RenderTextureFormat.ARGBHalf);
        m_textureHandlingBuffer.GetTemporaryRT(m_directLightDepthTextureId, _size, _size, 0, FilterMode.Bilinear, RenderTextureFormat.ARGBHalf);
        L2DLRenderHelpers.ExecuteBuffer(m_context, m_textureHandlingBuffer);
    }
Ejemplo n.º 8
0
    // --------------------------------------------------------------------
    public void CalculateShadowMap(ScriptableRenderContext _context, CommandBuffer _buffer, L2DLSpotLight _spotLight, L2DLDirectLightData _data, RenderTargetIdentifier i_occlusionMap, RenderTargetIdentifier o_shadowMap)
    {
        if (!L2DLRenderHelpers.SupportsComputeShaders())
        {
            return;
        }

        ReloadComputeShaders();

        int occlusionTraceComputeKernel = m_spotLightOcclusionTraceCompute.FindKernel("SpotLightOcclusionTrace");

        SetupCommonComputeShaderProperties(_buffer, m_spotLightOcclusionTraceCompute, occlusionTraceComputeKernel, _spotLight, _data);
        _buffer.SetComputeFloatParam(m_spotLightOcclusionTraceCompute, "_WorldDistPerStep", _spotLight.Range / (int)_spotLight.ShadowMapSize);
        _buffer.DispatchCompute(m_spotLightOcclusionTraceCompute, occlusionTraceComputeKernel, (int)_spotLight.ShadowMapSize / 64, 1, 1);
        L2DLRenderHelpers.ExecuteBuffer(_context, _buffer);
    }
Ejemplo n.º 9
0
    // --------------------------------------------------------------------
    void RenderOcclusionMapForLight(IL2DLDirectLight directLight)
    {
        L2DLRenderHelpers.BeginSample(m_context, m_occlusionMapRenderingBuffer);
        {
            m_context.SetupCameraProperties(directLight.ShadowCamera);

            if (!directLight.ShadowCamera.TryGetCullingParameters(out m_cullingParameters))
            {
                return;
            }
            m_cullingResults = m_context.Cull(ref m_cullingParameters);

            CoreUtils.SetRenderTarget(m_clearBuffer, new RenderTargetIdentifier[] { m_directLightDummyTextureId, m_directLightOcclusionMapId }, m_directLightDepthTextureId, ClearFlag.All);
            L2DLRenderHelpers.ExecuteBuffer(m_context, m_clearBuffer);

            L2DLRenderHelpers.DrawAllRenderers(m_context, m_cullingResults);
        }
        L2DLRenderHelpers.EndSample(m_context, m_occlusionMapRenderingBuffer);
    }
Ejemplo n.º 10
0
    // --------------------------------------------------------------------
    void RenderStep_PresentFinalImage()
    {
        // Push the RT we've written on to the camera target
        switch (TextureToView)
        {
        case L2DLBufferTextures.None:
            m_presentFinalImageBuffer.SetGlobalTexture("_Color", L2DLPipelineData.s_cameraColorTextureId);
            m_presentFinalImageBuffer.SetGlobalTexture("_DirectLight", L2DLPipelineData.s_cameraDirectLightResultTextureId);
            m_presentFinalImageBuffer.SetGlobalTexture("_IndirectLight", L2DLPipelineData.s_cameraIndirectLightResultTextureId);
            List <LPVIterationData> iterationData = m_indirectLightData.IndirectLightCalculator.LPVIterationData;
            m_presentFinalImageBuffer.SetGlobalInt("_IndirectLightMip", iterationData[iterationData.Count - 1].MipLevel);
            m_presentFinalImageBuffer.Blit(null, BuiltinRenderTextureType.CameraTarget, L2DLPipelineData.CombineMaterial);
            break;

        case L2DLBufferTextures.Colour:
            m_presentFinalImageBuffer.SetGlobalTexture("_MainTex", L2DLPipelineData.s_cameraColorTextureId);
            m_presentFinalImageBuffer.Blit(L2DLPipelineData.s_cameraColorTextureId, BuiltinRenderTextureType.CameraTarget, L2DLPipelineData.BlitMaterial);
            break;

        case L2DLBufferTextures.Emission:
            m_presentFinalImageBuffer.SetGlobalTexture("_MainTex", L2DLPipelineData.s_cameraEmissionTextureId);
            m_presentFinalImageBuffer.Blit(L2DLPipelineData.s_cameraEmissionTextureId, BuiltinRenderTextureType.CameraTarget, L2DLPipelineData.BlitMaterial);
            break;

        case L2DLBufferTextures.Occlusion:
            m_presentFinalImageBuffer.SetGlobalTexture("_MainTex", L2DLPipelineData.s_cameraOcclusionTextureId);
            m_presentFinalImageBuffer.Blit(L2DLPipelineData.s_cameraOcclusionTextureId, BuiltinRenderTextureType.CameraTarget, L2DLPipelineData.BlitMaterial);
            break;

        case L2DLBufferTextures.AdditionalData:
            m_presentFinalImageBuffer.SetGlobalTexture("_MainTex", L2DLPipelineData.s_cameraAdditionalDataTextureId);
            m_presentFinalImageBuffer.Blit(L2DLPipelineData.s_cameraAdditionalDataTextureId, BuiltinRenderTextureType.CameraTarget, L2DLPipelineData.BlitMaterial);
            break;

        case L2DLBufferTextures.Depth:
            m_presentFinalImageBuffer.SetGlobalTexture("_MainTex", L2DLPipelineData.s_cameraDepthTextureId);
            m_presentFinalImageBuffer.Blit(L2DLPipelineData.s_cameraDepthTextureId, BuiltinRenderTextureType.CameraTarget, L2DLPipelineData.BlitMaterial);
            break;
        }

        L2DLRenderHelpers.ExecuteBuffer(m_context, m_presentFinalImageBuffer);
    }
Ejemplo n.º 11
0
    // --------------------------------------------------------------------
    public void Render(ScriptableRenderContext context, Camera camera)
    {
        if (!m_indirectLightData.Enabled)
        {
            return;
        }

        m_context = context;
        m_camera  = camera;

        // Encapsulate in frame debugger
        L2DLRenderHelpers.BeginSample(m_context, m_indirectLightRenderingBuffer);
        {
            m_indirectLightData.IndirectLightCalculator?.CalculateIndirectLight(
                m_context,
                m_indirectLightRenderingBuffer,
                m_camera,
                L2DLPipelineData.s_cameraEmissionTextureId,
                L2DLPipelineData.s_cameraOcclusionTextureId,
                L2DLPipelineData.s_cameraIndirectLightResultTextureId);
        }
        L2DLRenderHelpers.EndSample(m_context, m_indirectLightRenderingBuffer);
    }
Ejemplo n.º 12
0
    // Textures need to be gotten at the start of the cameras rendering and held on to until the end so that all steps can access them
    // --------------------------------------------------------------------
    void GetTextures()
    {
        RenderTextureDescriptor bufferTextureDescriptor = new RenderTextureDescriptor(m_camera.pixelWidth, m_camera.pixelHeight, RenderTextureFormat.ARGBHalf, 0)
        {
            enableRandomWrite = true,
            useMipMap         = true,
            autoGenerateMips  = false,
        };

        RenderTextureDescriptor bufferDepthTextureDescriptor = new RenderTextureDescriptor(m_camera.pixelWidth, m_camera.pixelHeight, RenderTextureFormat.Depth, 16);

        m_textureHandlerBuffer.GetTemporaryRT(L2DLPipelineData.s_cameraColorTextureId, bufferTextureDescriptor, FilterMode.Point);
        m_textureHandlerBuffer.GetTemporaryRT(L2DLPipelineData.s_cameraEmissionTextureId, bufferTextureDescriptor, FilterMode.Point);
        m_textureHandlerBuffer.GetTemporaryRT(L2DLPipelineData.s_cameraOcclusionTextureId, bufferTextureDescriptor, FilterMode.Point);
        m_textureHandlerBuffer.GetTemporaryRT(L2DLPipelineData.s_cameraAdditionalDataTextureId, bufferTextureDescriptor, FilterMode.Point);
        m_textureHandlerBuffer.GetTemporaryRT(L2DLPipelineData.s_cameraDirectLightResultTextureId, bufferTextureDescriptor, FilterMode.Bilinear);
        m_textureHandlerBuffer.GetTemporaryRT(L2DLPipelineData.s_cameraIndirectLightResultTextureId, bufferTextureDescriptor, FilterMode.Bilinear);

        m_textureHandlerBuffer.GetTemporaryRT(L2DLPipelineData.s_cameraDepthTextureId, bufferDepthTextureDescriptor, FilterMode.Point);
        m_textureHandlerBuffer.GetTemporaryRT(L2DLPipelineData.s_cameraFakeDepthTextureId, bufferDepthTextureDescriptor, FilterMode.Point);

        L2DLRenderHelpers.ExecuteBuffer(m_context, m_textureHandlerBuffer);
    }
Ejemplo n.º 13
0
    // --------------------------------------------------------------------
    void RunSpotLightRendering(L2DLSpotLight spotLight)
    {
        SetupCommonLightRenderingProperties(m_spotLightRenderingBuffer, spotLight);
        m_spotLightRenderingBuffer.SetGlobalFloat("_lightAttenuation", 1f / Mathf.Max(spotLight.Range * spotLight.Range, 0.00001f));
        m_spotLightRenderingBuffer.SetGlobalVector("_lightPosition", spotLight.transform.position + spotLight.transform.up * spotLight.Range / 2f);
        m_spotLightRenderingBuffer.SetGlobalVector("_lightDirection", -spotLight.transform.up);

        float outerRad   = Mathf.Deg2Rad * 0.5f * spotLight.Angle;
        float outerCos   = Mathf.Cos(outerRad);
        float outerTan   = Mathf.Tan(outerRad);
        float innerCos   = Mathf.Cos(Mathf.Atan((46f / 64f) * outerTan));
        float angleRange = Mathf.Max(innerCos - outerCos, 0.00001f);
        float spotFade   = 1f / angleRange;

        m_spotLightRenderingBuffer.SetGlobalVector("_lightFade", new Vector2(spotFade, -outerCos * spotFade));

        m_spotLightRenderingBuffer.SetGlobalFloat("_maxIntensityOutput", spotLight.MaxIntensityOutput);
        m_spotLightRenderingBuffer.SetGlobalFloat("_startingRange", spotLight.StartingRange);

        m_spotLightRenderingBuffer.SetRenderTarget(new RenderTargetIdentifier[] { L2DLPipelineData.s_cameraDirectLightResultTextureId, L2DLPipelineData.s_cameraEmissionTextureId }, L2DLPipelineData.s_cameraFakeDepthTextureId);
        m_spotLightRenderingBuffer.Blit(null, BuiltinRenderTextureType.CurrentActive, SpotLightPassMaterial);
        L2DLRenderHelpers.ExecuteBuffer(m_context, m_spotLightRenderingBuffer);
    }
    // --------------------------------------------------------------------
    public void CalculateIndirectLight(
        ScriptableRenderContext _context,
        CommandBuffer _buffer,
        Camera _camera,
        RenderTargetIdentifier i_emissiveTexture,
        RenderTargetIdentifier i_occlusionTexture,
        RenderTargetIdentifier o_indirectLightTexture
        )
    {
        if (!L2DLRenderHelpers.SupportsComputeShaders())
        {
            return;
        }

        ReloadComputeShaders();

        // We'll assume that the emissive texture is all we care about, any reflected direct light can be added in beforehand as part of the general IndirectLight renderer
        if (m_emissionPolyphaseMipmapComputeShader == null)
        {
            m_emissionPolyphaseMipmapComputeShader = (ComputeShader)Resources.Load("Compute Shaders/Indirect Light/Polyphase Mipmap/GenerateEmissionPolyphaseMipmapsCompute");
        }
        if (m_occlusionPolyphaseMipmapComputeShader == null)
        {
            m_occlusionPolyphaseMipmapComputeShader = (ComputeShader)Resources.Load("Compute Shaders/Indirect Light/Polyphase Mipmap/GenerateOcclusionPolyphaseMipmapsCompute");
        }

        GeneratePolyphaseTextureMipmaps(_context, m_emissionPolyphaseMipmapComputeShader, i_emissiveTexture, new Vector2(_camera.pixelWidth, _camera.pixelHeight), 4); //TODO: Firgure out max mips from LPV data
        GeneratePolyphaseTextureMipmaps(_context, m_occlusionPolyphaseMipmapComputeShader, i_occlusionTexture, new Vector2(_camera.pixelWidth, _camera.pixelHeight), 4);

        // So we can grab some temporary textures that are a power of two above the camera size which generate mips automatically
        // We'll then render the emissive and occlusion into them

        // We can then use the mipmapped textures

        // LPV iterations into the direct light texture ready for final presenting
        GenerateIndirectLight(_context, i_emissiveTexture, i_occlusionTexture, o_indirectLightTexture, _camera, m_lpvIterationsData, Color.black);
    }
    // --------------------------------------------------------------------
    private void GeneratePolyphaseTextureMipmaps(
        ScriptableRenderContext _context,
        ComputeShader _shader,
        RenderTargetIdentifier _textureID,
        Vector2 _textureSize,
        int maxMipLevelGenerated = -1
        )
    {
        //Polyphase box filter for non-power of two texture mip-mapping

        int[] previousSize;
        int[] currentSize;

        //We need to check if width or height has been rounded
        bool[] rounded = new bool[2];

        //The initial size needs to be recalculated when restarting for each layer so it has to happen within the loop
        previousSize = new int[] { (int)_textureSize.x, (int)_textureSize.y };

        //Calculate the max possible mip levels this texture can have so we know how may iterations to do
        float mipLevels = (int)Mathf.Floor(Mathf.Log(Mathf.Max(_textureSize.x, _textureSize.y), 2));

        if (maxMipLevelGenerated != -1)
        {
            mipLevels = Mathf.Min(mipLevels, maxMipLevelGenerated);
        }

        //First mip has a special case for occlusion mipmapping
        m_polyphaseMipmapBuffer.SetComputeFloatParam(_shader, "isFirstMip", 1f);

        for (var lowerMipLevel = 0; lowerMipLevel < mipLevels; lowerMipLevel++)
        {
            //Get the current size of this mipmap
            currentSize = new int[] { previousSize[0] / 2, previousSize[1] / 2 };                                      //n for width and height
            rounded     = new bool[] { previousSize[0] / 2f > currentSize[0], previousSize[1] / 2f > currentSize[1] }; //Must be floats for the division

            //Pick a kernel given the state of the rounded edges (0, 1, 2, 3)
            int kernelIndex;
            if (rounded[0] == false)
            {
                if (rounded[1] == false)
                {
                    //Box - box
                    kernelIndex = 0;
                }
                else
                {
                    //Box - poly
                    kernelIndex = 1;
                }
            }
            else
            {
                if (rounded[1] == false)
                {
                    //Poly - box
                    kernelIndex = 2;
                }
                else
                {
                    //Poly - poly
                    kernelIndex = 3;
                }
            }

            // Set shader properties

            //Bind the lower mip level to read from
            m_polyphaseMipmapBuffer.SetComputeTextureParam(_shader, kernelIndex, "LowerMipTex", _textureID, lowerMipLevel);

            //Bind the higher mip level to write to
            m_polyphaseMipmapBuffer.SetComputeTextureParam(_shader, kernelIndex, "HigherMipTex", _textureID, lowerMipLevel + 1);

            //Setup additional working variables
            m_polyphaseMipmapBuffer.SetComputeVectorParam(_shader, "LowerMipTexSize", new Vector2(previousSize[0], previousSize[1]));
            m_polyphaseMipmapBuffer.SetComputeVectorParam(_shader, "HigherMipTexSize", new Vector2(currentSize[0], currentSize[1]));
            m_polyphaseMipmapBuffer.SetComputeVectorParam(_shader, "WasTextureSizeRounded", new Vector2(rounded[0] ? 1f : 0f, rounded[1] ? 1f : 0f));

            //Calculate these once so doesn't need to be repeated for each pixel
            m_polyphaseMipmapBuffer.SetComputeVectorParam(_shader, "HigherMipTexelUVSize", new Vector2(1f / currentSize[0], 1f / currentSize[1]));
            m_polyphaseMipmapBuffer.SetComputeVectorParam(_shader, "LowerMipTexelUVSize", new Vector2(1f / previousSize[0], 1f / previousSize[1]));

            m_polyphaseMipmapBuffer.DispatchCompute(
                _shader,
                kernelIndex,
                Mathf.CeilToInt(currentSize[0] / 8f),
                Mathf.CeilToInt(currentSize[1] / 8f),
                1
                );

            //Set previous size for next mip
            previousSize = currentSize;

            if (lowerMipLevel == 0)
            {
                m_polyphaseMipmapBuffer.SetComputeFloatParam(_shader, "isFirstMip", 0f);
            }
        }

        L2DLRenderHelpers.ExecuteBuffer(_context, m_polyphaseMipmapBuffer);
    }
    // --------------------------------------------------------------------
    private void GenerateIndirectLight
    (
        ScriptableRenderContext _context,
        RenderTargetIdentifier i_emissiveTexture,
        RenderTargetIdentifier i_occlusionTexture,
        RenderTargetIdentifier o_indirectLightTexture,
        Camera _camera,
        List <LPVIterationData> _lpvIterationsData,
        Color _ambientLightColour
    )
    {
        // Get working textures
        RenderTextureDescriptor bufferTextureDescriptor = new RenderTextureDescriptor(_camera.pixelWidth, _camera.pixelHeight, RenderTextureFormat.ARGBHalf, 0)
        {
            useMipMap         = true,
            autoGenerateMips  = false,
            enableRandomWrite = true
        };

        m_lpvIterationsBuffer.GetTemporaryRT(flipTextureId, bufferTextureDescriptor, FilterMode.Point);
        m_lpvIterationsBuffer.GetTemporaryRT(flopTextureId, bufferTextureDescriptor, FilterMode.Point);

        // Check shaders
        if (m_lpvIterationsComputeShader == null)
        {
            m_lpvIterationsComputeShader = (ComputeShader)Resources.Load("Compute Shaders/Indirect Light/LPV/LPVIterationCompute");
        }
        m_lpvIterationsFlipKernel = m_lpvIterationsComputeShader.FindKernel("LPVIterationFlip");
        m_lpvIterationsFlopKernel = m_lpvIterationsComputeShader.FindKernel("LPVIterationFlop");

        m_lpvIterationsBuffer.SetComputeTextureParam(m_lpvIterationsComputeShader, m_lpvIterationsFlipKernel, "OcclusionInput", i_occlusionTexture);
        m_lpvIterationsBuffer.SetComputeTextureParam(m_lpvIterationsComputeShader, m_lpvIterationsFlopKernel, "OcclusionInput", i_occlusionTexture);
        m_lpvIterationsBuffer.SetComputeFloatParam(m_lpvIterationsComputeShader, "OcclusionMultiplier", 1f); // TODO

        if (m_moveLPVDataDownMipLevelsComputeShader == null)
        {
            m_moveLPVDataDownMipLevelsComputeShader = (ComputeShader)Resources.Load("Compute Shaders/Indirect Light/LPV/MoveLPVDataDownMipLevels");
        }
        m_moveLPVDataDownMipLevelsKernel = m_moveLPVDataDownMipLevelsComputeShader.FindKernel("MoveLPVDataDownMipLevels");

        // LPV Iterations
        float[] textureWidths  = new float[_lpvIterationsData.Count];
        float[] textureHeights = new float[_lpvIterationsData.Count];

        int totalIterationsSoFar = 0;

        for (int i = 0; i < _lpvIterationsData.Count; i++)
        {
            float lightingOutputResolutionDivisor = Mathf.Pow(2, _lpvIterationsData[i].MipLevel);

            textureWidths[i]  = _camera.pixelWidth / lightingOutputResolutionDivisor;
            textureHeights[i] = _camera.pixelHeight / lightingOutputResolutionDivisor;

            int threadGroupsX = Mathf.CeilToInt(_camera.pixelWidth / lightingOutputResolutionDivisor / 8f);
            int threadGroupsY = Mathf.CeilToInt(_camera.pixelHeight / lightingOutputResolutionDivisor / 8f);

            if (i == 0)
            {
                //Copy
                m_lpvIterationsBuffer.CopyTexture(i_emissiveTexture, 0, _lpvIterationsData[i].MipLevel, flipTextureId, 0, _lpvIterationsData[i].MipLevel);

                //We just want to inject the ambient light colour into the specified levels
                //if (_lpvIterationsData[i].InjectAmbientLight)
                //{
                //    m_lpvIterationsBuffer.SetComputeTextureParam(shaders.ambientLightInjectionComputeShader, shaders.ambientLightInjectionComputeKernel, "Texture", flipTextureId, _lpvIterationsData[i].MipLevel);
                //    m_lpvIterationsBuffer.SetComputeVectorParam(shaders.ambientLightInjectionComputeShader, "AmbientLight", _ambientLightColour);
                //    m_lpvIterationsBuffer.DispatchCompute(shaders.ambientLightInjectionComputeShader, shaders.ambientLightInjectionComputeKernel, threadGroupsX, threadGroupsY, 1);
                //}
            }
            else
            {
                //Instead of copying across I need to shift all of the data down some mip levels using a compute shader for:
                // - The lighting flip tex (from whichever one was last used)1
                // - The lighting total tex
                m_lpvIterationsBuffer.SetComputeVectorParam(m_moveLPVDataDownMipLevelsComputeShader, "OutputCellSize", new Vector2(textureWidths[i] / textureWidths[i - 1], textureHeights[i] / textureHeights[i - 1]));

                m_lpvIterationsBuffer.SetComputeTextureParam(m_moveLPVDataDownMipLevelsComputeShader, m_moveLPVDataDownMipLevelsKernel, "CurrentTotalInput", o_indirectLightTexture, _lpvIterationsData[i - 1].MipLevel);
                m_lpvIterationsBuffer.SetComputeTextureParam(m_moveLPVDataDownMipLevelsComputeShader, m_moveLPVDataDownMipLevelsKernel, "EmissiveSourcesInput", i_emissiveTexture, _lpvIterationsData[i].MipLevel);
                m_lpvIterationsBuffer.SetComputeTextureParam(m_moveLPVDataDownMipLevelsComputeShader, m_moveLPVDataDownMipLevelsKernel, "Output1", (totalIterationsSoFar % 2) == 0 ? flipTextureId : flopTextureId, _lpvIterationsData[i].MipLevel);
                m_lpvIterationsBuffer.SetComputeTextureParam(m_moveLPVDataDownMipLevelsComputeShader, m_moveLPVDataDownMipLevelsKernel, "Output2", o_indirectLightTexture, _lpvIterationsData[i].MipLevel);
                m_lpvIterationsBuffer.DispatchCompute(m_moveLPVDataDownMipLevelsComputeShader, m_moveLPVDataDownMipLevelsKernel, threadGroupsX, threadGroupsY, 1);

                //if (_lpvIterationsData[i].InjectAmbientLight)
                //{
                //    m_lpvIterationsBuffer.SetComputeTextureParam(shaders.ambientLightInjectionComputeShader, shaders.ambientLightInjectionComputeKernel, "Texture", (totalIterationsSoFar % 2) == 0 ? flipTextureId : flopTextureId, _lpvIterationsData[i].MipLevel);
                //    m_lpvIterationsBuffer.SetComputeVectorParam(shaders.ambientLightInjectionComputeShader, "AmbientLight", _ambientLightColour);
                //    m_lpvIterationsBuffer.DispatchCompute(shaders.ambientLightInjectionComputeShader, shaders.ambientLightInjectionComputeKernel, threadGroupsX, threadGroupsY, 1);
                //}
            }

            //Clear only the FIRST TIME as it's the start of a new total counting
            if (_lpvIterationsData[i].MipLevel != 0)
            {
                m_lpvIterationsBuffer.SetRenderTarget(o_indirectLightTexture, _lpvIterationsData[i].MipLevel);
                m_lpvIterationsBuffer.ClearRenderTarget(true, true, Color.black);
            }

            m_lpvIterationsBuffer.SetComputeIntParam(m_lpvIterationsComputeShader, "WorkingMipLevel", _lpvIterationsData[i].MipLevel);
            m_lpvIterationsBuffer.SetComputeIntParam(m_lpvIterationsComputeShader, "StartTotalSavingIteration", _lpvIterationsData[i].TotalStartIteration);

            m_lpvIterationsBuffer.SetComputeFloatParam(m_lpvIterationsComputeShader, "TexelWorldWidth", _camera.orthographicSize / (_camera.pixelHeight / lightingOutputResolutionDivisor / 2f));
            m_lpvIterationsBuffer.SetComputeTextureParam(m_lpvIterationsComputeShader, m_lpvIterationsFlipKernel, "LightTotal", o_indirectLightTexture, _lpvIterationsData[i].MipLevel);
            m_lpvIterationsBuffer.SetComputeTextureParam(m_lpvIterationsComputeShader, m_lpvIterationsFlopKernel, "LightTotal", o_indirectLightTexture, _lpvIterationsData[i].MipLevel);
            m_lpvIterationsBuffer.SetComputeTextureParam(m_lpvIterationsComputeShader, m_lpvIterationsFlipKernel, "LightFlip", flipTextureId, _lpvIterationsData[i].MipLevel);
            m_lpvIterationsBuffer.SetComputeTextureParam(m_lpvIterationsComputeShader, m_lpvIterationsFlipKernel, "LightFlop", flopTextureId, _lpvIterationsData[i].MipLevel);
            m_lpvIterationsBuffer.SetComputeTextureParam(m_lpvIterationsComputeShader, m_lpvIterationsFlopKernel, "LightFlip", flipTextureId, _lpvIterationsData[i].MipLevel);
            m_lpvIterationsBuffer.SetComputeTextureParam(m_lpvIterationsComputeShader, m_lpvIterationsFlopKernel, "LightFlop", flopTextureId, _lpvIterationsData[i].MipLevel);

            for (var j = 0; j < _lpvIterationsData[i].Iterations; j++)
            {
                m_lpvIterationsBuffer.SetComputeIntParam(m_lpvIterationsComputeShader, "Iteration", j);
                m_lpvIterationsBuffer.DispatchCompute(m_lpvIterationsComputeShader, (totalIterationsSoFar + j) % 2 == 0 ? m_lpvIterationsFlipKernel : m_lpvIterationsFlopKernel, threadGroupsX, threadGroupsY, 1);
            }

            totalIterationsSoFar += _lpvIterationsData[i].Iterations;
        }

        //Release textures
        m_lpvIterationsBuffer.ReleaseTemporaryRT(flipTextureId);
        m_lpvIterationsBuffer.ReleaseTemporaryRT(flopTextureId);

        L2DLRenderHelpers.ExecuteBuffer(_context, m_lpvIterationsBuffer);
    }
Ejemplo n.º 17
0
    // --------------------------------------------------------------------
    public void Render(ScriptableRenderContext context, Camera camera)
    {
        m_context = context;
        m_camera  = camera;

        // Sample to encapsulate all used buffers under one heading in the frame debugger
        L2DLRenderHelpers.BeginSample(m_context, m_sceneDataRenderBuffer);
        {
            m_context.SetupCameraProperties(m_camera);

            // MUST go before culling so that in world UI is setup pre-cull
            L2DLRenderHelpers.PrepareCameraForSceneWindow(m_camera);

            if (!m_camera.TryGetCullingParameters(out m_cullingParameters))
            {
                return;
            }
            m_cullingResults = m_context.Cull(ref m_cullingParameters);

            //Clear the main output textures
            m_clearTexturebuffer.SetRenderTarget(new RenderTargetIdentifier[]
            {
                L2DLPipelineData.s_cameraColorTextureId
            },
                                                 L2DLPipelineData.s_cameraDepthTextureId);
            if (m_camera.cameraType == CameraType.SceneView)
            {
                // The scene m_camera's settings aren't always set to clear things, it's quite odd so hard code it to clear
                m_clearTexturebuffer.ClearRenderTarget(true, true, m_camera.backgroundColor.linear);
            }
            else
            {
                m_clearTexturebuffer.ClearRenderTarget(m_camera.clearFlags <= CameraClearFlags.Depth, m_camera.clearFlags == CameraClearFlags.Color, m_camera.clearFlags == CameraClearFlags.Color ? m_camera.backgroundColor.linear : Color.clear);
            }

            //Clear the buffer textures
            m_clearTexturebuffer.SetRenderTarget(new RenderTargetIdentifier[]
            {
                L2DLPipelineData.s_cameraOcclusionTextureId,
                L2DLPipelineData.s_cameraEmissionTextureId,
                L2DLPipelineData.s_cameraAdditionalDataTextureId
            },
                                                 L2DLPipelineData.s_cameraDepthTextureId);
            m_clearTexturebuffer.ClearRenderTarget(false, true, Color.clear);
            L2DLRenderHelpers.ExecuteBuffer(m_context, m_clearTexturebuffer);

            // Set render targets for rendering
            m_sceneDataRenderBuffer.SetRenderTarget(new RenderTargetIdentifier[]
            {
                L2DLPipelineData.s_cameraColorTextureId,
                L2DLPipelineData.s_cameraOcclusionTextureId,
                L2DLPipelineData.s_cameraEmissionTextureId,
                L2DLPipelineData.s_cameraAdditionalDataTextureId
            },
                                                    L2DLPipelineData.s_cameraDepthTextureId);
            L2DLRenderHelpers.ExecuteBuffer(m_context, m_sceneDataRenderBuffer);

            L2DLRenderHelpers.DrawAllRenderers(m_context, m_cullingResults);
        }
        L2DLRenderHelpers.EndSample(m_context, m_sceneDataRenderBuffer);

        // Editor Only
        L2DLRenderHelpers.DrawUnsupportedShaders(m_context, m_cullingResults);
    }