Пример #1
0
        /// <summary>
        /// Creates a single Reflection Probe in the given position
        /// </summary>
        /// <param name="position"></param>
        /// <param name="terrain"></param>
        /// <param name="reflectionProbeData"></param>
        /// <param name="seaLevelActive"></param>
        /// <param name="seaLevel"></param>
        /// <param name="parentTransform"></param>
        /// <param name="isHDRP"></param>
        /// <returns></returns>
        public static ReflectionProbe CreateReflectionProbe(Vector3 position, Vector3 size, Terrain terrain, ReflectionProbeData reflectionProbeData, bool seaLevelActive, float seaLevel, Transform parentTransform, bool isHDRP, bool probeCulling = false)
        {
            GameObject probeObject = new GameObject("Global Generated Reflection Probe");

            float sampledHeight = terrain.SampleHeight(position);

            ReflectionProbe reflectionProbe = probeObject.AddComponent <ReflectionProbe>();

            reflectionProbe.enabled       = false;
            reflectionProbe.blendDistance = 0f;
            reflectionProbe.cullingMask   = reflectionProbeData.reflectionprobeCullingMask;
            reflectionProbe.farClipPlane  = reflectionProbeData.reflectionProbeClipPlaneDistance;
            reflectionProbe.mode          = reflectionProbeData.reflectionProbeMode;
            switch (reflectionProbeData.reflectionProbeRefresh)
            {
            case GaiaConstants.ReflectionProbeRefreshModePW.OnAwake:
                reflectionProbe.refreshMode = ReflectionProbeRefreshMode.OnAwake;
                break;

            case GaiaConstants.ReflectionProbeRefreshModePW.EveryFrame:
                reflectionProbe.refreshMode = ReflectionProbeRefreshMode.EveryFrame;
                break;

            case GaiaConstants.ReflectionProbeRefreshModePW.ViaScripting:
                reflectionProbe.refreshMode = ReflectionProbeRefreshMode.ViaScripting;
                break;

            case GaiaConstants.ReflectionProbeRefreshModePW.ProbeManager:
                reflectionProbe.refreshMode = ReflectionProbeRefreshMode.ViaScripting;
                break;
            }

            if (!seaLevelActive)
            {
                position.y = 500f + seaLevel + 0.2f;
            }
            else
            {
                position.y             = sampledHeight + reflectionProbeData.reflectionProbeOffset;
                reflectionProbe.center = new Vector3(0f, 0f - reflectionProbeData.reflectionProbeOffset - sampledHeight, 0f);
            }

            if (position.y < seaLevel)
            {
                position.y = seaLevel + reflectionProbeData.reflectionProbeOffset;
            }
            probeObject.transform.position = position;
            probeObject.transform.SetParent(parentTransform);

            switch (reflectionProbeData.reflectionProbeResolution)
            {
            case GaiaConstants.ReflectionProbeResolution.Resolution16:
                reflectionProbe.resolution = 16;
                break;

            case GaiaConstants.ReflectionProbeResolution.Resolution32:
                reflectionProbe.resolution = 32;
                break;

            case GaiaConstants.ReflectionProbeResolution.Resolution64:
                reflectionProbe.resolution = 64;
                break;

            case GaiaConstants.ReflectionProbeResolution.Resolution128:
                reflectionProbe.resolution = 128;
                break;

            case GaiaConstants.ReflectionProbeResolution.Resolution256:
                reflectionProbe.resolution = 256;
                break;

            case GaiaConstants.ReflectionProbeResolution.Resolution512:
                reflectionProbe.resolution = 512;
                break;

            case GaiaConstants.ReflectionProbeResolution.Resolution1024:
                reflectionProbe.resolution = 1024;
                break;

            case GaiaConstants.ReflectionProbeResolution.Resolution2048:
                reflectionProbe.resolution = 2048;
                break;
            }

            reflectionProbe.shadowDistance  = 80f;
            reflectionProbe.size            = size;
            reflectionProbe.timeSlicingMode = reflectionProbeData.reflectionProbeTimeSlicingMode;
            reflectionProbe.hdr             = true;
            reflectionProbe.shadowDistance  = reflectionProbeData.reflectionProbeShadowDistance;

            //If HDRP
            if (isHDRP)
            {
#if HDPipeline
                HDAdditionalReflectionData reflectionData = probeObject.GetComponent <HDAdditionalReflectionData>();
                if (reflectionData == null)
                {
                    reflectionData = probeObject.AddComponent <HDAdditionalReflectionData>();
                }

                reflectionData.multiplier   = 1f;
                reflectionData.realtimeMode = ProbeSettings.RealtimeMode.OnEnable;
#endif
            }

#if GAIA_PRO_PRESENT
            ReflectionProbeCuller culler = reflectionProbe.GetComponent <ReflectionProbeCuller>();
            if (probeCulling)
            {
                if (culler == null)
                {
                    culler         = reflectionProbe.gameObject.AddComponent <ReflectionProbeCuller>();
                    culler.m_probe = reflectionProbe;
                    culler.Initialize();
                }
            }
            else
            {
                if (culler != null)
                {
                    GameObject.DestroyImmediate(culler);
                }
            }
#endif

            return(reflectionProbe);
        }
Пример #2
0
        public void RenderLightVolumes(RenderGraph renderGraph, LightingDebugSettings lightingDebugSettings, TextureHandle destination, TextureHandle depthBuffer, CullingResults cullResults, HDCamera hdCamera)
        {
            using (var builder = renderGraph.AddRenderPass <RenderLightVolumesPassData>("LightVolumes", out var passData))
            {
                bool lightOverlapEnabled = CoreUtils.IsLightOverlapDebugEnabled(hdCamera.camera);
                bool useColorAndEdge     = lightingDebugSettings.lightVolumeDebugByCategory == LightVolumeDebug.ColorAndEdge || lightOverlapEnabled;

                passData.hdCamera    = hdCamera;
                passData.cullResults = cullResults;
                passData.debugLightVolumeMaterial = m_DebugLightVolumeMaterial;
                passData.debugLightVolumeCS       = m_DebugLightVolumeCompute;
                passData.debugLightVolumeKernel   = useColorAndEdge ? m_DebugLightVolumeColorsKernel : m_DebugLightVolumeGradientKernel;
                passData.maxDebugLightCount       = (int)lightingDebugSettings.maxDebugLightCount;
                passData.borderRadius             = lightOverlapEnabled ? 0.5f : 1f;
                passData.colorGradientTexture     = m_ColorGradientTexture;
                passData.lightOverlapEnabled      = lightOverlapEnabled;
                passData.lightCountBuffer         = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true)
                {
                    colorFormat = GraphicsFormat.R32_SFloat, clearBuffer = true, clearColor = Color.black, name = "LightVolumeCount"
                });
                passData.colorAccumulationBuffer = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true)
                {
                    colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.black, name = "LightVolumeColorAccumulation"
                });
                passData.debugLightVolumesTexture = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true)
                {
                    colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.black, enableRandomWrite = true, name = "LightVolumeDebugLightVolumesTexture"
                });
                passData.depthBuffer = builder.UseDepthBuffer(depthBuffer, DepthAccess.ReadWrite);
                passData.destination = builder.WriteTexture(destination);

                builder.SetRenderFunc(
                    (RenderLightVolumesPassData data, RenderGraphContext ctx) =>
                {
                    var mpb = ctx.renderGraphPool.GetTempMaterialPropertyBlock();
                    RenderTargetIdentifier[] mrt = ctx.renderGraphPool.GetTempArray <RenderTargetIdentifier>(2);
                    mrt[0] = data.lightCountBuffer;
                    mrt[1] = data.colorAccumulationBuffer;

                    if (data.lightOverlapEnabled)
                    {
                        // We only need the accumulation buffer, not the color (we only display the outline of the light shape in this mode).
                        CoreUtils.SetRenderTarget(ctx.cmd, mrt[0], depthBuffer);

                        // The cull result doesn't contains overlapping lights so we use a custom list
                        foreach (var overlappingHDLight in HDAdditionalLightData.s_overlappingHDLights)
                        {
                            RenderLightVolume(ctx.cmd, data.debugLightVolumeMaterial, overlappingHDLight, overlappingHDLight.legacyLight, mpb);
                        }
                    }
                    else
                    {
                        // Set the render target array
                        CoreUtils.SetRenderTarget(ctx.cmd, mrt, depthBuffer);

                        // First of all let's do the regions for the light sources (we only support Punctual and Area)
                        int numLights = data.cullResults.visibleLights.Length;
                        for (int lightIdx = 0; lightIdx < numLights; ++lightIdx)
                        {
                            // Let's build the light's bounding sphere matrix
                            Light currentLegacyLight = data.cullResults.visibleLights[lightIdx].light;
                            if (currentLegacyLight == null)
                            {
                                continue;
                            }
                            HDAdditionalLightData currentHDRLight = currentLegacyLight.GetComponent <HDAdditionalLightData>();
                            if (currentHDRLight == null)
                            {
                                continue;
                            }

                            RenderLightVolume(ctx.cmd, data.debugLightVolumeMaterial, currentHDRLight, currentLegacyLight, mpb);
                        }

                        // When we enable the light overlap mode we hide probes as they can't be baked in shadow masks
                        if (!data.lightOverlapEnabled)
                        {
                            // Now let's do the same but for reflection probes
                            int numProbes = data.cullResults.visibleReflectionProbes.Length;
                            for (int probeIdx = 0; probeIdx < numProbes; ++probeIdx)
                            {
                                // Let's build the light's bounding sphere matrix
                                ReflectionProbe currentLegacyProbe        = data.cullResults.visibleReflectionProbes[probeIdx].reflectionProbe;
                                HDAdditionalReflectionData currentHDProbe = currentLegacyProbe.GetComponent <HDAdditionalReflectionData>();

                                if (!currentHDProbe)
                                {
                                    continue;
                                }

                                MaterialPropertyBlock m_MaterialProperty = new MaterialPropertyBlock();
                                Mesh targetMesh = null;
                                if (currentHDProbe.influenceVolume.shape == InfluenceShape.Sphere)
                                {
                                    m_MaterialProperty.SetVector(_RangeShaderID, new Vector3(currentHDProbe.influenceVolume.sphereRadius, currentHDProbe.influenceVolume.sphereRadius, currentHDProbe.influenceVolume.sphereRadius));
                                    targetMesh = DebugShapes.instance.RequestSphereMesh();
                                }
                                else
                                {
                                    m_MaterialProperty.SetVector(_RangeShaderID, new Vector3(currentHDProbe.influenceVolume.boxSize.x, currentHDProbe.influenceVolume.boxSize.y, currentHDProbe.influenceVolume.boxSize.z));
                                    targetMesh = DebugShapes.instance.RequestBoxMesh();
                                }

                                m_MaterialProperty.SetColor(_ColorShaderID, new Color(1.0f, 1.0f, 0.0f, 1.0f));
                                m_MaterialProperty.SetVector(_OffsetShaderID, new Vector3(0, 0, 0));
                                Matrix4x4 positionMat = Matrix4x4.Translate(currentLegacyProbe.transform.position);
                                ctx.cmd.DrawMesh(targetMesh, positionMat, data.debugLightVolumeMaterial, 0, 0, m_MaterialProperty);
                            }
                        }
                    }

                    // Set the input params for the compute
                    ctx.cmd.SetComputeTextureParam(data.debugLightVolumeCS, data.debugLightVolumeKernel, _DebugLightCountBufferShaderID, data.lightCountBuffer);
                    ctx.cmd.SetComputeTextureParam(data.debugLightVolumeCS, data.debugLightVolumeKernel, _DebugColorAccumulationBufferShaderID, data.colorAccumulationBuffer);
                    ctx.cmd.SetComputeTextureParam(data.debugLightVolumeCS, data.debugLightVolumeKernel, _DebugLightVolumesTextureShaderID, data.debugLightVolumesTexture);
                    ctx.cmd.SetComputeTextureParam(data.debugLightVolumeCS, data.debugLightVolumeKernel, _ColorGradientTextureShaderID, data.colorGradientTexture);
                    ctx.cmd.SetComputeIntParam(data.debugLightVolumeCS, _MaxDebugLightCountShaderID, data.maxDebugLightCount);
                    ctx.cmd.SetComputeFloatParam(data.debugLightVolumeCS, _BorderRadiusShaderID, data.borderRadius);

                    // Texture dimensions
                    int texWidth  = data.hdCamera.actualWidth;
                    int texHeight = data.hdCamera.actualHeight;

                    // Dispatch the compute
                    int lightVolumesTileSize = 8;
                    int numTilesX            = (texWidth + (lightVolumesTileSize - 1)) / lightVolumesTileSize;
                    int numTilesY            = (texHeight + (lightVolumesTileSize - 1)) / lightVolumesTileSize;
                    ctx.cmd.DispatchCompute(data.debugLightVolumeCS, data.debugLightVolumeKernel, numTilesX, numTilesY, data.hdCamera.viewCount);

                    // Blit this into the camera target
                    CoreUtils.SetRenderTarget(ctx.cmd, destination);
                    mpb.SetTexture(HDShaderIDs._BlitTexture, data.debugLightVolumesTexture);
                    ctx.cmd.DrawProcedural(Matrix4x4.identity, data.debugLightVolumeMaterial, 1, MeshTopology.Triangles, 3, 1, mpb);
                });
            }
        }