2013-03-11 2 views
0

как обычно заблаговременно ..Pixel bender нормальная карта

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

void 
evaluatePixel() 
{ 
    float2 pt = outCoord(); 

    pixel3 a = sampleNearest(src,pt); 
    pixel3 b = sampleNearest(src,float2(pt.x + 1.0, pt.y)); 
    pixel3 c = sampleNearest(src,float2(pt.x, pt.y + 1.0)); 

    float3 v1 = float3(1.0, 0.0, b.r - a.r); 
    float3 v2 = float3(0.0, 1.0, c.r - a.r); 

    normalize(v1); 
    normalize(v2); 

    float3 n = cross(v1,v2); 

    dst = pixel3(n.x,n.y,n.z); 
} 

Я ожидаю, что это создаст нормальную карту. Чтобы проверить, я предположил, что свет указывал прямо вниз и просто использовал n.z в качестве выходного цвета. Это создает сплошной цвет. Если вы возьмете приведенный выше код и запустите его, вы увидите, что, хотя есть различия в красном и зеленом, синий всегда заполняется 255. Почему это? Я ожидаю, что с учетом v1 и v2 нормализуется то, что это не должно всегда выводить полный синий цвет?

Что я делаю неправильно?!?

+0

делает это [это] (http://www.adobe.com/cfusion/exchange/index.cfm?event=extensionDetail&extid=1817528) помощь? –

+0

спасибо, было хорошо читать и интересно посмотреть, как этот парень это сделал; однако изображение, которое он создает, по-прежнему имеет полный синий цвет (или z = 1,0 в нормальном режиме). Поскольку 'v1' и' v2' являются единичными векторами, я бы ожидал, что 'n' будет единичным вектором и что где угодно" v1.z' или 'v2.z' arn't zero,' nz' не должно быть 1? Что мне здесь не хватает? – Pez

ответ

0

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

input image3 verts; 
output pixel3 triNorms; 

void 
evaluatePixel() 
{ 
    float2 tCoord = outCoord() - 0.5; //move coord from pixel center to lower-left corner 
    float quadIdx = mod(tCoord[0], 2.0); //potentially faster to use sign(fract(tCoord[0]/2.0)) 
    float2 vCoord0 = float2(floor(tCoord.x/2.0), tCoord.y); 
    float2 vCoord1 = float2(vCoord0.x + 1.0, vCoord0.y + 1.0 - quadIdx); 
    float2 vCoord2 = float2(vCoord0.x + quadIdx, vCoord0.y + 1.0); 
    float3 v0 = sampleNearest(verts, vCoord0 + 0.5); 
    float3 v1 = sampleNearest(verts, vCoord1 + 0.5); 
    float3 v2 = sampleNearest(verts, vCoord2 + 0.5); 
    float3 s0 = v1 - v0; 
    float3 s1 = v2 - v0; 
    float3 n = cross(s0, s1); 
    float len = 1.0/length(n); 
    n.x *= len; 
    n.y *= len; 
    n.z *= len; 
    triNorms = float3(n.x, n.y, n.z); 
} 

Это работает удивительно хорошо для меня. Проходит через вершины 1.8M менее чем за 100 мс. Чтобы уточнить, я определяю свои треугольники как столбцы между вершинами. Это означает, что для каждых 4 вершин есть два треугольника. Я отождествляю два треугольника на квадрат с «quadIdx».

Примечание: Вы нормализуете и затем вычисляете крест - это назад, вам нужно нормализовать его после. Кроме того, я действительно считаю, что нашел ошибку в normalize(). Это создавало NaN, где я не ожидал. Я выполнил свою собственную нормализацию с длиной(), и все это отлично работает!

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