Проверка того, насколько освещен игрок для стелс-игры

Итак, я создаю стелс-игру, и хотя использование теневого буфера с камерой и получение пикселей сработало, это не очень эффективно при свете под определенным углом, и это чрезвычайно дорого в Unity. Ищу способ определить насколько освещен плеер через шейдер, правда я не программист и шейдеры никогда не трогал. Я искал несколько месяцев, но не нашел значения, и все просто используют триггеры, которые не действуют в этой игре. Я пытаюсь сделать что-то похожее на игры Thief2 или Splinter Cell. Я знаю о raycasts, однако они недостаточно точны.

Итак, как мне определить, насколько освещен плеер, чтобы получить соответствующий градиент?

Вот код, который я пока использую для сбора света.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ShadowBufferScript : MonoBehaviour {

    public RenderTexture shadowBuffer;
    Texture2D tex2d;
    public float percentageHidden;
    public float relativeLuminance;

    void Start()
    {   
        tex2d = new Texture2D (shadowBuffer.width, shadowBuffer.height, TextureFormat.RGB24, false);
    }


    void FixedUpdate () 
    {
        tex2d = new Texture2D (shadowBuffer.width, shadowBuffer.height, TextureFormat.RGB24, false);
        RenderTexture.active = shadowBuffer;
        tex2d.ReadPixels (new Rect (0, 0, shadowBuffer.width, shadowBuffer.height), 0, 0);  
        tex2d.Apply ();

        Color shadowBufferColor = tex2d.GetPixel (0, 0);
        relativeLuminance = shadowBufferColor.r * 0.2126f + shadowBufferColor.g * 0.7152f + shadowBufferColor.b * 0.0722f;

        percentageHidden = relativeLuminance * 100;

    }
}

person Umbra    schedule 02.06.2018    source источник
comment
Можете ли вы предоставить конкретную строку кода, с которой вам нужна помощь?   -  person user1506104    schedule 02.06.2018
comment
@user1506104 user1506104 У меня нет конкретной строки кода, так как существующий код не подходит, так как загружает ЦП. Я ищу что-то новое, более точное, как в играх Thief 2 или Splinter Cell, чтобы определить, насколько освещен игрок, как это отображается на его экспонометрах в игре. Я уже сделал триггеры, рейкасты и getpixel, однако они либо неадекватны, либо слишком дороги. Я помещаю код, который я использую, чтобы собрать огни в моем вопросе.   -  person Umbra    schedule 02.06.2018
comment
Я думаю, что этот пост должен помочь вам с несколькими альтернативами answers.unity.com/questions/24662/   -  person    schedule 02.06.2018
comment
@AdrianSgro Я видел этот пост раньше, и мы действительно сделали то, что они там сделали. Volumes и Raycasts недостаточно точны, а RenderTexture чертовски дорог для процессора. Мне сказали, что шейдер может работать, однако, пока я исследовал шейдеры, я не могу найти значение, чтобы сказать мне, насколько освещен ваш персонаж. :(   -  person Umbra    schedule 02.06.2018


Ответы (1)


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

// Collision functions based on correct layering (Player/LightingZones)
[RequireComponent(typeof(Collider))]
public class LightingCalculator : MonoBehaviour
{
    private bool _entered = false;

    private void Update()
    {
        if (_entered) FindObjectOfType<PlayerController>().LightingValue = CalculateLighting();
    }

    private void OnCollisionEnter(Collision col)
    {
        _entered = true;
    }

    private void OnCollisionExit(Collision col)
    {
        _entered = false;
    }

    private float CalculateLighting()
    {
        float lighting = 0;
        // Your calculation
        return lighting;
    }
}
person Leon Willens    schedule 02.06.2018
comment
А, триггеры — это зоны столкновений в Unity. Я использовал триггеры для своего прототипа, и хотя получить градиент можно, и его было очень легко добавить в игру, настройка формы каждого триггера стала бесконечной рутиной на маленьком уровне, особенно в очень больших комнатах, поэтому я хотел что-то, что был на самом плеере. Мне предложили что-то в шейдере, может помочь. Некоторое значение, которое меняется в зависимости от попадания света на объект, но я не нашел ничего подобного в Unity. :( - person Umbra; 02.06.2018
comment
Я тоже не видел такой функции в Unity. Основное мышление относительно взаимодействия между GameObjects в значительной степени зависит от триггеров и столкновений (триггер — это просто столкновение без физического расчета, что было бы идеально для этого варианта использования, если бы у вас не было такого беспорядка. Я полагаю, вы работаете с направленным Как насчет того, чтобы просто применить триггерный коллайдер в форме конуса и просто проверить отбрасывание теней? - person Leon Willens; 03.06.2018
comment
На самом деле я использую прожекторы и точечные светильники. Да, я несколько месяцев искал эту функцию, и единственный другой вариант, о котором я слышал, — это шейдеры. Немного изучив шейдеры, я не нашел ничего, что указывало бы на наличие переменной, доступной через скрипт, чтобы определить, сколько света падает на нее или как цвет меняется от самого темного к самому светлому. У меня есть несколько решений, но ни одно из них меня не особенно волнует. Одно из решений состоит в том, чтобы иметь несколько слоев триггеров/объемов с различными значениями для получения нужного мне градиента. - person Umbra; 03.06.2018
comment
Или, судя по тому, что я вижу в сцене, шейдер становится темнее в тени (я никогда не писал шейдер, пожалуйста, позаботьтесь обо мне), так что же это за переменная, которая влияет на то, что объект становится темнее в тени в шейдере ( если он даже внутри шейдера. Опять же, я не знаю). - person Umbra; 04.06.2018