ПрограммированиеТерминыГрафика

Parallax Mapping

Для понимания данного термина, сначала ознакомьтесь с понятием Bump Mapping.

Описание
Ссылки

Описание

На рисунке изображен треугольник, на который вдоль видового вектора смотрит зритель, при этом видимой точкой bump’а будет - A. В реальности мы должны увидеть точку B, поэтому основная задача описываемого эффекта найти координаты точки B, т.е. получить новые текстурные координаты и использовать их как в случае с простым bump mapping’ом. Таким образом, более высокие участки (c высотой A) поверхности будут отдалятся от зрителя, в то время как близкие (с высотой B) будут приближаться, что и даст холмы.
pm | Parallax Mapping
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)

Комментарии [15]