Parallax Mapping
Для понимания данного термина, сначала ознакомьтесь с понятием Bump Mapping.
Описание
На рисунке изображен треугольник, на который вдоль видового вектора смотрит зритель, при этом видимой точкой bump’а будет - A. В реальности мы должны увидеть точку B, поэтому основная задача описываемого эффекта найти координаты точки B, т.е. получить новые текстурные координаты и использовать их как в случае с простым bump mapping’ом. Таким образом, более высокие участки (c высотой A) поверхности будут отдалятся от зрителя, в то время как близкие (с высотой B) будут приближаться, что и даст холмы.
A, B – высоты,
T0 – фактические координаты,
T1 – скорректированные координаты,
V – видовой вектор.
Для того что бы посчитать смещение необходимо три величины: фактические координаты, нормализованный видовой вектор и значение высоты.
Высота (на рисунке - A) с диапазоном {0,1} масштабируется множителем s и смещением b к диапазону, который лучше представляет физические свойства моделируемой поверхности. Как правильно выбирать коэффициенты?
Например, на поверхности размером MxN находится слой вещества толщиной K, тогда s = K/MxN и диапазон значений высоты равен {0,K/MxN}. Использование смещения b = - K/MxN, даст диапазон {K/MxN – 1, 0}. Среднее значение этих двух множителей дает наилучшее приближение: b/s=0.5; b=s*0.5f;
Значение новой высоты (B) равно:
Hn = h*s - b;
Смещение вычисляется трассировкой вектора, параллельного треугольнику от точки T0 к видовому вектору:
Offset=Hn*V.xy/V.z;
Но при малых углах смещение будет маленьким, т.е. Tn будет приближаться к T0, что даст эффект “размытости” поверхности. Самым простым решением этой проблемы является ограничение смещения не на больше чем на Hn:
Offset=Hn*V.xy;
Тогда искомые текстурные координаты равны:
Tn = T0 + Offset;
Полученные текстурные координаты используются для всех sampler’ов в пиксельном шейдере.
Пиксельный шейдер:
struct INPUT_STRUCT{ float2 T:TEXCOORD0; float3 L:TEXCOORD1; float3 H:TEXCOORD2; float3 V:TEXCOORD3; }; float4 main(INPUT_STRUCT IN):COLOR0 { //Получаем высоту из heightmap float b=scale*0.5f; float height= scale*tex2D( base_map, IN.T)-b; //Рассчитываем координаты этой высоты float2 Nt = IN.T + ( IN.V.xy)*height; float3 normal= tex2D( bump_map,Nt); normal = normalize( 2*( normal) - 1); float diffuse= dot( normal,IN.L); float spec= dot( normal,normalize( IN.H)); return ( diffuse+pow( spec,128))*tex2D( base_map,Nt); }
Вершинный шейдер:
struct INPUT_STRUCT { float4 P:POSITION; float3 N:NORMAL; float2 C:TEXCOORD0; float3 B:BINORMAL0; float3 T:TANGENT0; }; struct OUTPUT_STRUCT { float4 P:POSITION; float2 T:TEXCOORD0; float3 L:TEXCOORD1; float3 H:TEXCOORD2; float3 V:TEXCOORD3; }; OUTPUT_STRUCT main(INPUT_STRUCT IN){ OUTPUT_STRUCT OUT; OUT.P = mul( view_proj_matrix,IN.P); OUT.T = IN.C; float3 light_vector = light_position - IN.P; OUT.L.x = dot( light_vector,IN.T); OUT.L.y = dot( light_vector,IN.B); OUT.L.z = dot( light_vector,IN.N); OUT.L = normalize( OUT.L); float3 view_vector = view_position - IN.P; OUT.V.x = dot( view_vector,IN.T); OUT.V.y = dot( view_vector,IN.B); OUT.V.z = dot( view_vector,IN.N); OUT.V = normalize( OUT.V); OUT.H = normalize( OUT.L + OUT.V); return OUT; }
Ссылки
http://www.infiscape.com/doc/parallax_mapping.pdf
Что такое Parallax Mapping?
29 июля 2005 (Обновление: 28 фев 2012)