Как в шейдере анимировать одну отдельную конкретную вершину чтоб она постоянно двигалась "туда-сюда".
Красим вершины модели в чёрный цвет (RGB 000), выделяемцелевую вершину и красим её в красный.
внутри кода шейдера:
увеличиваем входную структуру на вектор цвета вершины
типа float3 VertexColor;
а затем в вертексном буфере ставим проверку вершинам на покраску
Цитироватьif (VertexColor.x > 0)
{
Pos=Pos+float3(sin(time),0,0);
}
где Pos - float3 позиция dt - float время
в таком случае наша красная вершина будет ходить туда-сюда
Sqwer спасибо огромное но немог бы ты выложить пример такого шейдера полностью!!!Чтобы не осталось вопросов :D :D :D
Думаю многим было бы интересно:
1. Красим вершины в 3D редакторе (в максе: в EditPoly пункт Vertex Properties или модификатор Vertex Paint). Одну в красный цвет, остальные - в черный.
2. Экспортируем в квест используя панду или квестовский экспортер
3. Подключаем HLSL Object канал и пишем код шейдера:
// матрица преобразования мирового пространства
float4x4 WorldVP : WorldViewProjection;
// Цепляем ValueVector через который будем двигать вершину по осям xyz
float3 movevector : CHANNELVALUE0 ;
// Определяем структуру исходящих данных
struct vertexOutput // Данные, которые мы передадим в вершинный шейдер
{
float4 HPosition : POSITION; // позиция вершины
float4 color : COLOR; // Цвет вершины
};
// Вершинный шейдер
vertexOutput VS(float4 position : POSITION, float4 vertcol : COLOR0) // Берем из 3D геометрии информацию о позиции вершин и их цвет
{
vertexOutput OUT;
OUT.HPosition = mul(position,WorldVP);// Модифицируем позиции вершин с учетом матрици мирового пространства
OUT.color = vertcol; // Передаем цвет вершин в шейдер
// Определяем условие, которое выполняется, если цвет вершины в компоненте .r больше нуля
if (vertcol.r > 0)
{
OUT.HPosition += float4(movevector,1); // Прибавим наш вектор
}
return OUT;
}
// Пиксельный шейдер
float4 PS(vertexOutput IN) : COLOR
{return IN.color;} // Красим пиксели в цвет вершин по данным из вершинного шейдера
// Техника
technique Main
{
pass p0
{
VertexShader = compile vs_2_0 VS();
PixelShader = compile ps_2_0 PS();
}
}
И все вроде бы ничего, но:
По осям x и y вершина двигается без проблем, а вот по z - ведет себя как то странно. В чем проблема?
Попробуй так ;)
// Матрицы
float4x4 WorldVP : WorldViewProjection; // Произведение мировой, видовой и проекционной матриц
float4x4 World : World; // Матрица мирового преобразования
float4x4 WorldIT : WorldInverseTranspose; // Инвертированная - транспонированная мир матрица
// Цепляем ValueVector через который будем двигать вершину по осям xyz
float3 movevector : CHANNELVALUE0 ;
// Входящие данные
struct a2v
{
float4 HPosition : POSITION; // позиция вершины
float4 color : COLOR; // Цвет вершины
};
// Исходящие данные
struct v2f
{
float4 HPosition : POSITION; // позиция вершины
float4 color : COLOR; // Цвет вершины
};
// Вершинный шейдер
v2f VS(a2v IN)
{
v2f OUT = (v2f)0; // Обнуление выходной структуры
OUT.HPosition = mul(IN.HPosition,WorldVP); // позиция в мировой системе координат
OUT.color = IN.color; // Передаем цвет вершин в шейдер
// Определяем условие, которое выполняется, если цвет вершины в компоненте .r больше нуля
if (IN.color.r > 0)
{
OUT.HPosition = IN.HPosition+float4(movevector,0); // Прибавим наш вектор
OUT.HPosition = mul(OUT.HPosition,WorldVP);
}
return OUT;
}
// Пиксельный шейдер
float4 PS(v2f IN) : COLOR
{
return IN.color;
}
// Техника
technique Main
{
pass p0
{
VertexShader = compile vs_2_0 VS();
PixelShader = compile ps_2_0 PS();
}
}
+ вариант, без IF, в котором интенсивность компоненты .r влияет на силу деформации
// Матрицы
float4x4 WorldVP : WorldViewProjection; // Произведение мировой, видовой и проекционной матриц
float4x4 World : World; // Матрица мирового преобразования
float4x4 WorldIT : WorldInverseTranspose; // Инвертированная - транспонированная мир матрица
// Цепляем ValueVector через который будем двигать вершину по осям xyz
float3 movevector : CHANNELVALUE0 ;
// Входящие данные
struct a2v
{
float4 HPosition : POSITION; // позиция вершины
float4 color : COLOR; // Цвет вершины
};
// Исходящие данные
struct v2f
{
float4 HPosition : POSITION; // позиция вершины
float4 color : COLOR; // Цвет вершины
};
// Вершинный шейдер
v2f VS(a2v IN)
{
v2f OUT = (v2f)0; // Обнуление выходной структуры
OUT.color = IN.color; // Передаем цвет вершин в шейдер
float3 pos= mul(movevector,IN.color.r);
OUT.HPosition = IN.HPosition+float4(pos,0); // Прибавим наш вектор
OUT.HPosition = mul(OUT.HPosition,WorldVP);
return OUT;
}
// Пиксельный шейдер
float4 PS(v2f IN) : COLOR
{
return IN.color;
}
// Техника
technique Main
{
pass p0
{
VertexShader = compile vs_2_0 VS();
PixelShader = compile ps_2_0 PS();
}
}
еще один вариант, в котором вершины деформируются с учетом их нормалей
// Матрицы
float4x4 WorldVP : WorldViewProjection; // Произведение мировой, видовой и проекционной матриц
float4x4 World : World; // Матрица мирового преобразования
float4x4 WorldIT : WorldInverseTranspose; // Инвертированная - транспонированная мир матрица
float koef : CHANNELVALUE0 ; // сила деформации
// Входящие данные
struct a2v
{
float4 HPosition : POSITION; // позиция вершины
float3 normal : NORMAL; // Нормаль к поверхности
float4 color : COLOR; // Цвет вершины
};
// Исходящие данные
struct v2f
{
float4 HPosition : POSITION; // позиция вершины
float4 color : COLOR; // Цвет вершины
};
// Вершинный шейдер
v2f VS(a2v IN)
{
v2f OUT = (v2f)0; // Обнуление выходной структуры
OUT.color = IN.color; // Передаем цвет вершин в шейдер
float strength=mul(koef,IN.color.r);
float3 pos= mul(IN.normal,strength);
OUT.HPosition = IN.HPosition+float4(pos,0); // Прибавим наш вектор
OUT.HPosition = mul(OUT.HPosition,WorldVP);
return OUT;
}
// Пиксельный шейдер
float4 PS(v2f IN) : COLOR
{
return IN.color;
}
// Техника
technique Main
{
pass p0
{
VertexShader = compile vs_2_0 VS();
PixelShader = compile ps_2_0 PS();
}
}
Факт:
оказывается Квест не поддерживает альфу в vertexColor :-\
ума не приложу, почему разработчики так поступили, ведь в 3dsMax vertexColor полноценный. Экспортировал стандартным квестовым экспортером, возможно в нем проблема.