Egenskygge
Grafikk
Børre Stenseth
Forklaring av>Skygge og glatting

Egenskygge og glatting

Hva
spherehalf

I modulen Lys og materialer er mekanismene for å beregne intensitet basert på lys- og materialegenskaper gjennomgått. I denne modulen skal vi se litt på hvordan disse beregningene brukes til framstille flater. Vi skal spesielt se på egenskygge (shading) og glatting (smoothing).

Når det gjelder skyggebegrepet så merk at på engelsk brukes begrepene shade og shadow. Med shade menes det vi på norsk kan kalle egenskygge, altså den skyggevirkningen vi får på et objekt basert på overflatens orientering i forhold til lyskilden(e). Med shadow menes det vi på norsk kan kalle slagskygge, altså den skyggen et objekt kaster på et annet objekt.

Det er egenskygge, shading, vi skal konsentrere oss om i denne modulen. Slagskygge er mer komplisert. Se en skisse til matematisk løsning på dette er beskrevet i modulen Plan, og en mer inngående forklaring i modulen: Slagskygge

Gouraud

OpenGL benytter Gouraudshading [1] . Utgangspunktet er at vi har beregnet intensiteten i alle hjørner i et polygon. Med intensitet mener vi hvilken styrke som skal tillegges den røde, blå og grønne lyskomponenten i det aktuelle punktet. Dette vet vi at vi gjør ved å angi normaler i hjørnene, f.eks. slik:


  glBegin(GL_TRIANGLE_STRIP);
    for(ix=0;ix< N ix++)
    {
      glNormal3f(..);
      glVertex3f(..);
    }
  glEnd();

Hvis vi konsentrerer oss om en av de trekantene som dannes, vil OpenGL på grunnlag av de lyskildene som er angitt, materialegenskapene, normalene og hjørnene beregne intensiteten i hvert av hjørnene. Gouraud shading er å finne en måte å beregne intensiteten i et vilket som helst punkt i trekanten basert på verdien i hjørnene.

Image644

Dette gjøres ved interpolasjon: Ia er resultatet av en interpolering mellom I1 og I2, og Ib er resultatet av en interpolering mellom I2 og I3.

Vi tenker oss at flaten genereres linje for linje og intensiteten i hvert punkt langs linja beregnes etter resonnementet nedenfor:

image646

Beregningen kan effektiviseres i praksis ved å gå nærmere inn på beregningene fra en linje til den neste.

De to kulene nedenfor illustrerer forskjellen på en en flat skygge og en glatt (gouraud) flate.

spheres3

På kula til venstre er hver flate for seg beregnet med en konstant, flat intensitet. Legg merke til en effekt som skyldes øyet: Macband-effekten. Det ser ut som om skillet mellom flatene står ut. Dette skyldes at øyet forsterker forskjellen mellom naboflater.

Vi kan skru av og på Gouraudshading i OpenGL:


  /* on */
  glShadeModel(GL_SMOOTH);
  /* off */
  glShadeModel(GL_FLAT);

Glatting over flere flater oppnår vi ved at en rekke av tegnekommandoene i OpenGL lager sammensatte flater og at en normal som oppgis i et hjørne anvendes i alle de flatene som deler dette hjørnet. F.eks.:


  glBegin(< mode >);
    for(ix=0;ix< N ix++)
    {
      glNormal3f(..);
      glVertex3f(..);
    }
  glEnd();

Der mode blant annet kan ha følgende verdier og effekter:

Image651

Hvis vi analyserer dette nærmere, kan vi se for oss to måter å angi normaler på. Vi tar som utgangspunkt at vi ønsker å framstille en "rundet", glatt overflate ved hjelp av flater (F1,F2,F3,F4).

gour1

Vi kan ta normalen i hver flate og bruke normalene fra flate n-1 og n som en normaler i flate n. Dersom vi har små flater og/eller svak krumming vil dette gi god glattingseffekt. gour2
Vi kan bruke normaler som er gjennomsnitt av flatenormalene i et fellespunkt mellom grenseflater. Dette er tydelig en bedre strategi. En strategi for å implementere dette tilskrives Newell. Du kan søke etter denne i litteraturen. gour3

Skjøting

Når vi har skrudd på glatting med

glShadeModel(GL_SMOOTH);

og bruker f.eks.:

  glBegin(GL_TRIANGLE_STRIP);
    for(ix=0;ix< N ix++)
    {
      glNormal3f(..);
      glVertex3f(..);
    }
  glEnd();

tar OpenGL seg av glattingen over de flatene som skapes mellom glBegin og glEnd. Ofte er vi i den situasjonen at vi må bruke flere slike glBegin - glEnd konstruksjoner for å skape en sammenhengende flate. Hvis vi ønsker at denne samlede flaten skal glattes, må vi selv ta ansvaret for å skjøte på en glatt måte. Dette kan vi gjøre ved å bruke strategien med "midlede" normaler, som angitt ovenfor, i skjøtene.

En torus, smultring, er et tydelig eksempel der dette behovet oppstår. Vi kan lage bånd rundt torusen med GL_TRIANGLE_STRIP, men vi har ingen automatisk måte å glatte mellom båndene.

torus newtorus

På figuren til venstre er det ikke er gjort noe forsøk på å skjøte mellom båndene, mens på figuren til høyre er normalene interpolert som angitt ovenfor.

Phong

Et alternativ til Gouraudshading er Phongshading [2] . I dette tilfellet beregnes en interpolering av normalene i hvert punkt og hele intensitetsberegningen gjøres på nytt basert på den nye normalen. Dette er en mer krevende metode, men den har noen klare fordeler. Vi skal drøfte dette litt nedenfor.

Noen vurderinger

Gouraudshading har noen begrensninger det er viktig å være klar over. En konsekvens av metoden er at lyskilder som ikke berører et hjørne i en flate ikke får noen effekt på flaten

spot

En spotlight plassert som på figuren ovenfor vil ikke gi noen effekt på flaten siden lyset ikke påvirker intensitetsberegninger i noen av hjørnene.

På figuren nedenfor ser vi noen effekter av Gouraud-shading.

spheres

Fra venstre mot høyre ser vi:

  • En kule med flat skyggelegging. Merk macband effekten
  • En kule med glatt skyggelegging
  • En kule med flat skyggelegging og en spotlight plassert som en hodelykt hos betrakteren
  • Samme oppsett med glatt skyggelegging

Alle kulene er, i tillegg til hodelykten, belyst fra en kilde oppe til høyre med retningsbestemt lys uten avgrensning av lyskjeglen.

Vi kan prøve oss med to strategier for å bedre resultatet.

  • Vi kan øke antall flater kraftig
  • Vi kan modulere spotlighteffekten slik at selve lyskjeglen får en "mykere" kontur.

Disse effektene er demonstrert nedenfor.

spheres2

Kula til venstre har bare fått økt antall flater, mens de to andre kulene har varierende grad av "myk" avgrensning av lyskjeglen. Lyskjeglen settes ved


  glLighti(GL_LIGHT2, GL_SPOT_EXPONENT, m_SpotExp);

der m_SpotExp kan være i området [1,128]. Større tall gir mykere overgang.

Modulen Bordlampe demonstrerer spotlights og effekten på flater.

Referanser
  1. Gouraud shadingen.wikipedia.org/wiki/Gouraud_shading14-03-2009
  1. Phong shadingen.wikipedia.org/wiki/Phong_shading14-03-2009
Vedlikehold
Børre Stenseth, revidert 2010
Forklaring av>Skygge og glatting
til toppen