2012-01-31 2 views
5

Я андроид приложение, я хочу, чтобы вычислить нормаль поверхности depanding на другой вершине этой поверхности. Я не хочу делать это в «мастерской» программе, потому что это занимает много времени. На самом деле для каждой вершины я прохожу 4 поплавка массива для каждого vextex:Как получить доступ к другой вершине в программе вершинного шейдера в opengl es 2?

attribute vec3 a_bottom; 
attribute vec3 a_left; 
attribute vec3 a_right; 
attribute vec3 a_top; 

vec3 calculNormal() { 
    return normalize(cross((a_left - a_right) , (a_bottom - a_top))); 
} 

очень очень очень грязный код я знаю, так что вместо передачи 4 массивов, я хочу сделать это:

vec3 calculNormal() { 
    vec3 a_left = CURRENT_FLOATBUFFER[ CURRENT_FLOAT_BUFFER_POSITION - 1 ]; 
    vec3 a_bottom = CURRENT_FLOATBUFFER[ CURRENT_FLOAT_BUFFER_POSITION - X ]; 
    ... 
    return normalize(cross((a_left - a_right) , (a_bottom - a_top))); 
} 

Так возможно ли в программе вершинного шейдера перейти к текущему буферу с плавающей точкой? Существуют ли специальные ключевые слова, например currentFloat? Или есть еще одна возможность, которую я пропустил?

ответ

8

Это действительно невозможно. Вершинный шейдер имеет доступ только к обрабатываемой вершине и ее атрибутам. И поскольку OpenGL ES не имеет расширения texture_buffer_object, вы не можете получить доступ к данным VBO внутри шейдера. Таким образом, единственный способ доступа к соседи вершин - это явно вставить их в атрибуты вершин, как в первом примере.

Но поскольку это похоже на то, что ваша геометрия представляет собой прямоугольный узор, вы также можете сохранить его в текстуре (или скопировать его в один, расширение pixel_buffer_object может помочь с этим, если оно поддерживается в ES). В этом случае вы можете просто использовать классический шейдер GPGPU-фрагмента, который вычисляет нормали для каждого «пикселя» (в данном случае вершины) выходного изображения (в данном случае нормальных данных прямоугольной геометрии) на основе значений его соседи (доступ к которым осуществляется простым доступом к тексту).

Но я не думаю, что ни одно, ни второе не сделают вас ничем, учитывая дополнительные операции надстройки и/или операции копирования памяти, поскольку вычисление вершинных нормалей уже довольно быстро. Вам не нужно делать это в любом кадре, и если вы действительно это делаете, то это потому, что вы также обновляете свои позиции вершин, и в этом случае вы можете использовать ту же самую процедуру обновления для обычных данных (будь то CPU или GPGPU).

4

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

Неправильный подход. Вычислите нормали и сохраните их вместе с вершинами.

Я не хочу делать это в программе «master», потому что это занимает много времени.

Вы не должны пересчитывать нормали для каждого прохождения рендеринга. Просто вычислите их и сохраните. Вычисления в вершинном шейдере не являются бесплатными. И вычисление нормалей в ВС - это просто отходы вычислительной мощности.

Рассчитать их, сохранить их.

+0

Hi datenwolf. Что делать, если я хочу создать карту высот после создания объекта во время выполнения? Должен ли я запускать его через шейдер, чтобы пробовать карту высот, преобразовывать вершины, отправлять их обратно, а затем загружать еще один VBO? Я не думаю, что выборка текстуры на процессоре - это действительно так, ну, с одной стороны, текстура была загружена с помощью glTexImage, а у CPU ее нет. – Zebrafish

+1

@TitoneMaurice: Первоначальный вопрос касался общих сеток. Но карты высот - это особый случай, когда нормаль поверхности можно вычислить с помощью свертки с правым ядром (дискретная разность, ака градиентное ядро). Используя 'textureGather' (GLSL-4 и более поздние версии), вы можете выбрать сетку 2х2 текселей, что вам и нужно.Однако я по-прежнему рекомендую предварительное вычисление нормалей, что дает вам то, что эффективно является * нормальной картой * для текстуры. – datenwolf

+1

@TitoneMaurice: Идея приложения: Создайте карту высот с высоким разрешением, создайте нормальную карту из нее, используйте нормальную карту полного разрешения (в шейдере фрагмента) для расчета освещенности и уменьшенную высоту карты для смещения вершин. Дальнейшая идея: вы можете сохранить высоту с нормальной разрешающей способностью и получить доступ к нижнему разрешению LoD на этапе вершины, а в шейдере фрагмента использовать разницу между полным разрешением и значением высоты вершины в качестве входных данных для отображения параллакса для повышения качества изображения. – datenwolf

Смежные вопросы