forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Xors3D (http://forum.boolean.name/forumdisplay.php?f=126)
-   -   Шейдеры + частицы (http://forum.boolean.name/showthread.php?t=16765)

ANIK123 08.05.2012 23:52

Шейдеры + частицы
 
Хочу слепить системку частиц с возможностью применения им шейдера - хочухочухочу!!!))) Я нуб, ламерюга и все такое - но желаю просветится и проникнуться знаниями о великих гуру :download:

Изза брака знаний Я столкнулся с такой проблемой:
Судари: подскажите, объясните, расскажите - где у нас тут координата w подевалась то, ааа?)

не шейдер,ефикс
Код:

        Handle mesh = xCreateMesh();
        Handle surface = xCreateSurface(mesh);

        Handle vertex0 = xAddVertex (surface, 0, 0, 0, 0, 0, 0);
        Handle vertex1 = xAddVertex (surface, 1, 0, 0, 1, 0, 0.25f);
        Handle vertex2 = xAddVertex (surface, 0, 0, 1, 0, 1, 0.50f);
        Handle vertex3 = xAddVertex (surface, 1, 0, 1, 1, 1, 0.75f);

        Handle tri0 = xAddTriangle (surface, vertex0, vertex2, vertex1);
        Handle tri1 = xAddTriangle (surface, vertex3, vertex1, vertex2);

        Handle pss = xLoadFXFile("shaders/particles_def.fx");
        xSetEntityEffect(mesh, pss);

не исходник,срр
Код:

struct vsi
{
        float4 position : POSITION;
        float4 texCoords : TEXCOORD;
        float4 color : COLOR;
};


vsi VS(vsi i)
{
        i.position = mul(i.position, viewProj);
        i.color.rgb = i.texCoords.z;
        return i;
}

Результат работы вышеуказанного набора символов представляет Нам полик - ВНИМАНИЕ! - полностью черный!!! Ах. какая досада. С координатой v или u все играет
вопрос: где же ты, w, кто тебя обидел?!?
Стандартное заранее спасибо. За ответ или за найденную w - возможно вознаграждение:-)

UPD: как словить в шейдере цвет вертекса заданного через иксВертексКолор? Думал что с помощью COLOR_DIFFUSE но полностью белый квадратик показал мне фак...

ЗЫ: Я знаю что уже задал вопрос этот тут и изначальний тут - безрезультатно, поэтому создал тему - более заметная хрень))) Предлагаю модераторам удалить эти два вышеуказанных сообщения
С уважением и большой как вселенная надеждой, Аник

dsd 09.05.2012 02:47

Ответ: Шейдеры + частицы
 
Цитата:

Сообщение от ANIK123 (Сообщение 227567)
UPD: как словить в шейдере цвет вертекса заданного через иксВертексКолор? Думал что с помощью COLOR_DIFFUSE но полностью белый квадратик показал мне фак...

struct VSInput
{
float4 position : POSITION;
float3 normal : NORMAL;
float4 color : COLOR;
float2 texCoords0 : TEXCOORD0;
};
Вот там где красненькое цвет вершины автоматически подставится с такой семантикой

struct VSOutput
{
float4 position : POSITION;
float3 normal : TEXCOORD1;
float2 texCoords : TEXCOORD0;
float4 color : TEXCOORD2;
};

Дальше вершинный шейдер, который должен развернуть квад лицом к камере.

Если
output.position = mul(input.position, matrixWorldViewProj);
то в выводе лежит позиция центра квада, притом что после этой команды все сместилось относительно камеры, то есть весь мир в её локальных координатах стал, то прибавив вектор смещения от центра этой вершины ты получишь где эта вершина должна быть. для верхнего левого прибавляешь(-1,1,0) для верхнего правого (1,1,0), к нижнему левому (-1,-1,0) к четвертому (1,-1,0). Отличить вершины легко по текстурным координатам и выбрать соответствующее смещение.

дальше передаешь цвет в вывод вершинного, который ввод пиксельного
output.color = input.color;

Потом идет пиксельный шейдер, который рисует на экран
float4 PSMain(VSOutput input) : COLOR0
{
return input.color;
}

И типа все должно сработать. Если память мне не изменяет, а она может :)

ANIK123 09.05.2012 07:48

Ответ: Шейдеры + частицы
 
Ух ты, КАКОЙ ответ!) Аж любо смотреть - так все разжевано и развернуто!))) Эхх, если б так Все делали... Спасибо тебе, добрый человек!)

Все заработало как часики швейЦарские) Правда с пропорциями квада чтото не то - какой-то сплющенный он получился

Код:

struct vsi
{
        float4 position : POSITION;
        float3 texCoords : TEXCOORD0;
        float4 color : COLOR;
};

struct vso
{
        float4 color : TEXCOORD1;
        float4 position : POSITION;
};

vso VS(vsi i)
{
        vso o;
        o.position = mul(i.position, viewProj);
        if (i.texCoords.x > 0){o.position.x += 1.0f;} else{o.position.x -= 1.0f;}
        if (i.texCoords.y > 0){o.position.y += 1.0f;} else{o.position.y -= 1.0f;}
        o.color = i.color;
        return o;
}

float4 PS(vso vo) : COLOR0
{
        return vo.color;
}

А на счет w-координаты есть инфа? Или как еще можно идентифицировать каждую частицу в шейдере?

И еще вопрос: есть функции для передачи в шейдер инфу всякую, ОК. Беру из документации одну такую, и тут компилятор как заорет! Грит, Я положил свой массив туда где якобы должен быть хэндл. Ну ладно - смотрю входные параметры этой функции а там - И вправду нужен какой-то Handle value! НУ ЛАДНО, думаю мож надо передать каким-то макаром адрес массива в целочисленном виде - фиг тебе! - сказала студия и Я остался сам на сам с чистым недоумением - чяднт?

ЗЫ: почему ты в выходной структуре вершинного шейдера семантику цвета определил как тексКоординаты?

dsd 09.05.2012 14:36

Ответ: Шейдеры + частицы
 
Да пожалста.

Цитата:

Сообщение от ANIK123 (Сообщение 227577)
Все заработало как часики швейЦарские) Правда с пропорциями квада чтото не то - какой-то сплющенный он получился

Это потому что у тебя экран не квадратный, оно же после умножения на матрицу проекционную уже в экранные координаты переводит. А вообще сначала надо умножить на мировую и видовую, это приведет вершину в локальные координаты камеры, затем добавить сильно упростившиеся смещения и потом полученную координату умножить на проекционную матрицу, которая переведет уже вершину в координаты на плоскости экрана, на которой рисует пиксельный. То есть либо смещения делать по пропорциям экрана и иметь еще глюк что дальняя частица равна по размеру ближней или таки слегка усложнить вершинный. Это я протупил давно в шейдерах не ковырялся.

А насчет координат это потому что пиксельный вроде принимает на вход координаты точки в пространстве, её нормаль и её текстурные координаты и все :) То есть если из вершинного надо много передать в пиксельный то в основном это через текстурные координаты делается, их много слоев можно, вроде. Мне хватало.

Цитата:

А на счет w-координаты есть инфа? Или как еще можно идентифицировать каждую частицу в шейдере?
....
ЗЫ: почему ты в выходной структуре вершинного шейдера семантику цвета определил как тексКоординаты?
Ну это третья текстурная координата, типа и текстура должна быть три-дэ. А идентифицировать в хорсе никак. То есть для вершинного шейдера все вершины одинаковые. Но
struct VSInput
{
float4 position : POSITION;
float4 blendWeights : BLENDWEIGHT;
float4 blendIndices : BLENDINDICES;
float3 normal : NORMAL;
float4 color : COLOR;
float2 texCoords0 : TEXCOORD0;
float2 texCoords1 : TEXCOORD1;
float3 binormal : BINORMAL;
float3 tangent : TANGENT;
}; Вот допустимые семантики для данных для вершины к которым ты имеешь доступ из хорса, куда ты можешь засунуть те данные, которые позволят их различить в вершинном.

Плюс еще в хорсе есть тайные семантики, которых нет в документации, но которые радикально могут облегчить жизнь :)

Плюс вот еще что полезно может быть:

В пиксельном у тебя есть координата точки на экране в виде x.y.z.w
x/w координаты по высоте экрана, y/w по ширине, а z/w в глубину
Координаты там от центра экрана меряются причем единицы соответствуют углам изображения. Какая-то магия матриц:-D

Причем z изменяется от 0 до 1, где ноль будет соответствовать ближней плоскости отсечения вида камеры, а 1 дальней.

ЗЫ вот еще по частицам что в шагах есть может полезно будет
В качестве результата своей работы, вершинные шейдер помет возвращать сле-дующие данные:
��
POSITION0 – трансформированная позиция вершины.
��
COLOR[n] – значение цвета, стоит отметить, что записывать именно цвет сюда вовсе необязательно, например, в случае если необходимо передать в пиксельный шейдер позицию, ее спокойно можно поместить в любое поле с семантикой COLOR или TEXCOORD.
��
TEXCOORD[n] – текстурные координаты. Не обязательно float2 зна-чение, может быть любым в зависимости от ваших нужд (например, для передачи нормали можно использовать float3).
��
FOG – float значения тумана для данной вершины.
��
PSIZE – размер точки. Действует только на точечные спрайты (системы частиц).
Например, если нам необходимо рассчитать попиксельное освещение в шейдере, структура выходных данных может быть следующей:

ANIK123 09.05.2012 16:51

Ответ: Шейдеры + частицы
 
Супер, все работает отлично!)
В дальнейшем буду частенько заходить сюда на твой пост поглядеть, почитать))) (см твой пост немного обрезало чтоли)
Осталось только одно нерешенное западло: в доке ксорса есть функция:
Код:

void xSetEffectFloatArray  ( Entity *  entity, 
  const char *  name, 
  float *  value, 
  int  count, 
  int  layer = -1 
 )

А в студии она выглядит НЕМНОЖКО иначе:
Код:

void xSetEffectFloatArray  ( Entity *  entity, 
  const char *  name, 
  Handle  value, 
  int  count, 
  int  layer = -1 
 )

С таким Я точно не ознакомлен, а данные передать то надо О_О

dsd 09.05.2012 17:18

Ответ: Шейдеры + частицы
 
Цитата:

Сообщение от ANIK123 (Сообщение 227597)
Супер, все работает отлично!)
В дальнейшем буду частенько заходить сюда на твой пост поглядеть, почитать))) (см твой пост немного обрезало чтоли)
Осталось только одно нерешенное западло: в доке ксорса есть функция:
Код:

void xSetEffectFloatArray  ( Entity *  entity, 
  const char *  name, 
  float *  value, 
  int  count, 
  int  layer = -1 
 )

А в студии она выглядит НЕМНОЖКО иначе:
Код:

void xSetEffectFloatArray  ( Entity *  entity, 
  const char *  name, 
  Handle  value, 
  int  count, 
  int  layer = -1 
 )

С таким Я точно не ознакомлен, а данные передать то надо О_О

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

ANIK123 12.05.2012 23:01

Ответ: Шейдеры + частицы
 
Грёбанная срань!!1
Добавил всего ОДНУ сраную строчку (i.color.a -= ((100.0f - (i.color.a / 0.01f)) * 0.1) * i.binormal.z; ) в пиксельный шейдер частиц и производительность сразу упала с 60 до аж 40 фпс!!1
Знал бы что так будет - забил бы на эту тупую идею сразу!!!

Да и скорее всего не только поэтому - Я еще слишком туп - никак не ногу додуматься как поворачивать частицы - в мозговом вместилище какая-то какаша из матриц образуется - наверное пока стоит поговнокодить ИИ - чтоб уже наверняка забросить геймдейв
:)

ЗЫ: извиняюсь, сегодня день тяжелый был, препятствие за препятствием и никакого прогресса - как с этим бороться чтоб не стать эмо или антигероем фильма ужасов?)

Mr_F_ 12.05.2012 23:52

Ответ: Шейдеры + частицы
 
Цитата:

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

ANIK123 13.05.2012 01:17

Ответ: Шейдеры + частицы
 
В Моей "супер-архипупер-мего" игре задумано много чего взрывать - вот и надумал сделать какой-нить более-менее прикольный огонек - и тут в башню Мою влетела вышеописанная формула - где бинормаль это анимационное значение, желательно в диапазоне 0/1 - вроде работает как надо, но тормозно - жуть
Первые два скрина с роковой "строчкой", третий собсно уже без нее

Как видно из картинок, Я просто "контрастирую" альфу, и получается прикольный эффект - как будто это не одна частица летит, а несколько маленьких и разных)

Mr_F_ 13.05.2012 03:21

Ответ: Шейдеры + частицы
 
частиц видимо дохера друг поверх друга, выходит что шейдер считается не 1 раз на каждый пиксель экрана а столько раз, сколько на этом пикселе загораживающих друг друга частиц.
так что видимо надо либо упрощать этот эффект и делать его из меньшего кол-ва частиц, либо рендерить его в лоуресе в отдельную текстуру (так например делали с брызгами воды в анчартеде последнем), либо... хз) что-нибудь ещё сымпровизировать. альфаблендовые поверхности нехило жрут фпс и в реальных играх, помню на gf8600 в MW1 вхождение полностью в дым от гранаты срезало фпс раза в 3-4.

ANIK123 13.05.2012 05:40

Ответ: Шейдеры + частицы
 
И при этом фильтрация стоит "попе"!
рендер в лоу-рес текстуру это идея не плохая ибо игра (по крайней мере в сегодняшней задумке) предполагается быть в низком разрешении (но с сглаживанием в 4х)(так "кинематографичнее") - т е как это сделать? иксРендерЭнтити насколько Я помню, да? И позиция в зд пространнстве сохранится (т е не будет рендерится поверх всех остальных энтити)? НО! - если игра будет в лоу-рес разрешении то и отпадает смысл в вышеописанном способе рендера частиц - тогда Все О"К)))
И вопрос: взгляните на код шейдера выше (плюс указания dsd) - ок, да?) - теперь составьте в уме "апдейт" - через бинормаль посылаю значение ротации - ОК - как повернуть спрайт? Можете ответить двумя вариантами:
1 - это элементарно! думай САМ, идиот!!1 (и Я потрачу кучу дней на самостоятельный поиск ответа (ёбанная работа, свободного времени почти нету))
2 - описывается код или представляется он Сам, с комментариями, чтобы лашпёд АНИК123 все догнал и не доставал больше великих гуру деградатскими вопросами)))
И еще: часто бывают ошибки при компиляции, вызванные неправильно инициализируемыми входными параметрами функции/члена, вопрос к сверх опытным разработчикам: это связано с... ЧЕМ?!? Есть класс (кл0), есть в нем функция-х**, есть в Ней входной параметр: указатель на класс (кл1), содержащий хэндл - при попытке выполнить некое действие над этим хэндлом приводит к краху, хоть при загрузке самого хэндла (в кл1) все ОК, ибо возвращается не НОЛЬ (если есть более нормальные проверки - искренне прошу поделиться)
Не знаю связано ли это с вышеописанным, но: есть функция, есть входной параметр char[32], и - блин, это капец! - в нем "сидит" набор СОВСЕМ лёвых символов вместо передаваемых функции! С чем это может быть связано? (самое страшно то, что это возникло в коде который Я ранее написал - и он Работал! - теперь, вставив его, получилась такая вот жопа, хотя по Идее Все должно "пахать")
Я в тупике (собсно Я как раз изложил Все "жопы" которые сопутствували Меня в этот день (когда писал пост выше))
Как всегда, прошу помочь - ибо Я уже забрасывал проЭктЬ - как раз из за таких-вот мелочей - и тупо принимался писать Все с нуля
На этот раз Я не хочу так делать - если идти, то до конца, или в жопу мойсеева - первый исход событий Мне более по душе
Заранее спасибо, как всегда, Ваш АНИК 123)))))))

dsd 13.05.2012 12:31

Ответ: Шейдеры + частицы
 
А чем тебя sin и cos не устраивают? Смещения у тебя есть же. Вот и будет:
x'=x * cos a+y * sin a;
y'=-x * sin a+y * cos a;
Оно? Поворот осей называется.

Mr_F_ 13.05.2012 12:41

Ответ: Шейдеры + частицы
 
Цитата:

как повернуть спрайт
передаёшь угол поворота спрайта в радианах, имея в VS позиции вертексов спрайта относительно центра спрайта (т.е. чтоб вместо центра спрайта был ноль), применяешь следующий код:

float c = cos(rotation);
float s = sin(rotation);
float4 rotationMatrix = float4(c, -s, s, c);
Position.xy = mul(Position.xy, float2x2(rotationMatrix));
---
пока писал, поста dsd не было, его вариант ничем не хуже.

ANIK123 15.05.2012 21:59

Ответ: Шейдеры + частицы
 
как-то так получилось
правда весьма непроизводительно получилось
как можно оптимизировать?
Код:

float4x4 matWorld : MATRIX_WORLD;
float4x4 matView : MATRIX_VIEW;
float4x4 matProj : MATRIX_PROJ;

texture  diffuseTexture : TEXTURE_0;
sampler diffuse = sampler_state
{
  Texture = <diffuseTexture>; // привязываем текстуру
  // устанавливаем адресацию координат
AddressU      = WRAP;
AddressV      = WRAP;
AddressW      = WRAP;
// устанавливаем фильтрацию
MinFilter    = NONE;
MagFilter    = NONE;
MipFilter    = NONE;
// устанавливаем уровень фильтрации
MaxAnisotropy = 4;
};

struct vsi
{
        float4 position : POSITION;
        float3 texCoords : TEXCOORD;
        float4 color : COLOR;

        float3 binormal : BINORMAL;
};

struct vso
{
        float4 color : TEXCOORD1;
        float4 position : POSITION;
        float2 texCoords : COLOR;

        float3 binormal : TEXCOORD0;

};

vso VS(vsi i)
{
        vso o;
        //i.position = mul(i.position, matWorld);
        i.binormal.y /= 2.0f;
        i.position = mul(i.position, matView);

        o.position = (0, 0, 0, 0);
        if (i.texCoords.x > 0){o.position.x += i.binormal.y;} else{o.position.x -= i.binormal.y;}
        if (i.texCoords.y > 0){o.position.y += i.binormal.y;} else{o.position.y -= i.binormal.y;}
        float c = cos(i.binormal.x);
        float s = sin(i.binormal.x);
        float4 rotationMatrix = float4(c, -s, s, c);
        o.position.xy = mul(o.position.xy, float2x2(rotationMatrix));

        o.position = i.position + o.position;
        o.position = mul(o.position, matProj);
        o.color = i.color;
        o.texCoords = i.texCoords;
        o.binormal = i.binormal;
        return o;
}

float4 PS(vso i) : COLOR0
{
        float4 color = tex2D(diffuse, i.texCoords);

        i.color.a = (color.a / 0.01f) * (i.color.a / 100.0f); // анимационная прозрачность смешивается с альфой текстуры
        i.color.a -= ((100.0f - (i.color.a / 0.01f)) *  0.1) * i.binormal.z;

        //saturate(i.color.a);

        i.color.rgb = color.rgb;

        return i.color;
}

// техника для отрисовки
technique MainTechnique
{
  pass p0
 {
  AlphaBlendEnable = true;
  VertexShader = compile vs_3_0 VS();
  PixelShader = compile ps_3_0 PS();
 }
}


Mr_F_ 15.05.2012 22:34

Ответ: Шейдеры + частицы
 
Цитата:

o.position = (0, 0, 0, 0);
if (i.texCoords.x > 0){o.position.x += i.binormal.y;} else{o.position.x -= i.binormal.y;}
if (i.texCoords.y > 0){o.position.y += i.binormal.y;} else{o.position.y -= i.binormal.y;}
бранчинг (ифы) медленная штука, а в шейдерах очень медленная.
может как-то так?
o.position.xy += sign(i.texCoords.xy) * i.binormal.xy;


Часовой пояс GMT +4, время: 11:10.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot