Just to resurrect the topic - is there any way to have a TV screen have emissive light? Like, lighting that changes based on the scene on the tv.
There is this from script from 2020, but it only works on web panels and it looks like Doofenschmalphys hasn't been active in years.
Hey everyone! This plugin adds a dynamically changing light to any Web Panel! It has only one slider, which determines how much of the canvas it looks at every frame. I figured it would be easier to modify the light directly than to try to save...
hub.virtamate.com
I thought this was a good idea, so I did some testing. It does work to light up the scene from what webpage/image you are looking at, but the web panel is outdated, and useless for video to me.
I took a quick look, but I don't really get what I'm doing with scripts, so if anyone knows how you change the reference to update this script and make it work with emmisive image panels, I'd be interested.
The original is CC-BY so here is the script.
WebPanelLight2.cs
----------------------
using System.Xml.Schema;
using System;
using UnityEngine;
using UnityEngine.UI;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using SimpleJSON;
using UnityEngine.Events;
namespace Doofenschmalphys{
public class WebPanelLight : MVRScript
{
List<Atom> lights = new List<Atom>();
Vector3 screenpos = new Vector3();
Quaternion screenrot = new Quaternion();
int x1,y1,x2,y2 = 0;
JSONStorableFloat Extent;
bool _loaded = false;
public override JSONClass GetJSON(bool includePhysical = true, bool includeAppearance = true, bool forceStore = false) {
var json = base.GetJSON(includePhysical, includeAppearance, forceStore);
try {
json["lightref"] = new JSONClass{
{"name", lights[0].name}
};
needsStore = true;
} catch (Exception exc) {
SuperController.LogError($"{nameof(WebPanelLight)}.{nameof(GetJSON)}: {exc}");
}
return json;
}
string fetchname = "null";
public override void RestoreFromJSON(JSONClass jc, bool restorePhysical = true, bool restoreAppearance = true, JSONArray presetAtoms = null, bool setMissingToDefault = true) {
base.RestoreFromJSON(jc, restorePhysical, restoreAppearance, presetAtoms, setMissingToDefault);
try {
var handsJSON = jc["lightref"];
if (handsJSON != null) {
// SuperController.LogMessage(handsJSON.ToString());
fetchname = handsJSON["name"];
}
_loaded = true;
} catch (Exception exc) {
SuperController.LogError($"{nameof(WebPanelLight)}.{nameof(RestoreFromJSON)}: {exc}");
}
}
private IEnumerator DeferredInit() {
yield return new WaitForEndOfFrame();
try {
if (!_loaded) containingAtom.RestoreFromLast(this);
OnEnable();
} catch (Exception exc) {
SuperController.LogError($"{nameof(WebPanelLight)}.{nameof(DeferredInit)}: {exc}");
}
}
public override void Init()
{
try
{
var f = containingAtom.GetStorableByID("Canvas");
var f2 = containingAtom.GetStorableByID("scale");
//var f3 = containingAtom.GetStorableByID("lightref");
var d = f.GetComponentsInChildren<Graphic>();
var img = d[0] as UnityEngine.UI.RawImage;
var tex = img.texture as Texture2D;
//SuperController.LogMessage(f3.ToString());
Vector3[] v = new Vector3[4];
f.GetComponent<RectTransform>().GetWorldCorners(v);
Vector3 center = new Vector3(v.Average(x=>x.x),v.Average(y=>y.y),v.Average(z=>z.z));
screenpos = center;
screenrot = f.transform.rotation;
Extent = new JSONStorableFloat("Percentage Sampled", 0.4f, (float extent) =>
{
CalcRectangle(extent);
}, 0f, 0.5f, false);
RegisterFloat(Extent);
CreateSlider(Extent);
CalcRectangle(Extent.val);
/*
StartCoroutine(GenerateLight(atom =>{
lights.Add(atom);
}));
*/
StartCoroutine(DeferredInit());
//SuperController.LogMessage(megac.ToString());
}
catch (Exception e)
{
SuperController.LogError($"{nameof(WebPanelLight)}.{nameof(Init)}: {e}");
}
}
bool MovedLights = false;
bool MakeNew=true;
public void Update(){
if(_loaded ){
var z = SuperController.singleton.GetAtomByUid(fetchname);
if(z!=null){
MovedLights=true;
lights.Add(z);
MakeNew=false;
}
_loaded=false;
}
if(MakeNew){
StartCoroutine(GenerateLight(atom =>{
lights.Add(atom);
}));
MakeNew=false;
}
if(!MovedLights){
SetupLights();
}
else{
var p = BSAMPLE();
//SuperController.LogMessage(p.ToString());
UpdateLights(p);
}
}
public void OnEnable()
{
try
{
// SuperController.LogMessage($"{nameof(MyPlugin)} enabled");
}
catch (Exception e)
{
// SuperController.LogError($"{nameof(MyPlugin)}.{nameof(OnEnable)}: {e}");
}
}
public void OnDisable()
{
try
{
//SuperController.LogMessage($"{nameof(MyPlugin)} disabled");
}
catch (Exception e)
{
//SuperController.LogError($"{nameof(MyPlugin)}.{nameof(OnDisable)}: {e}");
}
}
public void OnDestroy()
{
try
{
// SuperController.LogMessage($"{nameof(MyPlugin)} destroyed");
CullLights();
}
catch (Exception e)
{
// SuperController.LogError($"{nameof(MyPlugin)}.{nameof(OnDestroy)}: {e}");
}
}
void CalcRectangle(float inx){
var tex = BSCREEN();
x1 = (int)(inx * tex.width);
y1 = (int)(inx * tex.height);
x2 = (int)((1-inx) * tex.width);
y2 = (int)((1-inx) * tex.height);
}
Color BSAMPLE(){
var tex = BSCREEN();
var colors = tex.GetPixels(x1,y1,x2,y2);
return MEGAVG(colors);
}
Texture2D BSCREEN(){
var f = containingAtom.GetStorableByID("Canvas");
var d = f.GetComponentsInChildren<Graphic>();
var img = d[0] as UnityEngine.UI.RawImage;
return img.texture as Texture2D;
}
Color MEGAVG(Color[] a){
Color b = new Color(0f,0f,0f,0f);
foreach(Color c in a){
b+=c;
}
b/=a.Length;
return b;
}
void SetupLights(){
foreach(var light in lights){
light.transform.position = screenpos;
light.transform.rotation = screenrot;
light.transform.forward = -light.transform.forward;
light.GetStorableByID("Light").SetFloatParamValue("intensity", 2f);
light.GetStorableByID("Light").SetStringChooserParamValue("type","Spot");
light.GetStorableByID("Light").SetFloatParamValue("spotAngle",175f);
MovedLights=true;
}
}
void UpdateLights(Color a){
foreach(Atom light in lights){
var lightStore = light.GetStorableByID("Light");
//lightStore.SetFloatParamValue("intensity", (a.r+a.g+a.b)/3f);
float h, s, v = 0;
Color.RGBToHSV(a, out h, out s, out v);
lightStore.SetColorParamValue("color", new HSVColor { H = h, S = s, V = v });
}
}
void CullLights(){
foreach(Atom light in lights){
SuperController.singleton.RemoveAtom(light);
}
}
IEnumerator GenerateLight(UnityAction<Atom> callback)
{
string id = Guid.NewGuid().ToString();
StartCoroutine(SuperController.singleton.AddAtomByType("InvisibleLight", id));
while(SuperController.singleton.GetAtomByUid(id) == null)
{
yield return new WaitForEndOfFrame();
}
callback(SuperController.singleton.GetAtomByUid(id));
}
}
}