|
Xors3D Графический движок с поддержкой DirectX9 |
08.05.2012, 23:52
|
#1
|
Знающий
Регистрация: 29.11.2010
Сообщений: 244
Написано 31 полезных сообщений (для 49 пользователей)
|
Шейдеры + частицы
Хочу слепить системку частиц с возможностью применения им шейдера - хочухочухочу!!!))) Я нуб, ламерюга и все такое - но желаю просветится и проникнуться знаниями о великих гуру
Изза брака знаний Я столкнулся с такой проблемой:
Судари: подскажите, объясните, расскажите - где у нас тут координата 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 но полностью белый квадратик показал мне фак...
ЗЫ: Я знаю что уже задал вопрос этот тут и изначальний тут - безрезультатно, поэтому создал тему - более заметная хрень))) Предлагаю модераторам удалить эти два вышеуказанных сообщения
С уважением и большой как вселенная надеждой, Аник
__________________
Intel Core i3-4005U (1.7 ГГц), 4 ГБ ОЗУ, nVidia GeForce 940M 4 ГБ, Win8.1
|
(Offline)
|
|
09.05.2012, 02:47
|
#2
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Шейдеры + частицы
Сообщение от ANIK123
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;
}
И типа все должно сработать. Если память мне не изменяет, а она может
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо dsd за это полезное сообщение:
|
|
09.05.2012, 07:48
|
#3
|
Знающий
Регистрация: 29.11.2010
Сообщений: 244
Написано 31 полезных сообщений (для 49 пользователей)
|
Ответ: Шейдеры + частицы
Ух ты, КАКОЙ ответ!) Аж любо смотреть - так все разжевано и развернуто!))) Эхх, если б так Все делали... Спасибо тебе, добрый человек!)
Все заработало как часики швейЦарские) Правда с пропорциями квада чтото не то - какой-то сплющенный он получился
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! НУ ЛАДНО, думаю мож надо передать каким-то макаром адрес массива в целочисленном виде - фиг тебе! - сказала студия и Я остался сам на сам с чистым недоумением - чяднт?
ЗЫ: почему ты в выходной структуре вершинного шейдера семантику цвета определил как тексКоординаты?
__________________
Intel Core i3-4005U (1.7 ГГц), 4 ГБ ОЗУ, nVidia GeForce 940M 4 ГБ, Win8.1
Последний раз редактировалось ANIK123, 09.05.2012 в 09:30.
|
(Offline)
|
|
09.05.2012, 14:36
|
#4
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Шейдеры + частицы
Да пожалста.
Сообщение от ANIK123
Все заработало как часики швейЦарские) Правда с пропорциями квада чтото не то - какой-то сплющенный он получился
|
Это потому что у тебя экран не квадратный, оно же после умножения на матрицу проекционную уже в экранные координаты переводит. А вообще сначала надо умножить на мировую и видовую, это приведет вершину в локальные координаты камеры, затем добавить сильно упростившиеся смещения и потом полученную координату умножить на проекционную матрицу, которая переведет уже вершину в координаты на плоскости экрана, на которой рисует пиксельный. То есть либо смещения делать по пропорциям экрана и иметь еще глюк что дальняя частица равна по размеру ближней или таки слегка усложнить вершинный. Это я протупил давно в шейдерах не ковырялся.
А насчет координат это потому что пиксельный вроде принимает на вход координаты точки в пространстве, её нормаль и её текстурные координаты и все То есть если из вершинного надо много передать в пиксельный то в основном это через текстурные координаты делается, их много слоев можно, вроде. Мне хватало.
А на счет 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 в глубину
Координаты там от центра экрана меряются причем единицы соответствуют углам изображения. Какая-то магия матриц
Причем z изменяется от 0 до 1, где ноль будет соответствовать ближней плоскости отсечения вида камеры, а 1 дальней.
ЗЫ вот еще по частицам что в шагах есть может полезно будет
В качестве результата своей работы, вершинные шейдер помет возвращать сле-дующие данные:
POSITION0 – трансформированная позиция вершины.
COLOR[n] – значение цвета, стоит отметить, что записывать именно цвет сюда вовсе необязательно, например, в случае если необходимо передать в пиксельный шейдер позицию, ее спокойно можно поместить в любое поле с семантикой COLOR или TEXCOORD.
TEXCOORD[n] – текстурные координаты. Не обязательно float2 зна-чение, может быть любым в зависимости от ваших нужд (например, для передачи нормали можно использовать float3).
FOG – float значения тумана для данной вершины.
PSIZE – размер точки. Действует только на точечные спрайты (системы частиц).
Например, если нам необходимо рассчитать попиксельное освещение в шейдере, структура выходных данных может быть следующей:
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо dsd за это полезное сообщение:
|
|
09.05.2012, 16:51
|
#5
|
Знающий
Регистрация: 29.11.2010
Сообщений: 244
Написано 31 полезных сообщений (для 49 пользователей)
|
Ответ: Шейдеры + частицы
Супер, все работает отлично!)
В дальнейшем буду частенько заходить сюда на твой пост поглядеть, почитать))) (см твой пост немного обрезало чтоли)
Осталось только одно нерешенное западло: в доке ксорса есть функция:
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
)
С таким Я точно не ознакомлен, а данные передать то надо О_О
__________________
Intel Core i3-4005U (1.7 ГГц), 4 ГБ ОЗУ, nVidia GeForce 940M 4 ГБ, Win8.1
|
(Offline)
|
|
09.05.2012, 17:18
|
#6
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Шейдеры + частицы
Сообщение от ANIK123
Супер, все работает отлично!)
В дальнейшем буду частенько заходить сюда на твой пост поглядеть, почитать))) (см твой пост немного обрезало чтоли)
Осталось только одно нерешенное западло: в доке ксорса есть функция:
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
)
С таким Я точно не ознакомлен, а данные передать то надо О_О
|
Мой пост целый просто когда копировал текст из шагов лишнюю строчку зацепил и не заметил. А с этим походу никак, можешь послать лучи добра счастливым юзерам блицобэйсика это из-за них у тебя ничего не получилось, а у них работает, хотя им эта функция нужна в стопицот раз реже.
|
(Offline)
|
|
12.05.2012, 23:01
|
#7
|
Знающий
Регистрация: 29.11.2010
Сообщений: 244
Написано 31 полезных сообщений (для 49 пользователей)
|
Ответ: Шейдеры + частицы
Грёбанная срань!!1
Добавил всего ОДНУ сраную строчку ( i.color.a -= ((100.0f - (i.color.a / 0.01f)) * 0.1) * i.binormal.z; ) в пиксельный шейдер частиц и производительность сразу упала с 60 до аж 40 фпс!!1
Знал бы что так будет - забил бы на эту тупую идею сразу!!!
Да и скорее всего не только поэтому - Я еще слишком туп - никак не ногу додуматься как поворачивать частицы - в мозговом вместилище какая-то какаша из матриц образуется - наверное пока стоит поговнокодить ИИ - чтоб уже наверняка забросить геймдейв
ЗЫ: извиняюсь, сегодня день тяжелый был, препятствие за препятствием и никакого прогресса - как с этим бороться чтоб не стать эмо или антигероем фильма ужасов?)
__________________
Intel Core i3-4005U (1.7 ГГц), 4 ГБ ОЗУ, nVidia GeForce 940M 4 ГБ, Win8.1
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
12.05.2012, 23:52
|
#8
|
Терабайт исходников
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений (для 6,051 пользователей)
|
Ответ: Шейдеры + частицы
ЗЫ: извиняюсь, сегодня день тяжелый был, препятствие за препятствием и никакого прогресса - как с этим бороться чтоб не стать эмо или антигероем фильма ужасов?)
|
у каждого такое было, не сдавайся и упорно пили.
приведенный тобой код шейдера очень простой, у тебя много частиц полупрозрачных друг поверх друга? сколько? какой эффект ты хочешь ими создать?
|
(Offline)
|
|
13.05.2012, 01:17
|
#9
|
Знающий
Регистрация: 29.11.2010
Сообщений: 244
Написано 31 полезных сообщений (для 49 пользователей)
|
Ответ: Шейдеры + частицы
В Моей "супер-архипупер-мего" игре задумано много чего взрывать - вот и надумал сделать какой-нить более-менее прикольный огонек - и тут в башню Мою влетела вышеописанная формула - где бинормаль это анимационное значение, желательно в диапазоне 0/1 - вроде работает как надо, но тормозно - жуть
Первые два скрина с роковой "строчкой", третий собсно уже без нее
Как видно из картинок, Я просто "контрастирую" альфу, и получается прикольный эффект - как будто это не одна частица летит, а несколько маленьких и разных)
__________________
Intel Core i3-4005U (1.7 ГГц), 4 ГБ ОЗУ, nVidia GeForce 940M 4 ГБ, Win8.1
Последний раз редактировалось ANIK123, 13.05.2012 в 02:39.
|
(Offline)
|
|
13.05.2012, 03:21
|
#10
|
Терабайт исходников
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений (для 6,051 пользователей)
|
Ответ: Шейдеры + частицы
частиц видимо дохера друг поверх друга, выходит что шейдер считается не 1 раз на каждый пиксель экрана а столько раз, сколько на этом пикселе загораживающих друг друга частиц.
так что видимо надо либо упрощать этот эффект и делать его из меньшего кол-ва частиц, либо рендерить его в лоуресе в отдельную текстуру (так например делали с брызгами воды в анчартеде последнем), либо... хз) что-нибудь ещё сымпровизировать. альфаблендовые поверхности нехило жрут фпс и в реальных играх, помню на gf8600 в MW1 вхождение полностью в дым от гранаты срезало фпс раза в 3-4.
|
(Offline)
|
|
13.05.2012, 05:40
|
#11
|
Знающий
Регистрация: 29.11.2010
Сообщений: 244
Написано 31 полезных сообщений (для 49 пользователей)
|
Ответ: Шейдеры + частицы
И при этом фильтрация стоит "попе"!
рендер в лоу-рес текстуру это идея не плохая ибо игра (по крайней мере в сегодняшней задумке) предполагается быть в низком разрешении (но с сглаживанием в 4х)(так "кинематографичнее") - т е как это сделать? иксРендерЭнтити насколько Я помню, да? И позиция в зд пространнстве сохранится (т е не будет рендерится поверх всех остальных энтити)? НО! - если игра будет в лоу-рес разрешении то и отпадает смысл в вышеописанном способе рендера частиц - тогда Все О"К)))
И вопрос: взгляните на код шейдера выше (плюс указания dsd) - ок, да?) - теперь составьте в уме "апдейт" - через бинормаль посылаю значение ротации - ОК - как повернуть спрайт? Можете ответить двумя вариантами:
1 - это элементарно! думай САМ, идиот!!1 (и Я потрачу кучу дней на самостоятельный поиск ответа (ёбанная работа, свободного времени почти нету))
2 - описывается код или представляется он Сам, с комментариями, чтобы лашпёд АНИК123 все догнал и не доставал больше великих гуру деградатскими вопросами)))
И еще: часто бывают ошибки при компиляции, вызванные неправильно инициализируемыми входными параметрами функции/члена, вопрос к сверх опытным разработчикам: это связано с... ЧЕМ?!? Есть класс (кл0), есть в нем функция-х**, есть в Ней входной параметр: указатель на класс (кл1), содержащий хэндл - при попытке выполнить некое действие над этим хэндлом приводит к краху, хоть при загрузке самого хэндла (в кл1) все ОК, ибо возвращается не НОЛЬ (если есть более нормальные проверки - искренне прошу поделиться)
Не знаю связано ли это с вышеописанным, но: есть функция, есть входной параметр char[32], и - блин, это капец! - в нем "сидит" набор СОВСЕМ лёвых символов вместо передаваемых функции! С чем это может быть связано? (самое страшно то, что это возникло в коде который Я ранее написал - и он Работал! - теперь, вставив его, получилась такая вот жопа, хотя по Идее Все должно "пахать")
Я в тупике (собсно Я как раз изложил Все "жопы" которые сопутствували Меня в этот день (когда писал пост выше))
Как всегда, прошу помочь - ибо Я уже забрасывал проЭктЬ - как раз из за таких-вот мелочей - и тупо принимался писать Все с нуля
На этот раз Я не хочу так делать - если идти, то до конца, или в жопу мойсеева - первый исход событий Мне более по душе
Заранее спасибо, как всегда, Ваш АНИК 123)))))))
__________________
Intel Core i3-4005U (1.7 ГГц), 4 ГБ ОЗУ, nVidia GeForce 940M 4 ГБ, Win8.1
|
(Offline)
|
|
13.05.2012, 12:31
|
#12
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Шейдеры + частицы
А чем тебя sin и cos не устраивают? Смещения у тебя есть же. Вот и будет:
x'=x * cos a+y * sin a;
y'=-x * sin a+y * cos a;
Оно? Поворот осей называется.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
13.05.2012, 12:41
|
#13
|
Терабайт исходников
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений (для 6,051 пользователей)
|
Ответ: Шейдеры + частицы
передаёшь угол поворота спрайта в радианах, имея в VS позиции вертексов спрайта относительно центра спрайта (т.е. чтоб вместо центра спрайта был ноль), применяешь следующий код:
float c = cos(rotation);
float s = sin(rotation);
float4 rotationMatrix = float4(c, -s, s, c);
Position.xy = mul(Position.xy, float2x2(rotationMatrix));
---
пока писал, поста dsd не было, его вариант ничем не хуже.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
15.05.2012, 21:59
|
#14
|
Знающий
Регистрация: 29.11.2010
Сообщений: 244
Написано 31 полезных сообщений (для 49 пользователей)
|
Ответ: Шейдеры + частицы
как-то так получилось
правда весьма непроизводительно получилось
как можно оптимизировать?
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();
}
}
__________________
Intel Core i3-4005U (1.7 ГГц), 4 ГБ ОЗУ, nVidia GeForce 940M 4 ГБ, Win8.1
|
(Offline)
|
|
15.05.2012, 22:34
|
#15
|
Терабайт исходников
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений (для 6,051 пользователей)
|
Ответ: Шейдеры + частицы
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;
|
(Offline)
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 09:16.
|