Как связать сохраненную переменную с уравнением, которое влияет на несколько источников света по отдельности?(В Unity, используя C #) - PullRequest
0 голосов
/ 05 октября 2018

Для моей игры я симулирую блики, и у меня есть уравнение для расчета количества яркости на глазу наблюдателя.Поскольку блики основаны на перспективе, уравнение должно учитывать, что угол, на который солнце попадает в глаз пользователя (в данном случае, камера), будет меняться, когда пользователь поворачивает голову.Это, в свою очередь, требует изменения интенсивности в каждой точке, где у меня есть источник света, для каждого отдельного источника света.У кого-нибудь есть какие-либо стратегии для кодирования этого?

Я предполагаю, что мне нужно вызывать каждый источник света как функцию, а затем привязать интенсивность к уравнению блика, в котором угол падения источника света хранится как переменная, связанная с гарнитурой.

Способ, которым свет вызывается в единстве:

     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 () {

 }
}

И это изЕдинство сайта как пример изменения интенсивности света от переменных:

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

1 Ответ

0 голосов
/ 05 октября 2018

В каждом цикле обновления вам нужно будет циклически проходить по источникам света и получать вектор мирового пространства, представляющий расстояние между источником света и гарнитурой / пользователем по отношению к миру Normal.Это можно использовать для вычисления угла между гарнитурой (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, я бы порекомендовал разместить на сайте Game Development SE .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...