Как эффективно подсчитать количество пикселей, которые можно увидеть с определенной точки зрения в MonoGame, если эти пиксели имеют определенный цвет - PullRequest
0 голосов
/ 09 февраля 2020

У меня есть проект на моногамной платформе. Целью проекта является расчет коэффициента обзора геометрии, введенного в платформу, с использованием метода ortographi c. На уровне базового c я поставил кубический элемент c и камеру напротив куба. Здесь, когда я смотрю в куб через камеру, мне необходимо подсчитать количество пикселей объекта, видимого в перспективе методом ortographi c. У меня уже есть решение, но оно очень медленное. В моем решении я считаю количество пикселей определенного цвета, а затем делю это число на общее количество пикселей на экране. Я слышал о технике, которая включает использование OcclusionQuery. Но я полагаю, что мне нужно заняться программированием шейдеров, чтобы использовать эту технику, о которой я понятия не имею. Ребята, можете ли вы дать несколько советов, если есть другой метод, который легче реализовать и работает быстрее, чем тот, который я недавно делал, или объяснить, как работает этот OcclusionQuery. Здесь, например, я считаю общее количество серых пикселей, а затем делю его на общий экран площадь

здесь вы можете найти мой код, написанный ниже;

    private void CalculateViewFactor(Color[] data)
    {
        int objectPixelCount = 0;
        var color = new Color();
        color.R = data[0].R;
        color.G = data[0].G;
        color.B = data[0].B;
        foreach (Color item in data)
            if (item.R != color.R && item.G != color.G && item.B != color.B)
                objectPixelCount++;

        Console.WriteLine(objectPixelCount);
        Console.WriteLine(data.Length);
        Console.WriteLine( (float) objectPixelCount / data.Length);
    }

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

1 Ответ

1 голос
/ 09 февраля 2020

Это довольно сложно сделать правильно, и я могу только предложить «альтернативный», не обязательно более производительный или более продуманный подход.

В случае, если вам действительно не нужно знать точное число нарисованных пикселей, вы можете приблизить его. Существует методика, называемая Интеграция Монте-Карло .

. Начните с создания N точек на экране со случайными координатами. Вы проверяете и подсчитываете цвета в этих точках. Разделите количество точек с цветом вашего объекта на общее количество протестированных точек (то есть N ). Вы получите примерное соотношение пикселей, которое ваш объект занимает на последнем экране. Если теперь вы умножите это соотношение на общее количество пикселей на экране (то есть WidthPx * HeightPx ), вы получите приблизительное количество пикселей занятых по объекту.

enter image description here

Преимущества:

  • Выберите большее N для более точного результата, выберите меньшее N для лучшей производительности
  • Алгоритм прост, сложнее его испортить

Недостатки:

  • Это случайно и никогда не детерминирован c (каждый раз вы получите другой результат)
  • Это приблизительный и никогда не точный
  • Вам потребуется сгенерировать 2 * N случайные значения (два для каждой из контрольных точек), генерация случайных значений - это длинная операция
  • Я уверен, что позже вы захотите нарисовать текстуры / штриховки на экране, и тогда эта техника не будет работать, так как вы не сможете различить guish пикселей вашего объекта и других. Вы можете все Вы будете управлять меньшим невидимым буфером, в котором вы будете рисовать те же объекты, но без затенения, и каждый объект будет иметь одинаковый уникальный цвет, тогда вы примените к нему алгоритм Монте-Карло, но, конечно, это будет стоить вычислительных ресурсов.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...