Skip to content
Permalink
Browse files

[Rendering] Made LightProbe code not dependent on LightProbeProcessor…

… anymore
  • Loading branch information
xen2 committed Feb 13, 2019
1 parent 9eceed0 commit 921dd9d243379f6bd14dfdfe27ab830cd03139ca
@@ -86,7 +86,8 @@ public Task UpdateLightProbeCoefficients()
editor.ServiceProvider.TryGet<RenderDocManager>()?.StartCapture(game.GraphicsDevice, IntPtr.Zero);

// Reset lightprobes temporarily (if requested)
var runtimeData = game.SceneSystem.SceneInstance.GetProcessor<LightProbeProcessor>()?.RuntimeData;
// Note: we only process first LightProbeProcessor
var runtimeData = game.SceneSystem.SceneInstance.GetProcessor<LightProbeProcessor>()?.VisibilityGroup.Tags.Get(LightProbeRenderer.CurrentLightProbes);
if (runtimeData == null)
return new Dictionary<Guid, FastList<Color3>>();

@@ -97,7 +98,7 @@ public Task UpdateLightProbeCoefficients()
game.EditorSceneSystem.GraphicsCompositor.Game = null;

// Regenerate lightprobe coefficients (rendering)
var lightProbes = LightProbeGenerator.GenerateCoefficients(game, runtimeData.LightProbes);
var lightProbes = LightProbeGenerator.GenerateCoefficients(game);

// TODO: Use LightProbe Id instead of entity id once copy/paste and duplicate properly remap them
return lightProbes.ToDictionary(x => x.Key.Entity.Id, x => x.Value);
@@ -216,7 +217,7 @@ private void UpdateLightProbeWireframe()
{
var lightProbeProcessor = game.SceneSystem.SceneInstance.GetProcessor<LightProbeProcessor>();

var lightProbeRuntimeData = lightProbeProcessor?.RuntimeData;
var lightProbeRuntimeData = lightProbeProcessor?.VisibilityGroup.Tags.Get(LightProbeRenderer.CurrentLightProbes);
if (lightProbeRuntimeData == null)
{
// Nothing, just remove existing wireframe and exit
@@ -240,7 +241,10 @@ private void UpdateLightProbeWireframe()
for (var lightProbeIndex = 0; lightProbeIndex < lightProbeRuntimeData.LightProbes.Length; lightProbeIndex++)
{
// check if lightprobe moved
var lightProbe = lightProbeRuntimeData.LightProbes[lightProbeIndex];
var lightProbe = lightProbeRuntimeData.LightProbes[lightProbeIndex] as LightProbeComponent;
if (lightProbe == null)
continue;

if (lightProbe.Entity.Transform.WorldMatrix.TranslationVector != lightProbeRuntimeData.Vertices[lightProbeIndex])
{
needPositionRefresh = true;
@@ -262,7 +266,7 @@ private void UpdateLightProbeWireframe()
if (needPositionRefresh)
{
lightProbeProcessor.UpdateLightProbePositions();
lightProbeRuntimeData = lightProbeProcessor.RuntimeData;
lightProbeRuntimeData = lightProbeProcessor.VisibilityGroup.Tags.Get(LightProbeRenderer.CurrentLightProbes);
if (lightProbeRuntimeData == null)
{
Cleanup();
@@ -12,7 +12,7 @@ namespace Xenko.Engine
{
[DataContract("LightProbeComponent")]
[Display("Light probe", Expand = ExpandRule.Once)]
[DefaultEntityComponentProcessor(typeof(LightProbeProcessor))]
[DefaultEntityComponentRenderer(typeof(LightProbeProcessor))]
[ComponentOrder(15000)]
public class LightProbeComponent : EntityComponent
{
@@ -26,7 +26,7 @@ partial class ForwardRenderer
private unsafe void PrepareLightprobeConstantBuffer(RenderContext context)
{
var renderView = context.RenderView;
var lightProbesData = SceneInstance.GetCurrent(context).GetProcessor<LightProbeProcessor>()?.RuntimeData;
var lightProbesData = context.VisibilityGroup.Tags.Get(LightProbeRenderer.CurrentLightProbes);
if (lightProbesData != null)
{
foreach (var renderFeature in context.RenderSystem.RenderFeatures)
@@ -64,7 +64,7 @@ private unsafe void BakeLightProbes(RenderContext context, RenderDrawContext dra
Buffer lightprobesCoefficients = null;
var renderView = context.RenderView;

var lightProbesData = SceneInstance.GetCurrent(context).GetProcessor<LightProbeProcessor>()?.RuntimeData;
var lightProbesData = context.VisibilityGroup.Tags.Get(LightProbeRenderer.CurrentLightProbes);
if (lightProbesData == null || lightProbesData.Tetrahedra.Count == 0)
{
// No lightprobes, we still set GPU resources (otherwise rendering might fetch invalid data)
@@ -24,7 +24,7 @@ public static class LightProbeGenerator
{
public const int LambertHamonicOrder = 3;

public static Dictionary<LightProbeComponent, FastList<Color3>> GenerateCoefficients(ISceneRendererContext context, LightProbeComponent[] lightProbes)
public static Dictionary<LightProbeComponent, FastList<Color3>> GenerateCoefficients(ISceneRendererContext context)
{
using (var cubemapRenderer = new CubemapSceneRenderer(context, 256))
{
@@ -96,10 +96,10 @@ public static unsafe void UpdateCoefficients(LightProbeRuntimeData runtimeData)
{
for (var lightProbeIndex = 0; lightProbeIndex < runtimeData.LightProbes.Length; lightProbeIndex++)
{
var lightProbe = runtimeData.LightProbes[lightProbeIndex];
var lightProbe = runtimeData.LightProbes[lightProbeIndex] as LightProbeComponent;

// Copy coefficients
if (lightProbe.Coefficients != null)
if (lightProbe?.Coefficients != null)
{
var lightProbeCoefStart = lightProbeIndex * LambertHamonicOrder * LambertHamonicOrder;
for (var index = 0; index < LambertHamonicOrder * LambertHamonicOrder; index++)
@@ -175,7 +175,7 @@ public static unsafe LightProbeRuntimeData GenerateRuntimeData(FastList<LightPro
probeIndices[i] = *(Int4*)tetrahedron.Vertices;
}

var lightProbesCopy = new LightProbeComponent[lightProbes.Count];
var lightProbesCopy = new object[lightProbes.Count];
for (int i = 0; i < lightProbes.Count; ++i)
lightProbesCopy[i] = lightProbes[i];

@@ -9,18 +9,16 @@

namespace Xenko.Rendering.LightProbes
{
public class LightProbeProcessor : EntityProcessor<LightProbeComponent>
public class LightProbeProcessor : EntityProcessor<LightProbeComponent>, IEntityComponentRenderProcessor
{
private bool needPositionUpdate = false;

public LightProbeProcessor() : base(typeof(TransformComponent))
{
}

/// <summary>
/// The current light probe runtime data.
/// </summary>
public LightProbeRuntimeData RuntimeData { get; private set; }
/// <inheritdoc/>
public VisibilityGroup VisibilityGroup { get; set; }

/// <summary>
/// Light probe runtime data is auto-computed when lightprobes are added/removed. If you move them at runtime, please call this method.
@@ -30,7 +28,7 @@ public LightProbeProcessor() : base(typeof(TransformComponent))
/// </remarks>
public void UpdateLightProbePositions()
{
RuntimeData = null;
VisibilityGroup.Tags.Set(LightProbeRenderer.CurrentLightProbes, null);
needPositionUpdate = false;

// Initial load
@@ -48,7 +46,7 @@ public void UpdateLightProbePositions()
if (lightProbes.Count < 4)
return;

RuntimeData = LightProbeGenerator.GenerateRuntimeData(lightProbes);
VisibilityGroup.Tags.Set(LightProbeRenderer.CurrentLightProbes, LightProbeGenerator.GenerateRuntimeData(lightProbes));
}
catch
{
@@ -62,10 +60,11 @@ public void UpdateLightProbePositions()
/// </summary>
public void UpdateLightProbeCoefficients()
{
if (RuntimeData == null)
var runtimeData = VisibilityGroup.Tags.Get(LightProbeRenderer.CurrentLightProbes);
if (runtimeData == null)
return;

LightProbeGenerator.UpdateCoefficients(RuntimeData);
LightProbeGenerator.UpdateCoefficients(runtimeData);
}

public override void Draw(RenderContext context)
@@ -3,9 +3,9 @@

using System;
using System.Collections.Generic;
using Xenko.Core;
using Xenko.Core.Collections;
using Xenko.Core.Mathematics;
using Xenko.Engine;
using Xenko.Graphics;
using Xenko.Rendering.Lights;
using Xenko.Shaders;
@@ -14,13 +14,15 @@
namespace Xenko.Rendering.LightProbes
{
/// <summary>
/// Light renderer for clustered shading.
/// Light probe renderer.
/// </summary>
/// <remarks>
/// Due to the fact that it handles both Point and Spot with a single logic, it doesn't fit perfectly the current logic of one "direct light groups" per renderer.
/// </remarks>
public class LightProbeRenderer : LightGroupRendererBase
{
/// <summary>
/// Property key to access the current collection of <see cref="LightProbeRuntimeData"/> from <see cref="VisibilityGroup.Tags"/>.
/// </summary>
public static readonly PropertyKey<LightProbeRuntimeData> CurrentLightProbes = new PropertyKey<LightProbeRuntimeData>("LightProbeRenderer.CurrentLightProbes", typeof(LightProbeRenderer));

private LightProbeShaderGroupData lightprobeGroup;

public override Type[] LightTypes { get; } = Type.EmptyTypes;
@@ -92,7 +94,7 @@ public override void UpdateLayout(string compositionName)
// Setup light probe shader only if there is some light probe data
// TODO: Just like the ForwardLightingRenderFeature access the LightProcessor, accessing the SceneInstance.LightProbeProcessor is not what we want.
// Ideally, we should send the data the other way around. Let's fix that together when we refactor the lighting at some point.
var lightProbeRuntimeData = SceneInstance.GetCurrent(renderContext)?.GetProcessor<LightProbeProcessor>()?.RuntimeData;
var lightProbeRuntimeData = renderContext.VisibilityGroup.Tags.Get(LightProbeRenderer.CurrentLightProbes);
ShaderSource = lightProbeRuntimeData != null ? shaderSourceEnabled : shaderSourceDisabled;
}
}
@@ -22,8 +22,11 @@ namespace Xenko.Rendering.LightProbes
{
public class LightProbeRuntimeData
{
// Input data
public LightProbeComponent[] LightProbes;
/// <summary>
/// Can be used to setup a link to a source.
/// Typically, this might be a lightprobe component.
/// </summary>
public object[] LightProbes;

// Computed data
public Vector3[] Vertices;

0 comments on commit 921dd9d

Please sign in to comment.
You can’t perform that action at this time.