Beeld


Glows met POV-Ray en (bv) Perl:

2 afbeeldingen renderen: het eerste, de gewone afbeelding, dient als achtergrond voor het effect. Het tweede - waarin de gebieden die een glow moeten krijgen wit zijn, en de andere zwart - dient als masker voor het effect.

Het BMP-bestand openen, de header interpreteren (de resolutie eruithalen) en 3 rijen aanmaken van x*y elementen. (Rij-linearisatie van de pixels. De locatie van pixel (a,b) in de rij is (als x en y de resoluties zijn):

a+(b*x)

(als x en y gaan van 0 tot ...)
De drie rijen bevatten telkens opeenvolgende bytes: de kleurcodes voor rood, groen en blauw.
Nu moet het masker bewerkt worden. Voor het masker is 1 rij voldoende, omdat enkel de intensiteit van beland is. Om het later gemakkelijker te maken, is het best die intensiteit in het interval [0,1] te houden.
Voorlopig houd ik het op glows die slechts 1 pixel uit het glowgebied komen.

OPMERKING: ik krijg hier juist een idee! Het lijkt mij het beste om 3 maskers te maken: voor elke kleur (rood, groen en blauw) 1. Dat is veel flexibeler. Nadeel is wel dat de afbeelding 3 keer gerenderd moet worden.

Nu moeten we dus het/de masker(s) bewerken. Maakt niet echt veel uit of ik het uiteindelijk zal maken met 1 masker, of met 3, de bewerkingen zijn voor elk masker toch hetzelfde.
Voor de gemakkelijkheid, is het misschien (veel) beter om niet de ASCII-tekentjes in de tabellen te zetten, maar de waarden ervan. Misschien is het zelfs nog beter om ze eerst om te zetten van het interval [0,255] naar [0,1], dat rekent gemakkelijker.
Het proces van 'feathering' kan op deze manier gedaan worden:
Er zijn twee filters nodig: groei-filter en blur-filter. De groei filter telt alle omliggende waarden op, de blur-filter berekent het gemiddelde daarvan. Deze filters zijn zeer eenvoudig te definieren door:

(Neem rood groen en blauw van x en y in het interval [0,1])

rood(groei(x,y))=rood(x,y)+rood(x-1,y-1)+rood(x,y-1)+rood(x+1,y-1)+rood(x-1,y)+rood(x+1,y)+rood(x-1,y+1)+rood(x,y+1)+rood(x+1,y+1)
rood(blur(x,y))=(rood(x,y)+rood(x-1,y-1)+rood(x,y-1)+rood(x+1,y-1)+rood(x-1,y)+rood(x+1,y)+rood(x-1,y+1)+rood(x,y+1)+rood(x+1,y+1))/9
(en hetzelfde voor groen en blauw. Als een van de waarden groter is dan 1, verander het dan in een 1).
(Let wel op: als x=0, dan kan x-1 niet genomen worden! Hetzelfde geldt voor:
x=resx => x+1 kan niet
y=resy => y+1 kan niet
y=0 => y-1 kan niet
)
Nu moet eerst de groei-filter toegepast worden op de maskers, en daarna de blur-filter 1 of meer keer. (Voor grotere glows moet de groei-filter meer dan eens toegepast worden.)

Nu is het masker (of de maskers) klaar. Als er 3 maskers gebruikt werden, moet elk masker vermenigvuldigd worden met zijn bijbehorende kleur (zodat het masker voor rood rood getint wordt enz.). Dan moeten de maskers samengevoegd worden (gewoon de 3 kleurcomponenten gebruiken. Eigenlijk hoeft dat samenvoegen niet echt, ge hebt toch 3 rijen nodig, en ge hebt er al 3, dus...). De afbeelding gevormd door de samenvoeging van de (gekleurde) maskers, is de glow-laag. Die moet op de achtergrondlaag geplaatst worden, maar zo dat er nooit intensiteit verloren gaat. Voor elke kleurcomponent moet dus voor elke pixel gekeken worden of de waarde van de glow-laag hoger is dan die van de achtergrond-laag. De hoogste waarde is de waarde voor de nieuwe afbeelding.

Die nieuwe afbeelding (die dus bestaat uit 3 rijen van elk x*y elementen) moet dan opnieuw weggeschreven worden naar een BMP-bestand. Vermits de resolutie en de kleurdiepte (blijft 24 bit) hetzelfde is als de oorspronkelijke afbeelding, kan de oorspronkelijke header gebruikt worden.

Nu alleen 't nog maken :-)