private void UpdateAtlas(List <SignedDistanceField> sdfDefinitionsPassed, GraphicsDevice graphics,
                                 SpriteBatch spriteBatch, DeferredEnvironmentMapRenderModule environmentMapRenderModule, LightAccumulationModule lightAccumulationModule)
        {
            if (sdfDefinitionsPassed.Count < 1)
            {
                return;
            }

            bool updateAtlas = false;

            if (_signedDistanceFieldDefinitions == null || sdfDefinitionsPassed.Count !=
                _signedDistanceFieldDefinitionsCount)
            {
                _signedDistanceFieldDefinitionsCount = 0;
                updateAtlas = true;
            }


            {
                for (int i = 0; i < sdfDefinitionsPassed.Count; i++)
                {
                    bool found = false;
                    for (int j = 0; j < _signedDistanceFieldDefinitionsCount; j++)
                    {
                        if (sdfDefinitionsPassed[i] == _signedDistanceFieldDefinitions[j])
                        {
                            found = true;
                            break;

                            if (sdfDefinitionsPassed[i].NeedsToBeGenerated)
                            {
                                throw new Exception("test");
                            }
                        }
                    }

                    if (!found)
                    {
                        _signedDistanceFieldDefinitions[_signedDistanceFieldDefinitionsCount] = sdfDefinitionsPassed[i];
                        sdfDefinitionsPassed[i].ArrayIndex = _signedDistanceFieldDefinitionsCount;
                        _signedDistanceFieldDefinitionsCount++;

                        updateAtlas = true;
                    }
                }
            }

            //Now build the atlas

            if (!updateAtlas)
            {
                return;
            }

            _atlasRenderTarget2D?.Dispose();

            int x = 0, y = 0;

            //Count size
            for (int i = 0; i < _signedDistanceFieldDefinitionsCount; i++)
            {
                x = (int)Math.Max(_signedDistanceFieldDefinitions[i].SdfTexture.Width, x);
                _signedDistanceFieldDefinitions[i].TextureResolution.W = y;
                y += _signedDistanceFieldDefinitions[i].SdfTexture.Height;

                _volumeTexResolutionArray[i] = _signedDistanceFieldDefinitions[i].TextureResolution;
                _volumeTexSizeArray[i]       = _signedDistanceFieldDefinitions[i].VolumeSize;
            }

            //todo: Check if we can use half here
            _atlasRenderTarget2D = new RenderTarget2D(graphics, x, y, false, SurfaceFormat.Single, DepthFormat.None);

            graphics.SetRenderTarget(_atlasRenderTarget2D);
            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, SamplerState.PointClamp);
            for (int i = 0; i < _signedDistanceFieldDefinitionsCount; i++)
            {
                spriteBatch.Draw(_signedDistanceFieldDefinitions[i].SdfTexture,
                                 new Rectangle(0, (int)_signedDistanceFieldDefinitions[i].TextureResolution.W, _signedDistanceFieldDefinitions[i].SdfTexture.Width, _signedDistanceFieldDefinitions[i].SdfTexture.Height), Color.White);
            }
            spriteBatch.End();


            //Atlas
            VolumeTex = _atlasRenderTarget2D;
            _volumeTexSizeParam.SetValue(_volumeTexSizeArray);
            _volumeTexResolutionParam.SetValue(_volumeTexResolutionArray);

            lightAccumulationModule.PointLightRenderModule.deferredPointLightParameter_VolumeTexParam.SetValue(_atlasRenderTarget2D);
            lightAccumulationModule.PointLightRenderModule.deferredPointLightParameter_VolumeTexSizeParam.SetValue(_volumeTexSizeArray);
            lightAccumulationModule.PointLightRenderModule.deferredPointLightParameter_VolumeTexResolution.SetValue(_volumeTexResolutionArray);

            environmentMapRenderModule.ParamVolumeTexParam.SetValue(_atlasRenderTarget2D);
            environmentMapRenderModule.ParamVolumeTexSizeParam.SetValue(_volumeTexSizeArray);
            environmentMapRenderModule.ParamVolumeTexResolution.SetValue(_volumeTexResolutionArray);
        }
        public void UpdateDistanceFieldTransformations(List <BasicEntity> entities, List <SignedDistanceField> sdfDefinitions, DeferredEnvironmentMapRenderModule environmentMapRenderModule, GraphicsDevice graphics, SpriteBatch spriteBatch, LightAccumulationModule lightAccumulationModule)
        {
            if (!GameSettings.sdf_draw)
            {
                return;
            }

            //First of all let's build the atlas
            UpdateAtlas(sdfDefinitions, graphics, spriteBatch, environmentMapRenderModule, lightAccumulationModule);

            int i = 0;

            for (var index = 0; index < entities.Count; index++)
            {
                BasicEntity entity = entities[index];

                if (entity.SignedDistanceField.IsUsed)
                {
                    _instanceInverseMatrixArray[i] = entity.WorldTransform.InverseWorld;
                    _instanceScaleArray[i]         = entity.WorldTransform.Scale;
                    _instanceSDFIndexArray[i]      = entity.SignedDistanceField.ArrayIndex;

                    i++;

                    if (i >= InstanceMaxCount)
                    {
                        break;
                    }
                }
            }

            _instancesCount = i;

            //TODO: Check for change

            //Submit
            //Instances

            _instanceInverseMatrixArrayParam.SetValue(_instanceInverseMatrixArray);
            _instanceScaleArrayParam.SetValue(_instanceScaleArray);
            _instanceSDFIndexArrayParam.SetValue(_instanceSDFIndexArray);
            _instancesCountParam.SetValue((float)_instancesCount);

            lightAccumulationModule.PointLightRenderModule.deferredPointLightParameter_InstanceInverseMatrix.SetValue(_instanceInverseMatrixArray);
            lightAccumulationModule.PointLightRenderModule.deferredPointLightParameter_InstanceScale.SetValue(_instanceScaleArray);
            lightAccumulationModule.PointLightRenderModule.deferredPointLightParameter_InstanceSDFIndex.SetValue(_instanceSDFIndexArray);
            lightAccumulationModule.PointLightRenderModule.deferredPointLightParameter_InstancesCount.SetValue((float)_instancesCount);

            environmentMapRenderModule.ParamInstanceInverseMatrix.SetValue(_instanceInverseMatrixArray);
            environmentMapRenderModule.ParamInstanceScale.SetValue(_instanceScaleArray);
            environmentMapRenderModule.ParamInstanceSDFIndex.SetValue(_instanceSDFIndexArray);
            environmentMapRenderModule.ParamInstancesCount.SetValue((float)_instancesCount);
        }