public static float Evaluate(ref VolumeFalloffEngineData falloff, ref OrientedBBox obb, float3 positionWS, float distanceWS)
        {
            float3x3 obbFrame   = new float3x3(obb.right, obb.up, math.cross(obb.up, obb.right));
            float3   obbExtents = new float3(obb.extentX, obb.extentY, obb.extentZ);

            float3 samplePositionBS  = math.mul(obbFrame, positionWS - obb.center);
            float3 samplePositionBCS = samplePositionBS / obbExtents;

            bool isInsideVolume = math.max(math.abs(samplePositionBCS.x), math.max(math.abs(samplePositionBCS.y), math.abs(samplePositionBCS.z))) < 1.0f;

            if (!isInsideVolume)
            {
                return(0.0f);
            }

            float3 samplePositionBNDC = samplePositionBCS * 0.5f + 0.5f;

            float volumeWeight = VolumeFalloff.ComputeVolumeFalloffWeight(
                samplePositionBNDC,
                distanceWS,
                falloff.rcpFaceFadePos,
                falloff.rcpFaceFadeNeg,
                falloff.rcpDistFadeLen,
                falloff.endTimesRcpDistFadeLen
                );

            volumeWeight *= falloff.weight;
            return(volumeWeight);
        }
Exemplo n.º 2
0
        public DensityVolumeList PrepareVisibleDensityVolumeList(HDCamera camera, CommandBuffer cmd)
        {
            DensityVolumeList densityVolumes = new DensityVolumeList();

            if (preset == VolumetricLightingPreset.Off)
            {
                return(densityVolumes);
            }

            using (new ProfilingSample(cmd, "Prepare Visible Density Volume List"))
            {
                Vector3 camPosition = camera.camera.transform.position;
                Vector3 camOffset   = Vector3.zero; // World-origin-relative

                if (ShaderConfig.s_CameraRelativeRendering != 0)
                {
                    camOffset = camPosition; // Camera-relative
                }

                m_VisibleVolumeBounds.Clear();
                m_VisibleVolumeProperties.Clear();

                // Collect all visible finite volume data, and upload it to the GPU.
                HomogeneousDensityVolume[] volumes = Object.FindObjectsOfType(typeof(HomogeneousDensityVolume)) as HomogeneousDensityVolume[];

                for (int i = 0; i < Math.Min(volumes.Length, k_MaxVisibleVolumeCount); i++)
                {
                    HomogeneousDensityVolume volume = volumes[i];

                    // Only test active finite volumes.
                    if (volume.enabled && volume.parameters.IsLocalVolume())
                    {
                        // TODO: cache these?
                        var obb = OrientedBBox.Create(volume.transform);

                        // Handle camera-relative rendering.
                        obb.center -= camOffset;

                        // Frustum cull on the CPU for now. TODO: do it on the GPU.
                        if (GeometryUtils.Overlap(obb, camera.frustum, 6, 8))
                        {
                            // TODO: cache these?
                            var properties = volume.parameters.GetProperties();

                            m_VisibleVolumeBounds.Add(obb);
                            m_VisibleVolumeProperties.Add(properties);
                        }
                    }
                }

                s_VisibleVolumeBoundsBuffer.SetData(m_VisibleVolumeBounds);
                s_VisibleVolumePropertiesBuffer.SetData(m_VisibleVolumeProperties);

                // Fill the struct with pointers in order to share the data with the light loop.
                densityVolumes.bounds     = m_VisibleVolumeBounds;
                densityVolumes.properties = m_VisibleVolumeProperties;

                return(densityVolumes);
            }
        }
        public static void ComputeOrientedBBoxFromFalloffAndTransform(out OrientedBBox obb, ref VolumeFalloff falloff, Transform t)
        {
            Matrix4x4 m = falloff.isTransformScaleUsed
                ? (t.localToWorldMatrix * Matrix4x4.TRS(falloff.center, Quaternion.identity, falloff.size))
                : Matrix4x4.TRS(t.position + (t.rotation * falloff.center), t.rotation, falloff.size);

            obb = new OrientedBBox(m);
        }
        public void VoxelizeDensityVolumes(HDCamera camera, CommandBuffer cmd)
        {
            if (preset == VolumetricLightingPreset.Off)
            {
                return;
            }

            Vector3 camPosition = camera.camera.transform.position;
            Vector3 camOffset   = Vector3.zero; // World-origin-relative

            if (ShaderConfig.s_CameraRelativeRendering != 0)
            {
                camOffset = -camPosition; // Camera-relative
            }

            m_VisibleVolumes.Clear();
            m_VisibleVolumeProperties.Clear();

            // Collect all the visible volume data, and upload it to the GPU.
            HomogeneousDensityVolume[] volumes = Object.FindObjectsOfType(typeof(HomogeneousDensityVolume)) as HomogeneousDensityVolume[];

            foreach (HomogeneousDensityVolume volume in volumes)
            {
                // Only test active finite volumes.
                if (volume.enabled && volume.volumeParameters.IsLocalVolume())
                {
                    // TODO: cache these?
                    var obb = OrientedBBox.Create(volume.transform);

                    // Frustum cull on the CPU for now. TODO: do it on the GPU.
                    if (GeometryUtils.Overlap(obb, camOffset, camera.frustum, 6, 8))
                    {
                        // TODO: cache these?
                        var properties = volume.volumeParameters.GetProperties();

                        m_VisibleVolumes.Add(obb);
                        m_VisibleVolumeProperties.Add(properties);
                    }
                }
            }

            s_VisibleVolumesBuffer.SetData(m_VisibleVolumes);
            s_VisibleVolumePropertiesBuffer.SetData(m_VisibleVolumeProperties);
        }
        public DensityVolumeList PrepareVisibleDensityVolumeList(HDCamera hdCamera, CommandBuffer cmd, float time)
        {
            DensityVolumeList densityVolumes = new DensityVolumeList();

            if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.Volumetrics))
            {
                return(densityVolumes);
            }

            var visualEnvironment = VolumeManager.instance.stack.GetComponent <VisualEnvironment>();

            if (visualEnvironment.fogType.value != FogType.Volumetric)
            {
                return(densityVolumes);
            }

            using (new ProfilingSample(cmd, "Prepare Visible Density Volume List"))
            {
                Vector3 camPosition = hdCamera.camera.transform.position;
                Vector3 camOffset   = Vector3.zero;// World-origin-relative

                if (ShaderConfig.s_CameraRelativeRendering != 0)
                {
                    camOffset = camPosition; // Camera-relative
                }

                m_VisibleVolumeBounds.Clear();
                m_VisibleVolumeData.Clear();

                // Collect all visible finite volume data, and upload it to the GPU.
                DensityVolume[] volumes = DensityVolumeManager.manager.PrepareDensityVolumeData(cmd, hdCamera.camera, time);

                for (int i = 0; i < Math.Min(volumes.Length, k_MaxVisibleVolumeCount); i++)
                {
                    DensityVolume volume = volumes[i];

                    // TODO: cache these?
                    var obb = new OrientedBBox(Matrix4x4.TRS(volume.transform.position, volume.transform.rotation, volume.parameters.size));

                    // Handle camera-relative rendering.
                    obb.center -= camOffset;

                    // Frustum cull on the CPU for now. TODO: do it on the GPU.
                    // TODO: account for custom near and far planes of the V-Buffer's frustum.
                    // It's typically much shorter (along the Z axis) than the camera's frustum.
                    // XRTODO: fix combined frustum culling
                    if (GeometryUtils.Overlap(obb, hdCamera.frustum, 6, 8) || hdCamera.camera.stereoEnabled)
                    {
                        // TODO: cache these?
                        var data = volume.parameters.ConvertToEngineData();

                        m_VisibleVolumeBounds.Add(obb);
                        m_VisibleVolumeData.Add(data);
                    }
                }

                s_VisibleVolumeBoundsBuffer.SetData(m_VisibleVolumeBounds);
                s_VisibleVolumeDataBuffer.SetData(m_VisibleVolumeData);

                // Fill the struct with pointers in order to share the data with the light loop.
                densityVolumes.bounds  = m_VisibleVolumeBounds;
                densityVolumes.density = m_VisibleVolumeData;

                return(densityVolumes);
            }
        }
        public DensityVolumeList PrepareVisibleDensityVolumeList(HDCamera camera, CommandBuffer cmd)
        {
            DensityVolumeList densityVolumes = new DensityVolumeList();

            if (preset == VolumetricLightingPreset.Off)
            {
                return(densityVolumes);
            }

            var visualEnvironment = VolumeManager.instance.stack.GetComponent <VisualEnvironment>();

            if (visualEnvironment.fogType != FogType.Volumetric)
            {
                return(densityVolumes);
            }

            VBuffer vBuffer = FindVBuffer(camera.GetViewID());

            if (vBuffer == null)
            {
                return(densityVolumes);
            }

            using (new ProfilingSample(cmd, "Prepare Visible Density Volume List"))
            {
                Vector3 camPosition = camera.camera.transform.position;
                Vector3 camOffset   = Vector3.zero; // World-origin-relative

                if (ShaderConfig.s_CameraRelativeRendering != 0)
                {
                    camOffset = camPosition; // Camera-relative
                }

                m_VisibleVolumeBounds.Clear();
                m_VisibleVolumeData.Clear();

                // Collect all visible finite volume data, and upload it to the GPU.
                DensityVolume[] volumes = DensityVolumeManager.manager.PrepareDensityVolumeData(cmd);

                for (int i = 0; i < Math.Min(volumes.Length, k_MaxVisibleVolumeCount); i++)
                {
                    DensityVolume volume = volumes[i];

                    // TODO: cache these?
                    var obb = OrientedBBox.Create(volume.transform);

                    // Handle camera-relative rendering.
                    obb.center -= camOffset;

                    // Frustum cull on the CPU for now. TODO: do it on the GPU.
                    if (GeometryUtils.Overlap(obb, camera.frustum, 6, 8))
                    {
                        // TODO: cache these?
                        var data = volume.parameters.GetData();

                        m_VisibleVolumeBounds.Add(obb);
                        m_VisibleVolumeData.Add(data);
                    }
                }

                s_VisibleVolumeBoundsBuffer.SetData(m_VisibleVolumeBounds);
                s_VisibleVolumeDataBuffer.SetData(m_VisibleVolumeData);

                // Fill the struct with pointers in order to share the data with the light loop.
                densityVolumes.bounds  = m_VisibleVolumeBounds;
                densityVolumes.density = m_VisibleVolumeData;

                return(densityVolumes);
            }
        }