私の目的は何ですか?


Osnove

Namen tega projekta je demonstracija različnih primerov uporabe modula noisy-webgl, ki sem ga ustvaril za ta projekt. Sam modul je WebGL priredba mojega prejšnjega modula, noisy-js.

Domena

Spletna stran uporablja ime 海 (umi), ki se prevede kot morje ali ocean. Izbrano je na podlagi izgleda končnega renderja, kjer pri nespremenjenih nastavitvah izgleda kot otočje sredi morja.

Ker že imam v lasti domeno azcn.io, sem domeno umi uvrstil kot poddomeno le-te.

Dizajn

Kot prikazni jezik sem izbral japonščino, saj predstavlja državo, ki ima močno povezavo do morja. Izgovor besede ‘umi’ je kratek in vokalno prijeten.

Kot logotip sem uporabil kanji simbol 海, ovit v krog v stilu poteze čopiča (ang. brush stroke). Ker je logotip kompleksen, sem za izdelavo favicon-a uporabil le krožni segment.

Spletna stran uporablja barvo ozadja, ki je enaka, kot je voda v renderjih prednastavljenih atributov. S tem zagotovim neprekinjen prehod med vsebino renderjev in preostankom spletne strani.

Tekstovna vsebina spletne strani uporablja tako horizontalno, kot tudi vertikalno orientacijo, kar je v tem primeru tudi kontekstno relevantno.

Model spletne strani sledi naslednji obliki: navigation, tagline, content, footer.

Vse podstrani imajo dostop do vseh ostalih podstrani z uporabo navigacijskega segmenta. Povezave se ne pojavljajo izven tega segmenta. Povezave so v smiselnem vrstnem redu, glede na pričakovano uporabo spletne strani - povezave od leve proti desni.

Tagline je vrstica, v katero postavim krajši stavek ali frazo, ki v bralcu vzbudi interes do pregleda trenutne podstrani, ali pa mu na kratko predstavi namen oziroma tematiko.

Content predstavlja glavni segment vsake podstrani. Znotraj tega je na vsaki strani vsebina drastično drugačna, saj je njen namen strnjena demonstracija različnih primerov uporabe.

Na dnu strani se nahaja noga z mojim imenom in copyright podatkom.


Tehnologije

Za izdelavo HTML-ja sem uporabil Pug. Pug je pogon za predloge, ki se pretvori v HTML markup z uporabo kompilacije z Node.js. Z uporabo le-tega lahko pišem kratko in jedrnato kodo, ki uporablja enake besede kot HTML, skupaj s poljubno uporabo JavaScript-a za programatično generiranje kode.

Za JavaScript bi za preprečitev napak praviloma uporabil TypeScript, vendar pri tem projektu to ni bilo potrebno zaradi nizke kompleksnosti vsebin izven Umi objekta, ki je že v osnovi bil napisan v JavaScript-u.

Za CSS pravila uporabljam Sass v SCSS obliki. Sass mi omogoča bolj razumljivo strukturo in organizacijo CSS pravil, s čimer si zmanjšam število potencialnih napak.

Preprosto združitev vseh treh komponent sem dosegel z uporabo Gulp orodja. Avtomatizacija kompilacije in pretvorbe je z Gulp-om bistveno lažja.

Gulp sem konfiguriral, da nadzoruje vse datoteke v predpostavljenih mapah in samodejno zažene primerni postopek, glede na njihovo lokacijo in končnico.

HTML postopek:

  1. Preberi vsebino datoteke lang.json, ki vsebuje EN-JP prevode vseh tekstovnih vsebin.
  2. Vsebino posreduj v Pug modul.
  3. Rezultat formatiraj (olepšaj) s Prettier modulom.
  4. Formatiran rezultat shrani v /dist/ mapo.

JS postopek:

  1. Zaženi modul sourcemaps.
  2. Združi vsebine vseh JavaScript datotek.
  3. Rezultat formatiraj (ogršaj) s Terser modulom.
  4. Ustvari source map datoteko s sourcemaps modulom.
  5. Oboje shrani v /dist/ mapo.

CSS postopek:

  1. Zaženi modul sourcemaps.
  2. Izvedi prevod iz SCSS v CSS s Sass modulom.
  3. Dodaj predpone različnih brskalnikov z uporabo precss in autoprefixer modulov znotraj postcss modula.
  4. Ustvari source map datoteko s sourcemaps modulom.
  5. Oboje shrani v /dist/ mapo.

JS in CSS postopka združita vse datoteke v eno končno datoteko, pri čemer se dodatno ustvari tudi source maps datoteka, ki vzpostavi reference med kompiliranimi in izvornimi datotekami.


Procedural generation

Vse slikovne vsebine, ki predstavljajo teren, so proceduralno oziroma postopkovno generirane. To pomeni, da je v ozadju algoritem, s katerim na strani klienta v brskalniku zgeneriram vse slike ob zagonu strani. Ker je to generiranje postopek, ki traja dalj časa, je nalaganje strani malenkost počasnejše, glede na uporabnikovo strojno opremo.

Najintenzivnejši del generiranja je kreiranje vzorca šuma (ang. noise pattern), ki deluje kot črno-beli zemljevid višine terena (ang. heightmap). Teren je nato pobarvan glede na svetlost piksla, kjer svetlejši piksel pomeni višja točka terena. Barve različnih višin so podane kot seznam barv in njihovih lokacij znotraj 0-1 območja, s čimer jih nato interpretiram kot gradient.

Ker je vse to preveč dolgotrajen postopek za CPU, preložim delo na GPU, s čimer dosežem drastično hitrejše izvajanje paralelnih algoritmov, kot je v tem primeru noisy-webgl.

Podstran 旅行 uporablja dodatno obdelavo renderja kot pretvorbo v psevdo-3D izgled, ampak je zaradi same časovne omejitve pri izdelavi tega projekta izvedena na procesorju. Iz tega razloga deluje počasneje, vendar sem z uporabo manjših resolucij uspel skrajšati čas procesiranja in nalaganja, saj mora obdelati manjše število podatkov.

Spletni brskalniki omejijo število aktivnih WebGL elementov/platen, ker so izredno intenzivni pri porabi računalniških sredstev, zato po zaključku izrisa ene slike na vsakem platnu, celotni element odstranim in ga zamenjam z img elementom, vir katerega je platno, pretvorjeno v image data string.

Ker se vse tovrstne slike izrisujejo na uporabnikovi strani, je prenos podatkov pri prehodu med podstranmi minimalen.

Težave

Kot težavo s količino podatkov bi rad izpostavil le pisavo. Ker je vsebina strani prikazana v japonščini, je stilističen izgled simbolov odvisen od operacijskega sistema uporabnika. Vsebina uporablja Times pisavo, kar japonskim simbolom daje zavit videz. Windows operacijski sistemi ne podpirajo tovrstnega izgleda brez dodatno nameščenih pisav, saj Times pisava ni prisotna. Japonski simboli izgledajo natisnjeni pri uporabi Times New Roman.

Kot rešitev za poenotenje izgleda sem uporabil pisavo Noto Serif JP, s čimer se je prvi zagon strani dodatno upočasnil zaradi prenosa ogromnih datotek pisav - 4.6 MB le za dve debelini pisave.

Dodatno uporabljam tudi klasično verzijo pisave enake družine - Noto Serif, vendar le-ta predstavlja le delež velikosti JP verzije pisave.


Umi

Celotna stran uporablja naslednji postopek za generiranje vsebine:

  1. Ko se stran naloži, poženi vsebino page.js (GH: /src/js/page.js).
  2. Preberi trenutno lokacijo strani in poženi primerne slikarje/gradnike.
  3. Prenesi shader datoteke (GH: /glsl/).
  4. Podaj nastavitve in atribute za vsak umi/platno v svoj Umi objekt.
  5. Izriši eno sličico za vsak umi.
  6. Ustvari novo sliko iz podatkov in odstrani umi/platno (ang. canvas).
  7. V primeru podstrani 旅行 se te slike nato pretvorijo v psevdo-3D izgled.

Adaptacija noisy-webgl algoritma iz 5. koraka deluje po sledečem postopku:

  1. V konstruktorju sprejmi referenco na platno, skupaj z nastavitvami.
  2. Po inicializaciji sprejmi atribute in gradiente.
  3. Izvedi validacijo atributov in jih po potrebi pretvori ali zavrži.
  4. S procesom prepisovanja vstavi ali prevedi vse atribute in gradiente v shader kodo.
  5. Ustvari vertex in fragment shaderja, ter iz tega ustvari WebGL program.
  6. Ustvari in prikaže pravokotnik čez celotno vidno polje.
  7. Poženi vertex shader.
  8. Odstrani program.

Spodaj je opisan postopek delovanja 7. koraka na grafičnem procesorju:

  1. Za vsako koordinato pravokotnika (njegovih trikotnikov), podaj koordinate fragment shaderju in ga poženi.
  2. Pretvori koordinato piksla v odstotek znotraj vidnega polja.
  3. Določi začetni položaj glede na podane atribute - znižaj globino na straneh, ali v krogu.
  4. Uporabi Worley algoritem za celični šum (ang. cellular noise).
  5. Uporabi variacijo algoritma, podobnega Simplex algoritmu za naključni šum.
  6. Združi rezultate obeh algoritmov.
  7. Dodatno obdelaj rezultat, glede na podane atribute.
  8. Obarvaj rezultat, glede na svetlost, z uporabo podanega gradienta.

Opis 7. koraka iz prvotnega seznama, pri čemer zgoraj opisani rezultat pretvorim v psevdo-3D je sledeč:

  1. Podaj vsebino rezultata renderja v novo platno, tokrat le 2D namesto WebGL.
  2. Za uporabo tega algoritma se uporabi črno-beli gradient renderja.
  3. Program teče na CPU-ju, zato uporabi manjšo resolucijo.
  4. Preberi in shrani vsako n vrstico slike, v mojem primeru vsako 16. vrstico.
  5. Uporabi 1D Gaussian blur na vsaki vrstici, za manj hrapavo površino.
  6. Izriši vertikalno črto iz višine svetlosti piksla v vrstici.
  7. Začetna in končna višina sta odvisni od globine (vrstnega reda) vrstice.
  8. Barva piksla znotraj črte je odvisna od njegove relativne višine.

SEO

Search Engine Optimization danes deluje povsem drugače, kot je včasih. Nekoč zlata pravila, kot so uporaba keywords metapodatkov ali podobnih optimizacij niso več veljavna. Google uporablja kriterije, kot so varnost in dostopnost strani, hitrost njenega nalaganja, mobilna dostopnost, starost domene, vsebina besedila domene in besedila URL-jev, optimizacija vsebine, ključne besede v naslovih, uporabniška izkušnja, povezave, signali družabnih omrežij ter podatki o podjetju, ko je to primerno.

Bolj je pomembna optimizacija uporabniške izkušnje, kot tehnična optimizacija za iskalnike. Googlov AI algoritem RankBrain uporablja vsebinske signale, kot so splošna relevanca vsebine in relevanca vsebine v lokalnem območju, število besed, ključne besede v body segmentu, v opisu, naslovu in H1 elementih; in uporabniške signale, kot so “click-through rate”, kar predstavlja delež ljudi, ki dejansko pritisne na povezavo do strani v rezultatih iskanja, “bounce rate”, kar je število ljudi, ki se po obisku strani hitro vrnejo nazaj na rezultate iskanja, ter “dwell time”, kar predstavlja čas, ki ga uporabniki preživijo na strani po tem, ko jo obiščejo.

Copyright

Za licenco tega projekta sem izbral MIT licenco, s čimer drugim omogočam skoraj povsem prosto izbiro uporabe kode ali njenih segmentov za distribuiranje in spreminjanje tako odprto- kot tudi zaprto-kodnih derivacij. To omogoča uporabo tega projekta pri komercialnih produktih, kot tudi za zasebne ali druge primere. Ta licenca me razvezuje od garancije in škode, nastale z uporabo produkta.

Tovrstno dopustno licenco sem uporabil, ker stran ne predpostavlja morebitnega lastništva projekta, temveč predstavlja orodje, ki naj ne bi bilo omejeno za uporabo v drugih projektih in integracijah.

Dodatne funkcionalnosti

Zaradi časovne omejitve mi ni uspelo pripraviti nekaterih funkcionalnosti, kot so sprememba jezika strani, ustvarjalec gradientov, upravljanje in spreminjanje atributov, GPU izris psevdo-3D pretvorb, dvojni izris (črno-beli height map + barvni render), umi animacija, ter mnogo drugih.

Viri

Noisy-JS 「 noisy-js/page.js at main · azcion/noisy-js (github.com)

Noisy-WebGL 「 noisy-webgl/webgl.js at main · azcion/noisy-webgl (github.com)

Worley 「 webgl-noise/cellular2D.glsl at master · ashima/webgl-noise (github.com)

Simplex 「 webgl-noise/noise2D.glsl at master · ashima/webgl-noise (github.com)