Przejdź do głównej zawartości

Mój pierwszy efekt

W tym poradniku nauczysz się tworzyć efekty cząsteczkowe (Particle Effects, PFX) — od prostego dymu, przez ogień, po deszcz i śnieg.

Jak działają efekty cząsteczkowe?

System PFX w Gothic emituje cząsteczki (małe sprite'y z teksturą) z emitera o określonym kształcie. Każda cząsteczka ma swój kierunek, prędkość, czas życia i wygląd.

Efekty definiowane są jako instancje klasy C_ParticleFX w plikach w katalogu System/PFX/:

PlikOpis
PfxInst.dEfekty ogólne (ogień, dym, iskry, woda, pogoda)
PfxInstEngine.dEfekty wymagane przez silnik (krew, kurz, plusk wody)
PfxInstMagic.dEfekty magiczne (zaklęcia, runy, aury)

Klasa C_ParticleFX — przegląd

Klasa ma 49 pól podzielonych na 7 kategorii. Nie musisz ustawiać wszystkich — pola, których nie ustawisz, przyjmą wartości domyślne (zazwyczaj 0 lub pusty string).

1. Emisja — ile cząsteczek i kiedy

PoleTypOpis
ppsValuefloatBazowa liczba cząsteczek na sekundę
ppsScaleKeys_SstringMnożniki rozłożone w czasie, np. "1 2 3"
ppsIsLoopingint1 = zapętlone, 0 = jednorazowe
ppsIsSmoothint1 = płynna interpolacja między kluczami
ppsFPSfloatPrędkość odtwarzania kluczy (klatki/s)
ppsCreateEm_SstringNazwa efektu potomnego (spawny per cząsteczka)
ppsCreateEmDelayfloatOpóźnienie efektu potomnego

2. Kształt emitera — skąd lecą cząsteczki

PoleTypOpis
shpType_SstringKształt: "POINT", "LINE", "BOX", "CIRCLE", "SPHERE", "MESH"
shpFOR_SstringUkład odniesienia: "OBJECT" lub "WORLD"
shpOffsetVec_SstringPrzesunięcie: "X Y Z"
shpDistribType_SstringRozkład: "RAND", "UNIFORM", "WALK", "DIR"
shpIsVolumeint1 = emisja z objętości, 0 = z powierzchni
shpDim_SstringWymiary (zależne od kształtu)
shpMesh_SstringMesh emitera (gdy shpType_S = "MESH")
shpMeshRender_Bint1 = renderuj mesh emitera

3. Kierunek i prędkość

PoleTypOpis
dirMode_SstringTryb: "DIR", "TARGET", "MESH_POLY", "RAND", "NONE"
dirFOR_SstringUkład odniesienia kierunku
dirAngleHeadfloatKąt obrotu poziomego (°)
dirAngleHeadVarfloatWariancja kąta (±°)
dirAngleElevfloatKąt elewacji (°); 90 = w górę, -90 = w dół
dirAngleElevVarfloatWariancja elewacji (±°)
velAvgfloatŚrednia prędkość początkowa
velVarfloatWariancja prędkości (±)

4. Czas życia cząsteczek

PoleTypOpis
lspPartAvgfloatŚredni czas życia (ms)
lspPartVarfloatWariancja czasu życia (±ms)

5. Zachowanie w locie

PoleTypOpis
flyGravity_SstringWektor grawitacji: "X Y Z"
flyCollDet_Bint0 = brak kolizji, 1 = kolizje, 3 = kolizje + ślady

6. Wizualizacja

PoleTypOpis
visName_SstringTekstura (.TGA) lub model (.3DS)
visOrientation_SstringBillboard: "NONE", "VELO", "VELO3D", "VOB"
visTexIsQuadPolyint0 = trójkąt, 1 = kwadrat
visTexAniFPSfloatFPS animacji tekstury
visTexAniIsLoopingint0 = raz, 1 = pętla, 2 = ping-pong
visTexColorStart_SstringKolor początkowy: "R G B" (0–255)
visTexColorEnd_SstringKolor końcowy (interpolacja w czasie życia)
visSizeStart_SstringRozmiar początkowy: "W H"
visSizeEndScalefloatMnożnik rozmiaru końcowego
visAlphaFunc_SstringBlending: "BLEND", "ADD", "MUL"
visAlphaStartfloatPrzezroczystość początkowa (0–255)
visAlphaEndfloatPrzezroczystość końcowa (0–255)

7. Efekty dodatkowe

PoleTypOpis
trlFadeSpeedfloatPrędkość zanikania śladu (trail)
trlTexture_SstringTekstura śladu
trlWidthfloatSzerokość śladu
mrkFadeSpeedfloatPrędkość zanikania odcisku (mark)
mrkTexture_SstringTekstura odcisku
mrkSizefloatRozmiar odcisku
flockModestringTryb stadny: "WIND"
flockStrengthfloatSiła efektu stadnego
useEmittersFORint1 = cząsteczki podążają za emiterem
timeStartEnd_SstringOkno czasowe renderowania: "8 22" (8:00–22:00)
m_bIsAmbientPFXint1 = efekt ambientowy (można wyłączyć w gothic.ini)

Przykład 1: Prosty dym

Zacznijmy od czegoś prostego — słup dymu unoszący się w górę:

instance PFX_MojDym (C_ParticleFX)
{
// --- Emisja: 30 cząsteczek/s, ciągłe ---
ppsValue = 30;
ppsScaleKeys_S = "1";
ppsIsLooping = 1;

// --- Kształt: punkt ---
shpType_S = "POINT";
shpFOR_S = "OBJECT";

// --- Kierunek: w górę z losowym odchyleniem ---
dirMode_S = "DIR";
dirFOR_S = "OBJECT";
dirAngleElev = 90; // w górę
dirAngleElevVar = 15; // ±15° odchylenia
dirAngleHeadVar = 180; // rozrzut na boki
velAvg = 0.02; // powolny
velVar = 0.01;

// --- Czas życia: 2–3 sekundy ---
lspPartAvg = 2500;
lspPartVar = 500;

// --- Brak grawitacji (dym unosi się) ---
flyGravity_S = "0 0.0001 0"; // lekko w górę

// --- Wygląd ---
visName_S = "SMOKE1.TGA";
visOrientation_S = "NONE"; // billboard skierowany do kamery
visTexColorStart_S = "150 150 150"; // szary
visTexColorEnd_S = "80 80 80"; // ciemniejszy z czasem
visSizeStart_S = "10 10";
visSizeEndScale = 5; // rośnie 5x
visAlphaFunc_S = "BLEND"; // zwykłe przenikanie
visAlphaStart = 180;
visAlphaEnd = 0; // zanika
};
wskazówka

visAlphaFunc_S — tryby blendingu:

  • "BLEND" — klasyczne przenikanie (dym, mgła, kurz)
  • "ADD" — addytywne (ogień, iskry, magia — jasne, świecące)
  • "MUL" — multiplikatywne (cienie, przyciemnianie)

Przykład 2: Ognisko

Ogień to połączenie szybkiej emisji, addytywnego blendingu i animowanej tekstury:

instance PFX_MojOgien (C_ParticleFX)
{
// --- Emisja: dużo cząsteczek, ciągłe ---
ppsValue = 80;
ppsScaleKeys_S = "1";
ppsIsLooping = 1;

// --- Kształt: koło (baza ogniska) ---
shpType_S = "CIRCLE";
shpFOR_S = "OBJECT";
shpIsVolume = 1;
shpDim_S = "15"; // promień 15 jednostek

// --- Kierunek: w górę ---
dirMode_S = "DIR";
dirFOR_S = "OBJECT";
dirAngleElev = 90;
dirAngleElevVar = 20;
dirAngleHeadVar = 180;
velAvg = 0.05;
velVar = 0.02;

// --- Czas życia: krótki (szybki ogień) ---
lspPartAvg = 800;
lspPartVar = 200;

// --- Lekka grawitacja w górę (gorące powietrze) ---
flyGravity_S = "0 0.0003 0";

// --- Wygląd ---
visName_S = "FIREFLARE.TGA";
visOrientation_S = "NONE";
visTexAniFPS = 8; // animacja tekstury
visTexAniIsLooping = 1; // zapętlona
visTexColorStart_S = "255 255 255"; // biały (prześwietlony środek)
visTexColorEnd_S = "255 100 30"; // pomarańczowy (krawędzie)
visSizeStart_S = "5 5";
visSizeEndScale = 4; // rośnie
visAlphaFunc_S = "ADD"; // addytywne = świecące
visAlphaStart = 255;
visAlphaEnd = 0;
};

Przykład 3: Iskry

Iskry to małe, szybkie cząsteczki z grawitacją i kolizjami:

instance PFX_MojeIskry (C_ParticleFX)
{
// --- Emisja: jednorazowy wybuch ---
ppsValue = 50;
ppsScaleKeys_S = "1 0"; // natychmiast, potem nic
ppsIsLooping = 0; // jednorazowe
ppsFPS = 2;

// --- Kształt: punkt ---
shpType_S = "POINT";
shpFOR_S = "OBJECT";

// --- Kierunek: rozbiegają się we wszystkie strony ---
dirMode_S = "DIR";
dirFOR_S = "OBJECT";
dirAngleHeadVar = 180; // pełne 360°
dirAngleElev = 45; // lekko w górę
dirAngleElevVar = 45; // ale z dużym rozrzutem
velAvg = 0.15; // szybkie
velVar = 0.08;

// --- Czas życia: krótki ---
lspPartAvg = 600;
lspPartVar = 300;

// --- Grawitacja ciągnie w dół ---
flyGravity_S = "0 -0.0005 0";
flyCollDet_B = 1; // kolizje ze światem

// --- Wygląd: małe, jaskrawe punkty ---
visName_S = "ZFLARE1.TGA";
visOrientation_S = "NONE";
visTexColorStart_S = "255 220 100"; // żółty
visTexColorEnd_S = "255 80 20"; // ciemny pomarańcz
visSizeStart_S = "2 2";
visSizeEndScale = 0.5; // zmniejszają się
visAlphaFunc_S = "ADD";
visAlphaStart = 255;
visAlphaEnd = 0;
};

Przykład 4: Śnieg

Śnieg to duży emiter na dużej wysokości, wolno opadające cząsteczki:

instance PFX_MojSnieg (C_ParticleFX)
{
// --- Emisja: ciągła ---
ppsValue = 50;
ppsScaleKeys_S = "1";
ppsIsLooping = 1;

// --- Kształt: duży okrąg wysoko nad graczem ---
shpType_S = "CIRCLE";
shpFOR_S = "OBJECT";
shpOffsetVec_S = "0 500 0"; // 500 jednostek nad emiterem
shpIsVolume = 1;
shpDim_S = "300"; // promień 300

// --- Kierunek: w dół ---
dirMode_S = "DIR";
dirFOR_S = "OBJECT";
dirAngleHead = 20; // lekki wiatr
dirAngleHeadVar = 10;
dirAngleElev = -89; // prawie prosto w dół
velAvg = 0.05;
velVar = 0.02;

// --- Czas życia: długi ---
lspPartAvg = 5000;

// --- Brak grawitacji (stała prędkość opadania) ---
flyGravity_S = "0 0 0";

// --- Wygląd: białe płatki ---
visName_S = "MFX_SLEEP_STAR.TGA";
visOrientation_S = "NONE";
visTexColorStart_S = "255 255 255";
visTexColorEnd_S = "255 255 255";
visSizeStart_S = "5 5";
visSizeEndScale = 1;
visAlphaFunc_S = "ADD";
visAlphaStart = 255;
visAlphaEnd = 255;

// --- Efekt ambientowy (gracz może wyłączyć w opcjach) ---
m_bIsAmbientPFX = 1;
};

Przykład 5: Krew (efekt potomny)

System potomnych emiterów pozwala tworzyć złożone efekty. Krew w Gothic składa się z dwóch instancji — głównej (bryzy krwi) i potomnej (plamy na podłożu):

// Główny efekt: bryzy krwi rozlatujące się
instance PFX_MojaKrew (C_ParticleFX)
{
ppsValue = 64;
ppsCreateEm_S = "PFX_MojaKrew_Plama"; // potomny efekt!

dirMode_S = "DIR";
dirFOR_S = "OBJECT";
dirAngleHeadVar = 30;
dirAngleElevVar = 30;
velAvg = 0.1;
velVar = 0.05;

lspPartAvg = 750;
lspPartVar = 550;

flyGravity_S = "0 -0.0001 0"; // spada
flyCollDet_B = 1;

visName_S = "BLOOD1.TGA";
visTexColorStart_S = "255 255 255";
visTexColorEnd_S = "255 255 255";
visSizeStart_S = "6 6";
visSizeEndScale = 1;
visAlphaFunc_S = "BLEND";
visAlphaStart = 255;
};

// Efekt potomny: plama na podłożu
instance PFX_MojaKrew_Plama (C_ParticleFX)
{
ppsValue = 1;
ppsIsLooping = 0; // jedna plama

shpType_S = "POINT";

dirMode_S = "NONE"; // bez ruchu
velAvg = 0;

lspPartAvg = 3000; // 3 sekundy

visName_S = "YOURBLOODSPLAT.TGA";
visSizeStart_S = "10 10";
visSizeEndScale = 1;
visAlphaFunc_S = "BLEND";
visAlphaStart = 200;
visAlphaEnd = 0; // zanika
};
informacja

ppsCreateEm_S — każda cząsteczka z głównego emitera staje się źródłem nowego efektu potomnego. To potężne narzędzie, ale kosztowne — używaj ostrożnie, by nie obciążyć silnika.

Kształty emiterów

KształtshpType_SshpDim_SOpis
Punkt"POINT"Emisja z jednego punktu
Linia"LINE""100" (długość)Emisja wzdłuż linii
Prostopadłościan"BOX""W H D"Emisja z prostokątnego obszaru
Okrąg"CIRCLE""50" (promień)Emisja z koła (lub dysku gdy shpIsVolume = 1)
Sfera"SPHERE""50" (promień)Emisja z kuli
Mesh"MESH""250" (skala)Emisja z powierzchni mesha 3D

shpIsVolume

  • shpIsVolume = 0 — cząsteczki pojawiają się na krawędzi kształtu (np. na obwodzie koła)
  • shpIsVolume = 1 — cząsteczki pojawiają się wewnątrz kształtu (np. w całym kole)

Orientacja cząsteczek

TrybvisOrientation_SOpis
Billboard"NONE"Cząsteczki zawsze zwrócone do kamery (domyślne)
Wzdłuż prędkości"VELO"Cząsteczki rozciągnięte w kierunku ruchu (deszcz, iskry)
3D wzdłuż prędkości"VELO3D"Jak VELO, ale z pełną rotacją 3D
Obiekt"VOB"Orientacja zgodna z obiektem nadrzędnym

Rejestracja w ParticleFX.src

Efekty cząsteczkowe mają oddzielną kompilację od skryptów gry. Dodaj swój plik do System/ParticleFX.src:

_intern\ParticleFx.d
Pfx\PfxInstEngine.d
Pfx\PfxInst.d
Pfx\PfxInstMagic.d
Pfx\MojePfx.d
ostrzeżenie

Efekty PFX nie są kompilowane przez Gothic.src — używają własnego pliku ParticleFX.src w katalogu System/.

Porady praktyczne

Wydajność

  • Im wyższe ppsValue, tym więcej cząsteczek = więcej obliczeń
  • flyCollDet_B z dużą ilością cząsteczek mocno obciąża CPU
  • useEmittersFOR = 1 wraz z flyCollDet_B to najkosztowniejsza kombinacja
  • ppsCreateEm_S mnoży liczbę efektów — każda cząsteczka tworzy nowy emiter

Debugowanie

  • Jeśli efekt nie jest widoczny, sprawdź czy visAlphaStart > 0 i visSizeStart_S nie jest za małe
  • Sprawdź, czy tekstura (.TGA) istnieje w katalogu Textures/
  • Efekty z m_bIsAmbientPFX = 1 mogą być wyłączone w opcjach gry

Częste wzorce

EfektKluczowe ustawienia
DymBLEND, duży visSizeEndScale, visAlphaEnd = 0
OgieńADD, animowana tekstura, krótki lspPartAvg
IskryADD, jednorazowy burst, grawitacja w dół, kolizje
Deszcz/śniegDuży emiter CIRCLE, offset w Y, dirAngleElev = -89
KrewBLEND, grawitacja, efekt potomny (plamy)
Magia/auraADD, CIRCLE emiter, useEmittersFOR = 1

Podsumowanie

Tworzenie efektów cząsteczkowych wymaga:

  1. Instancji klasy C_ParticleFX z odpowiednimi parametrami
  2. Kształtu emitera (shpType_S) — skąd lecą cząsteczki
  3. Kierunku i prędkości — jak się poruszają
  4. Wizualizacji — tekstura, kolor, rozmiar, przenikanie
  5. Rejestracji w ParticleFX.src (nie w Gothic.src!)