如何将存储的变量链接到单独影响多个光源的方程?(在 Unity 中,使用 C#)



对于我的游戏,我正在模拟眩光,并有一个计算观察者眼睛亮度的方程。由于眩光是基于视角的,因此该等式需要考虑太阳照射到用户眼睛的角度(在本例中为相机装备(将随着用户移动头部而变化。这反过来又需要改变我有一个灯的每个点的强度,对于每个单独的光。 有没有人有任何策略来编写这个?

我假设我需要将每个灯单独调用为一个函数,然后将强度链接到眩光方程,该方程将光源入射角存储为变量,链接到耳机。

在统一中召唤光的方式是:

private Light[] lights;
// Use this for initialization
void Start () {
lights = FindObjectsOfType(typeof(Light)) as Light[];
foreach(Light light in lights)
{
light.intensity = 0;
Debug.Log(light);
}
}

但是强度需要以(10 *(来自太阳的照度值(/(根据耳机位置变化的角度(^2(的速率变化。

我将如何在此代码中存储耳机角度,以便强度不是静态数字,而是基于变量?

提供的任何帮助将不胜感激!

编辑:

这是我现在拥有的,无需输入更改:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GlareChange : MonoBehaviour {
private Light[] lights;
// Use this for initialization
void Start()
{
// SDK Object Alias|Utilities|90140
namespace VRTK
{
using UnityEngine;
/// <summary>
/// The GameObject that the SDK Object Alias script is applied to will become a child of the selected SDK Object.
/// </summary>
[AddComponentMenu("VRTK/Scripts/Utilities/VRTK_SDKObjectAlias")]
public class VRTK_SDKObjectAlias : MonoBehaviour
{
/// <summary>
/// Valid SDK Objects
/// </summary>
public enum SDKObject
{
/// <summary>
/// The main camera rig/play area object that defines the player boundary.
/// </summary>
Boundary,
/// <summary>
/// The main headset camera defines the player head.
/// </summary>
Headset
}
[Tooltip("The specific SDK Object to child this GameObject to.")]
public SDKObject sdkObject = SDKObject.Boundary;
protected virtual void OnEnable()
{
VRTK_SDKManager.SubscribeLoadedSetupChanged(LoadedSetupChanged);
ChildToSDKObject();
}
protected virtual void OnDisable()
{
if (!gameObject.activeSelf)
{
VRTK_SDKManager.UnsubscribeLoadedSetupChanged(LoadedSetupChanged);
}
}
protected virtual void LoadedSetupChanged(VRTK_SDKManager sender, VRTK_SDKManager.LoadedSetupChangeEventArgs e)
{
if (VRTK_SDKManager.ValidInstance() && gameObject.activeInHierarchy)
{
ChildToSDKObject();
}
}
protected virtual void ChildToSDKObject()
{
Vector3 currentPosition = transform.localPosition;
Quaternion currentRotation = transform.localRotation;
Vector3 currentScale = transform.localScale;
Transform newParent = null;
switch (sdkObject)
{
case SDKObject.Boundary:
newParent = VRTK_DeviceFinder.PlayAreaTransform();
break;
case SDKObject.Headset:
newParent = VRTK_DeviceFinder.HeadsetTransform();
break;
}
transform.SetParent(newParent);
transform.localPosition = currentPosition;
transform.localRotation = currentRotation;
transform.localScale = currentScale;

lights = Find(typeof(Light)) as Light[];
foreach (Light light in lights)
{
//EYE = illuminance from source, in this case the sun
//q = angle from viewer
light.intensity = (10*EYE/(Mathf.Atan2(currentPosition/SUNPOSITION));
Debug.Log(light);
}
}
}
// Update is called once per frame
void Update () {
}
}

这是来自 unity 站点,作为从变量更改光强度的示例:

using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour {
public float duration = 1.0F;
public Light lt;
void Start() {
lt = GetComponent<Light>();
}
void Update() {
float phi = Time.time / duration * 2 * Mathf.PI;
float amplitude = Mathf.Cos(phi) * 0.5F + 0.5F;
lt.intensity = amplitude;
}
}

在每个更新周期中,您需要遍历光源并获得一个世界空间矢量,该矢量表示光源与头戴设备/用户之间相对于世界正常状态的距离。这可用于计算头戴显示设备 (A(、光源 (C( 和世界法线 (B( 之间的角度。

注意:根据您的坐标空间,您可能需要交换符号或操作数(

d(light) = light.Position - user.Position

角度 θ 可以通过使用此距离构造直角三角形 ABC,然后使用三角函数求解角度 ABC 的切线来计算(同样,符号和操作数可能需要根据使用的坐标空间进行调整(:

tan(θ) = (user.Position.Y - light.Position.Y)/(user.Position.X - light.Position.X)

据推测,您的每个光源都有一个基底或绝对强度。使用此基数(绝对(光度值来计算用户看到的实际(表观(光度,如公式所示:

L(act) = 10 * L(abs)/θ^2

Unity 框架可能具有为您执行这些任务的内置功能,但这些组件将在后台执行此或类似操作。如果您正在寻找特定于 Unity 的指南,我建议您发布到游戏开发 SE 站点。

最新更新