Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Assets/GothicVR/Scripts/Creator/VobCreator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,9 @@ private static GameObject CreateLight(ZenKit.Vobs.Light vob)
SetPosAndRot(vobObj, vob.Position, vob.Rotation);

StationaryLight lightComp = vobObj.AddComponent<StationaryLight>();
lightComp.ColorAnimationList = vob.ColorAnimationList.Select(color =>
new Color(color.R / 255f, color.G / 255f, color.B / 255f, color.A / 255f)).ToList();
lightComp.ColorAnimationFps = vob.ColorAnimationFps;
lightComp.Color = new Color(vob.Color.R / 255f, vob.Color.G / 255f, vob.Color.B / 255f, vob.Color.A / 255f);
lightComp.Type = vob.LightType == ZenKit.Vobs.LightType.Point
? UnityEngine.LightType.Point
Expand Down
1 change: 1 addition & 0 deletions Assets/GothicVR/Scripts/Creator/WorldCreator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public static async Task CreateAsync(string worldName)

SkyManager.I.InitSky();
StationaryLight.InitStationaryLights();
StationaryLightsManager.I.InitLightColorChange();

if (FeatureFlags.I.showBarrier)
{
Expand Down
37 changes: 35 additions & 2 deletions Assets/GothicVR/Scripts/Manager/StationaryLightsManager.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using GVR.Util;
using UnityEngine;
Expand All @@ -21,10 +23,38 @@ private void LateUpdate()
{
UpdateRenderer(renderer);
}

DirtiedMeshes.Clear();
Profiler.EndSample();
}
}

public void InitLightColorChange()
{
StartCoroutine(UpdateLightColors());
}


private IEnumerator UpdateLightColors()
{
while(true)
{
var colorIndices =
Shader.GetGlobalFloatArray(StationaryLight.GlobalStationaryLightColorIndicesShaderId);
var highestTimeInterval = 0f;
foreach (var light in StationaryLight.Lights)
{
colorIndices[light.Index] = Array.IndexOf(StationaryLight.LightColors,
StationaryLight.Lights[light.Index].Color.linear);
if (highestTimeInterval < light.ColorAnimationFps)
highestTimeInterval = light.ColorAnimationFps;
}

Shader.SetGlobalFloatArray(StationaryLight.GlobalStationaryLightColorIndicesShaderId, colorIndices);
yield return new WaitForSeconds(1 / highestTimeInterval);
}
}

public static void AddLightOnRenderer(StationaryLight light, MeshRenderer renderer)
{
if (!LightsPerRenderer.ContainsKey(renderer))
Expand Down Expand Up @@ -67,12 +97,14 @@ private void UpdateRenderer(MeshRenderer renderer)
{
indicesMatrix[i / 4, i % 4] = LightsPerRenderer[renderer][i].Index;
}

for (int i = 0; i < NonAllocMaterials.Count; i++)
{
if (NonAllocMaterials[i])
{
NonAllocMaterials[i].SetMatrix(StationaryLight.StationaryLightIndicesShaderId, indicesMatrix);
NonAllocMaterials[i].SetInt(StationaryLight.StationaryLightCountShaderId, LightsPerRenderer[renderer].Count);
NonAllocMaterials[i].SetInt(StationaryLight.StationaryLightCountShaderId,
LightsPerRenderer[renderer].Count);
}
}

Expand All @@ -82,6 +114,7 @@ private void UpdateRenderer(MeshRenderer renderer)
{
indicesMatrix[i / 4, i % 4] = LightsPerRenderer[renderer][i + 16].Index;
}

for (int i = 0; i < NonAllocMaterials.Count; i++)
{
if (NonAllocMaterials[i])
Expand All @@ -92,4 +125,4 @@ private void UpdateRenderer(MeshRenderer renderer)
}
}
}
}
}
40 changes: 36 additions & 4 deletions Assets/GothicVR/Scripts/Vob/StationaryLight.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using GVR.Manager;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using GVR.Extensions;
using UnityEngine;
using UnityEngine.Profiling;
Expand Down Expand Up @@ -114,6 +116,7 @@ public float SpotAngle
public static readonly List<StationaryLight> Lights = new List<StationaryLight>();

public static readonly int GlobalStationaryLightPositionsAndAttenuationShaderId = Shader.PropertyToID("_GlobalStationaryLightPositionsAndAttenuation");
public static readonly int GlobalStationaryLightColorIndicesShaderId = Shader.PropertyToID("_GlobalStationaryLightColorIndices");
public static readonly int GlobalStationaryLightColorsShaderId = Shader.PropertyToID("_GlobalStationaryLightColors");
public static readonly int StationaryLightIndicesShaderId = Shader.PropertyToID("_StationaryLightIndices");
public static readonly int StationaryLightIndices2ShaderId = Shader.PropertyToID("_StationaryLightIndices2");
Expand All @@ -124,6 +127,10 @@ public float SpotAngle
private List<MeshRenderer> _affectedRenderers = new List<MeshRenderer>();
private Light _unityLight;
private static readonly List<(Vector3 Position, float Range)> ThreadSafeLightData = new();
internal int CurrentColorIndex;
internal float ColorAnimationFps; // change color every 1/ColorAnimationFps seconds
internal List<Color> ColorAnimationList = new();
public static Vector4[] LightColors;

private void OnDrawGizmosSelected()
{
Expand Down Expand Up @@ -151,6 +158,7 @@ private void OnDestroy()
private void OnEnable()
{
Profiler.BeginSample("Stationary light enabled");
StartCoroutine(ChangeColor(this));
for (int i = 0; i < _affectedRenderers.Count; i++)
{
StationaryLightsManager.AddLightOnRenderer(this, _affectedRenderers[i]);
Expand All @@ -161,6 +169,7 @@ private void OnEnable()
private void OnDisable()
{
Profiler.BeginSample("Stationary light disable");
StopCoroutine(ChangeColor(this));
for (int i = 0; i < _affectedRenderers.Count; i++)
{
StationaryLightsManager.RemoveLightOnRenderer(this, _affectedRenderers[i]);
Expand All @@ -175,23 +184,46 @@ public static void InitStationaryLights()
// e.g. if we disabled Vob loading within FeatureFlags.
if (Lights.IsEmpty())
return;

List<Vector4> _lightColorsList = new List<Vector4>();
foreach (var light in Lights)
{
_lightColorsList.Add(light.Color.linear);
_lightColorsList.AddRange(light.ColorAnimationList.Select(t => t.linear).Select(dummy => (Vector4)dummy));
}
Vector4[] _lightPositionsAndAttenuation = new Vector4[Lights.Count];
Vector4[] _lightColors = new Vector4[Lights.Count];
float[] _lightColorIndices = new float[Lights.Count];
LightColors = _lightColorsList.Distinct().ToArray();
for (int i = 0; i < Lights.Count; i++)
{
Lights[i].Index = i;
Lights[i].GatherRenderers();
_lightPositionsAndAttenuation[i] = new Vector4(Lights[i].transform.position.x, Lights[i].transform.position.y, Lights[i].transform.position.z, 1f / (Lights[i].Range * Lights[i].Range));
_lightColors[i] = Lights[i].Color.linear;
int index = Array.IndexOf(LightColors, Lights[i].Color.linear);
_lightColorIndices[i] = index;
Lights[i].gameObject.SetActive(false);
Lights[i].gameObject.SetActive(true);
}

Shader.SetGlobalVectorArray(GlobalStationaryLightPositionsAndAttenuationShaderId, _lightPositionsAndAttenuation);
Shader.SetGlobalVectorArray(GlobalStationaryLightColorsShaderId, _lightColors);
Shader.SetGlobalFloatArray(GlobalStationaryLightColorIndicesShaderId, _lightColorIndices);
Shader.SetGlobalVectorArray(GlobalStationaryLightColorsShaderId, LightColors);
ThreadSafeLightData.Clear(); // Clear the thread safe data as it is no longer needed.
}

private static IEnumerator ChangeColor(StationaryLight light)
{
yield return new WaitForSeconds(1 / light.ColorAnimationFps);
while (true)
{
yield return new WaitForSeconds(1 / light.ColorAnimationFps);
if (light.ColorAnimationList.Count == 0) continue;
light.CurrentColorIndex++;
if (light.CurrentColorIndex >= light.ColorAnimationList.Count)
light.CurrentColorIndex = 0;

light.Color = light.ColorAnimationList[light.CurrentColorIndex];
}
}

public static int CountLightsInBounds(Bounds bounds)
{
Expand Down
3 changes: 2 additions & 1 deletion Assets/GothicVR/Shaders/StationaryLighting.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#define MAX_AFFECTING_STATIONARY_LIGHTS 16

float4 _GlobalStationaryLightPositionsAndAttenuation[MAX_TOTAL_STATIONARY_LIGHTS];
float _GlobalStationaryLightColorIndices[MAX_TOTAL_STATIONARY_LIGHTS];
real3 _GlobalStationaryLightColors[MAX_TOTAL_STATIONARY_LIGHTS];

half3 AdditionalStationaryDiffuse(uint lightIndex, real3 worldPos, real3 normal)
Expand All @@ -15,7 +16,7 @@ half3 AdditionalStationaryDiffuse(uint lightIndex, real3 worldPos, real3 normal)
half3 lightDirection = half3(lightVector * rsqrt(distanceSqr));
float diffuseDot = saturate(dot(lightDirection, normal));

return _GlobalStationaryLightColors[lightIndex] * CustomDistanceAttenuation(distanceSqr, lightPosAndAttenuation.w) * diffuseDot * _PointLightIntensity;
return _GlobalStationaryLightColors[_GlobalStationaryLightColorIndices[lightIndex]] * CustomDistanceAttenuation(distanceSqr, lightPosAndAttenuation.w) * diffuseDot * _PointLightIntensity;
}

#endif