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); }
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); } }