public override void Prepare(RenderDrawContext context)
        {
            for (int index = 0; index < RenderSystem.Views.Count; index++)
            {
                var view        = RenderSystem.Views[index];
                var viewFeature = view.Features[RootRenderFeature.Index];
                foreach (var viewLayout in viewFeature.Layouts)
                {
                    var voxelizerStorer = viewLayout.GetLogicalGroup(VoxelizerStorerCasterKey);

                    ParameterCollection VSViewParameters = new ParameterCollection();
                    ParameterCollection ViewParameters   = new ParameterCollection();

                    RenderVoxelVolumeData data = ReflectiveVoxelRenderer.GetDataForView(view);
                    if (data == null)
                    {
                        continue;
                    }

                    VSViewParameters.Set(IsotropicVoxelFragmentKeys.VoxelVolumeW0, data.ClipMaps);
                    VSViewParameters.Set(IsotropicVoxelFragmentKeys.VoxelFragments, ReflectiveVoxelRenderer.Fragments);
                    VSViewParameters.Set(IsotropicVoxelFragmentKeys.VoxelFragmentsCounter, ReflectiveVoxelRenderer.FragmentsCounter);
                    VSViewParameters.Set(IsotropicVoxelFragmentKeys.VoxelMatrix, data.Matrix);
                    VSViewParameters.Set(IsotropicVoxelFragmentKeys.VoxelMatrixViewport, data.ViewportMatrix);
                    VSViewParameters.Set(IsotropicVoxelFragmentKeys.clipMapCount, data.ClipMapCount);
                    VSViewParameters.Set(IsotropicVoxelFragmentKeys.clipMapResolution, data.ClipMapResolution);

                    var resourceGroup = viewLayout.Entries[view.Index].Resources;
                    resourceGroup.UpdateLogicalGroup(ref voxelizerStorer, VSViewParameters);
                }
            }
        }
            VoxelAttributeEmissionOpacity GetTraceAttr()
            {
                var lightVoxel = ((LightVoxel)Light.Type);

                if (lightVoxel.Volume == null)
                {
                    return(null);
                }
                RenderVoxelVolumeData data = Voxels.VoxelRenderer.GetDataForComponent(lightVoxel.Volume);

                if (data == null)
                {
                    return(null);
                }

                VoxelAttributeEmissionOpacity traceAttr = null;

                foreach (var attr in data.Attributes)
                {
                    if (attr.GetType() == typeof(VoxelAttributeEmissionOpacity))
                    {
                        traceAttr = (VoxelAttributeEmissionOpacity)attr;
                    }
                }
                return(traceAttr);
            }
Beispiel #3
0
        VoxelAttributeEmissionOpacity GetTraceAttr(RenderVoxelVolumeData data)
        {
            if (data == null)
            {
                return(null);
            }

            VoxelAttributeEmissionOpacity traceAttr = null;

            foreach (var attr in data.Attributes)
            {
                if (attr.GetType() == typeof(VoxelAttributeEmissionOpacity))
                {
                    traceAttr = (VoxelAttributeEmissionOpacity)attr;
                }
            }
            return(traceAttr);
        }
            public override void ApplyViewParameters(RenderDrawContext context, int viewIndex, ParameterCollection parameters)
            {
                base.ApplyViewParameters(context, viewIndex, parameters);

                var lightVoxel = ((LightVoxel)Light.Type);

                var intensity            = Light.Intensity;
                var intensityBounceScale = lightVoxel.BounceIntensityScale;
                var specularIntensity    = lightVoxel.SpecularIntensityScale * intensity;

                if (viewIndex != 0)
                {
                    intensity        *= intensityBounceScale / 3.141592f;
                    specularIntensity = 0.0f;
                }

                if (lightVoxel.Volume == null)
                {
                    return;
                }
                RenderVoxelVolumeData data = Voxels.VoxelRenderer.GetDataForComponent(lightVoxel.Volume);

                if (data == null)
                {
                    return;
                }

                parameters.Set(intensityKey, intensity);
                parameters.Set(specularIntensityKey, specularIntensity);

                if (GetTraceAttr() != null)
                {
                    lightVoxel.DiffuseMarcher?.ApplyViewParameters(parameters);
                    lightVoxel.SpecularMarcher?.ApplyViewParameters(parameters);
                    GetTraceAttr().ApplyViewParameters(parameters);
                }
            }
            public override void ApplyViewParameters(RenderDrawContext context, int viewIndex, ParameterCollection parameters)
            {
                base.ApplyViewParameters(context, viewIndex, parameters);

                var lightVoxel = ((LightVoxel)Light.Type);

                var intensity            = Light.Intensity;
                var intensityBounceScale = lightVoxel.BounceIntensityScale;

                RenderVoxelVolumeData data = Xenko.Rendering.Shadows.ReflectiveVoxelRenderer.GetDataForComponent(lightVoxel.Volume);

                if (data == null)
                {
                    return;
                }

                var voxelMatrix = data.Matrix;// ViewProjection;// Matrix.Invert(Matrix.RotationQuaternion(lightVoxel.Rotation));

                // global parameters
                parameters.Set(intensityKey, intensity);
                parameters.Set(intensityBounceScaleKey, intensityBounceScale);
                parameters.Set(voxelMatrixKey, voxelMatrix);

                if (data.ClipMaps != null)
                {
                    parameters.Set(voxelVolumekey, data.ClipMaps);
                    parameters.Set(mipMapsVolumekey, data.MipMaps);
                }
                else
                {
                    parameters.Set(voxelVolumekey, null);
                    parameters.Set(mipMapsVolumekey, null);
                }
                parameters.Set(voxelVolumeMipCountKey, 1);
                parameters.Set(voxelVolumeClipMapCountKey, data.ClipMapCount);
            }
        public virtual void Collect(RenderContext Context, IShadowMapRenderer ShadowMapRenderer)
        {
            renderVoxelVolumes = Context.VisibilityGroup.Tags.Get(CurrentRenderVoxelVolumes);

            if (renderVoxelVolumes == null)
            {
                return;
            }

            Vector3 resolutionMax     = new Vector3(0, 0, 0);
            int     fragmentsMax      = 0;
            int     fragmentsCountMax = 0;

            //Create per-volume textures
            foreach (var pair in renderVoxelVolumes)
            {
                var volume = pair.Value;
                var bounds = volume.ClipMapMatrix.ScaleVector;

                var resolution = bounds / volume.AproxVoxelSize;

                //Calculate closest power of 2 on each axis
                resolution.X = (float)Math.Pow(2, Math.Round(Math.Log(resolution.X, 2)));
                resolution.Y = (float)Math.Pow(2, Math.Round(Math.Log(resolution.Y, 2)));
                resolution.Z = (float)Math.Pow(2, Math.Round(Math.Log(resolution.Z, 2)));

                resolution = new Vector3(resolution.X, resolution.Z, resolution.Y);//Temporary

                Vector3 ClipMapResolution = new Vector3(resolution.X, resolution.Y, resolution.Z * volume.ClipMapCount);
                Vector3 MipMapResolution  = resolution / 2;

                RenderVoxelVolumeData data;
                if (!renderVoxelVolumeData.TryGetValue(pair.Key, out data))
                {
                    renderVoxelVolumeData.Add(pair.Key, data = new RenderVoxelVolumeData());
                }

                data.ClipMapResolution = resolution;
                if (NeedToRecreateTexture(data.ClipMaps, ClipMapResolution))
                {
                    data.ClipMaps = Xenko.Graphics.Texture.New3D(Context.GraphicsDevice, (int)ClipMapResolution.X, (int)ClipMapResolution.Y, (int)ClipMapResolution.Z, new MipMapCount(false), Xenko.Graphics.PixelFormat.R16G16B16A16_Float, TextureFlags.ShaderResource | TextureFlags.UnorderedAccess);
                }
                if (NeedToRecreateTexture(data.MipMaps, resolution))
                {
                    data.MipMaps = Xenko.Graphics.Texture.New3D(Context.GraphicsDevice, (int)MipMapResolution.X, (int)MipMapResolution.Y, (int)MipMapResolution.Z, new MipMapCount(true), Xenko.Graphics.PixelFormat.R16G16B16A16_Float, TextureFlags.ShaderResource | TextureFlags.UnorderedAccess);
                }


                resolutionMax     = Vector3.Min(new Vector3(256), Vector3.Max(resolutionMax, resolution));
                fragmentsMax      = Math.Max(fragmentsMax, (int)(ClipMapResolution.X * ClipMapResolution.Y * ClipMapResolution.Z));
                fragmentsCountMax = Math.Max(fragmentsCountMax, (int)(ClipMapResolution.X * ClipMapResolution.Y) * volume.ClipMapCount);
            }

            //Create re-usable textures

            float resolutionMaxSide = Math.Max(Math.Max(resolutionMax.X, resolutionMax.Y), resolutionMax.Z);

            if (NeedToRecreateTexture(MSAARenderTarget, new Vector3(resolutionMaxSide, resolutionMaxSide, 1)))
            {
                MSAARenderTarget = Texture.New(Context.GraphicsDevice, TextureDescription.New2D((int)resolutionMaxSide, (int)resolutionMaxSide, new MipMapCount(false), PixelFormat.R8G8B8A8_UNorm, TextureFlags.RenderTarget, 1, GraphicsResourceUsage.Default, MultisampleCount.X8), null);
            }

            if (NeedToRecreateBuffer(Fragments, fragmentsMax))
            {
                Fragments = Xenko.Graphics.Buffer.Structured.New(Context.GraphicsDevice, fragmentsMax, 24, true);
            }
            if (NeedToRecreateBuffer(FragmentsCounter, fragmentsCountMax))
            {
                FragmentsCounter = Xenko.Graphics.Buffer.Typed.New(Context.GraphicsDevice, fragmentsCountMax, PixelFormat.R32_SInt, true);
            }

            Vector3 MipMapResolutionMax = resolutionMax / 2;

            if (TempMipMaps == null || !TextureDimensionsEqual(TempMipMaps[0], MipMapResolutionMax))
            {
                if (TempMipMaps != null)
                {
                    for (int i = 0; i < TempMipMaps.Length; i++)
                    {
                        TempMipMaps[0].Dispose();
                    }
                }

                int mipCount = 1 + (int)Math.Floor(Math.Log(Math.Max(MipMapResolutionMax.X, Math.Max(MipMapResolutionMax.Y, MipMapResolutionMax.Z)), 2));

                TempMipMaps = new Xenko.Graphics.Texture[mipCount];

                for (int i = 0; i < TempMipMaps.Length; i++)
                {
                    TempMipMaps[i] = Xenko.Graphics.Texture.New3D(Context.GraphicsDevice, (int)MipMapResolutionMax.X, (int)MipMapResolutionMax.Y, (int)MipMapResolutionMax.Z, false, Xenko.Graphics.PixelFormat.R16G16B16A16_Float, TextureFlags.ShaderResource | TextureFlags.UnorderedAccess);

                    MipMapResolutionMax /= 2;
                    MipMapResolutionMax  = Vector3.Max(new Vector3(1), MipMapResolutionMax);
                }
            }
            if (Generate3DMipmaps == null)
            {
                Generate3DMipmaps = new Xenko.Rendering.ComputeEffect.ComputeEffectShader(Context)
                {
                    ShaderSourceName = "Generate3DMipmaps"
                };
                ClearBuffer = new Xenko.Rendering.ComputeEffect.ComputeEffectShader(Context)
                {
                    ShaderSourceName = "ClearBuffer"
                };
                ArrangeFragments = new Xenko.Rendering.ComputeEffect.ComputeEffectShader(Context)
                {
                    ShaderSourceName = "ArrangeFragments"
                };
            }

            //Create all the views
            reflectiveVoxelViews.Clear();
            foreach (var pair in renderVoxelVolumes)
            {
                var volume = pair.Value;
                var data   = renderVoxelVolumeData[pair.Key];
                var bounds = volume.ClipMapMatrix.ScaleVector;

                var shadowRenderView = new RenderView();

                float nearClip = 0.1f;
                float farClip  = 999.7f;
                //Currently hard coded and kinda odd
                shadowRenderView.View       = Matrix.Translation(0.0f, 1.0f, 0.0f) * Matrix.RotationX(-3.1415f / 2.0f);
                shadowRenderView.Projection = Matrix.OrthoRH(bounds.X * (float)Math.Pow(2, volume.ClipMapCount), bounds.Z * (float)Math.Pow(2, volume.ClipMapCount), nearClip, farClip);
                Matrix.Multiply(ref shadowRenderView.View, ref shadowRenderView.Projection, out shadowRenderView.ViewProjection);
                shadowRenderView.Frustum     = new BoundingFrustum(ref shadowRenderView.ViewProjection);
                shadowRenderView.CullingMode = CameraCullingMode.Frustum;
                shadowRenderView.ViewSize    = new Vector2(1024, 1024);

                float maxRes = Math.Max(Math.Max(data.ClipMapResolution.X, data.ClipMapResolution.Y), data.ClipMapResolution.Z);

                var rotmat = new Matrix(1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1);//xzy

                var viewToTexTrans = Matrix.Translation(0.5f, 0.5f, 0.5f);
                var viewToTexScale = Matrix.Scaling(0.5f, 0.5f, 0.5f);
                var viewportAspect = Matrix.Scaling(data.ClipMapResolution / maxRes);

                // Matrix BaseVoxelMatrix = transmat * scalemat * rotmat;
                Matrix BaseVoxelMatrix = volume.ClipMapMatrix * Matrix.Identity;
                BaseVoxelMatrix.Invert();
                BaseVoxelMatrix = BaseVoxelMatrix * Matrix.Scaling(2f, 2f, 2f) * rotmat;

                data.Matrix         = BaseVoxelMatrix * viewToTexScale * viewToTexTrans;
                data.ViewportMatrix = BaseVoxelMatrix * viewportAspect;
                data.ClipMapCount   = volume.ClipMapCount;

                shadowRenderView.NearClipPlane = nearClip;
                shadowRenderView.FarClipPlane  = farClip;
                shadowRenderView.RenderStages.Add(VoxelStage);

                reflectiveVoxelViews.Add(shadowRenderView, pair.Key);

                // Add the render view for the current frame
                Context.RenderSystem.Views.Add(shadowRenderView);

                // Collect objects in shadow views
                Context.VisibilityGroup.TryCollect(shadowRenderView);

                ShadowMapRenderer?.RenderViewsWithShadows.Add(shadowRenderView);
            }
        }