@Ignatus
Ad. 1. cytując z dokumentacji w skrypcie: id - identyfikator przebiegu renderowania (czyli jakaś nazwa po prostu);
view_index - numer viewa, do którego należeć będzie ten przebieg. Działa to tak, że jeśli dasz -1 to pass będzie renderował się dla każdego viewa, czyli będzie zapisywał informacje do swego surface ze wszystkich viewów, ale jeśli podasz np. 0 to będzie zapisywał informacje o obiektach renderowanych wyłącznie w view[0].
clear_color - kolor, jakim wypełni się surface zanim zacznie zbierać informacje o obiektach. stosuje się to po to, by wyczyścić surface.
clear_alpha - alpha, jaką wypełni się surface zanim zacznie zbierać informacje o obiektach. stosuje się to po to, by wyczyścić surface.
target - id obiektu lub obiektów, które mają być brane pod uwagę przy zapisie do surface przebiegu. możesz podać id konkretnego obiektu, grupy obiektów (np. obj_fire, stała all, czy parenty różnych obiektów - obj_dirt)
Ad. 2. patrząc na listę dodawanych passów, mamy kolejno:
multipass_add("dirt_mask", 0, c_black, 0, obj_dirty);
multipass_add("dirt_color", 0, c_black, 0, obj_dirt);
z tego wiemy, że będziemy zbierać 2 rodzaje informacji o obiektach: maski zabrudzeń, oraz kolor zabrudzeń. dla informacji masek zabrudzeń (dirt_mask) będziemy zbierać informacje o obiektach typu obj_dirty, a obiekt ten jest parentem dla wszystkich innych obiektów, które mają być oznaczone jako zdolne do brudzenia się krwią, a więc wszystkie obiekty na scenie gry, które chcesz, by były zdolne do brudzenia się, nadajesz im parenta obj_dirty. Do takich obiektów należeć mogą ściany, jakieś przedmioty w pomieszczeniach, najpewniej to, co nie jest podłogą. Podobnie ma się rzecz z obiektami, które mają brudzić, czyli wystarczy, że obj_blood będzie miał parenta obj_dirt, to wszystkie obiekty krwi trafią do surface przebiegu dirt_color. Ten system nie wymaga tworzenia obiektów w jakiś szczególny, niestandardowy sposób, tworzysz je tak samo jak zawsze - system podczas zbierania informacji o obiektach do swoich surfacesów ogarnia wszystkie obiekty na scenie oznaczone identyfikatorem przekazanym w ostatnim argumencie funkcji multipass_add().
Ad. 3. tak jak wyżej to opisałem: obj_dirt to parent dla wszystkich innych obiektów, które mają brudzić, jest to taka grupa obiektów brudzących. obj_dirty zaś jest parentem dla wszystkich obiektów, które mają przyjmować na siebie zabrudzenia.
Ad. 4. wystarczy, że utworzysz go na scenie i będzie on posiadał parenta obj_dirt. Jest jeszcze jedna ważna rzecz, którą muszę wyjaśnić, otóż: jak zapewne zauważyłeś w kodzie draw obiektów tv, coach, blood i innych, mają one w sobie linijki takie jak ta:
if (multipass_current() == "dirt_color") {
draw_self();
}
chodzi w tym o to, że event draw obiektu może być wywoływany wiele razy dla wielu przebiegów, które zechcą pobierać informacje o danej grupie obiektów. Dajmy na to, dodam dwa przebiegi, które oba jako target podadzą ten sam typ obiektów all. a więc event draw Twojego obiektu wywoła się nie raz, jak normalnie, ale aż 3 razy (raz dla sceny normalnie, oraz dwa dodatkowe razy bo dwa przebiegi zarzyczyły sobie informacji o wszystkich obiektach sceny) - tym kodem wyżej upewniamy się, że nasz obiekt będzie rysowany tylko i wyłącznie dla przebiegu o nazwie "dirt _color" i będzie niewidoczny dla innych przebiegów oraz nie zostanie narysowany na scenie normalnie, bo chcemy by kolor krwi był tylko w surface przebiegu, którym potem zmiksujemy krew z maską zabrudzeń i w ten sposób dostaniemy finalne obsmarowanie krwią widoczne tylko tam, gdzie są obiekty brudzące się. Jeśli nie dodasz tego sprawdzania bieżącego przebiegu, wtedy krew zostanie narysowana zarówno na scenie normalnie, jak i w każdym surface każdego przebiegu, a tego nie chcemy. Jeśli chcesz, aby jakiś obiekt rysował się normalnie na scenie, ale także rysował jakiś swój inny wariant dla jakiegoś przebiegu (np. chcesz aby na scenie obiekt rysował żarówkę, ale też chcesz, aby dla przebiegu "glow" narysował poświatę światła emitowanego przez żarówkę), to wtedy kod wygląda coś jak to:
// rysujemy poświatę żarówki dla przebiegu "glow":
if (multipass_current() == "glow") {
sprite_index = spr_glow; // na chwile zmieniamy sprite obiektu na poświatę.
draw_self(); // rysujemy obiekt.
sprite_index = spr_lightbulb; // przywracamy obiektowi sprite żarówki.
// rysujemy obiekt żarówki normalnie dla sceny gry:
} else if (multipass_current() == undefined) {
draw_self();
}
Ad. 5. zależy jak dokładną informację potrzebujesz. Generalnie to co Cię interesuje najbardziej to shader ten bierze 2 tekstury z surfacesów dwóch przebiegów "dirt_mask" oraz "dirt_color" i dla każdego piksela ekranu kolorem wynikowym RGB będzie kolor tekstury dirt_color (czyli kolor zabrudzeń, tutaj krwi) zaś kanałem alpha będzie kanał alpha tekstury "dirt_mask" przemnożony przez kanał alpha "dirt_color" - obrazowo to działa tak, jak nazwa "maskowanie" sugeruje: kolor krwi będzie widoczny tylko i wyłącznie tam, gdzie istnieją obiekty maski (czyli obiekty zdolne do zabrudzenia się).
Ad. 6.
- nie ma żadnej listy - jedyne, co musisz to nadać obiektom krwi parenta obj_dirt oraz dodać im do eventu draw:
if (multipass_current() == "dirt_color") {
draw_self();
}
- tutaj nie ma także żadnej listy - tak samo jak z krwią, musisz nadać obiektom brudzącym się parenta obj_dirty oraz dodać kod do eventu draw:
if (multipass_current() != "dirt_color") {
draw_self();
}
- poza tym wyżej musisz oczywiście dodać do gry skrypty z grupy "multipass" oraz stworzyć obiekt zajmujący się obsługą przebiegów, tak jak to wygląda w obiekcie obj_dirt_multipass_render. Głównie interesują Cię kody:
Event Create:
multipass_initialize();
multipass_add("dirt_mask", 0, c_black, 0, obj_dirty);
multipass_add("dirt_color", 0, c_black, 0, obj_dirt);
Event Destroy:
multipass_cleanup();
Event Draw:
multipass_render();
Event Draw GUI:
var sampler_mask = shader_get_sampler_index(sh_dirt, "s_Mask");
var texture_mask = multipass_texture("dirt_mask");
shader_set(sh_dirt);
texture_set_stage(sampler_mask, texture_mask);
draw_surface_stretched(
multipass_surface("dirt_color"),
0,
0,
display_get_gui_width(),
display_get_gui_height()
);
shader_reset();