WaBis

walter.bislins.ch

JSG3D: Kamera-Beleuchtung

Die Kamera-Beleuchtung entspricht einer Lichtquelle, die an der Kamera montiert ist und die Scene von vorne beleuchtet. Die Kamera-Beleuchtung ist eine diffuse Beleuchtung ohne Reflexionen. Sie kann gut mit der Ambient-Beleuchtung kombiniert werden, kann aber auch mit der Phong-Beleuchtung kombiniert werden.

Demo

In dieser Demo können die Farbsättigung der Flächen (AreaColSat), die Kamera- und Ambient-Bleuchtung (CamLightCol, AmbiLightCol, LightSat) und die Reflexionsanteile der entsprechenden Beleuchtung (CamRefl, AmbiRefl) eingestellt werden.

Die Col-Regler bestimmten die Farbe, die Sat-Regler bestimmen die Helligkeit und Sättigung der Farbe:

  • Sat = 0.0 → schwarz
  • Sat = 0.5 → maximale Sättigung der Farbe
  • Sat = 1.0 → weiss
function CreateGraph() {
  var g3d = NewGraph3D( {
    AreaDrawMode: DrawMode,
    Aperture: Aperture,
    CamLight: JsgColor.HL( CamLightCol, LightSat ),
    AmbientLight: JsgColor.HL( AmbiLightCol, LightSat ),
    Attr: {
      AreaColor: JsgColor.HL( 4/6, AreaColSat ),
      AreaBackColor: JsgColor.HL( 1, AreaColSat )
    },
    Lighting: {
      ApplyPhong: false,
      ApplyCamLight: true,
      ApplyAmbient: true,
      CamRefl: CamRefl,
      AmbiRefl: AmbiRefl
    },
    BackLighting: {
      Dimm: Dimm
    },
    :
  } );
  :
}

Properties der Kamera-Beleuchtung

Die Kamera-Beleuchtung wird durch folgende Properties beeinflusst:

JsgEleData.AreaDrawMode
Zeichenmodus für Flächen. Damit Flächen gefüllt werden, muss Modus 2 (Area) oder 3 (Area und Grid) gewählt werden.
JsgEleLighting.ApplyCamLight
Schaltet die Kamera-Beleuchtung ein oder aus.
JsgScene.CamLight
Globale Farbe und Helligkeit (JsgColor) des Kamera-Lichtes.
JsgEleAttr.AreaColor, JsgEleAttr.AreaBackColor
Farbe einer Fläche (JsgColor).
JsgEleLighting.CamRefl
Anteil der Reflexion des Kameralichtes für die Fläche (0..1).
JsgEleLighting.Dimm
Abdunklung einer Flächenseite gegenüber der anderen (0..1).
JsgCamera.Aperture
Die Blende (Aperture) beeinflusst die globale Helligkeit der Grafik (< 1 Abdunklung der Szene, > 1 Aufhellung).

ApplyCamLight, CamRefl, AreaColor und AreaBackColor sind Eigenschaften einer Fläche und können für jede Fläche separat definiert werden. ApplyCamLight, CamRefl und Flächen-Farbe kann für vorder und Rückseite einer Fläche separat eingestellt werden (AreaColor, AreaBackColor). Mit dem Property Dimm kann eine Flächenseite gegenüber der anderen abgedunkelt werden.

Berechnung der Beleuchtung

Die resultierende Farbe eines Flächen-Elementes bei der Kamera-Beleuchtung setzt sich zusammen aus der Mischung von CamLight und AreaColor, wobei der Anteil von CamLight durch CamRefl gesteuert wird. Die Helligkeit eines Flächen-Elementes hängt von der Orientierung der Fläche zur Blickrichtung der Kamera ab. Zeigt der Normalen-Vektor auf die Kamera zu oder von ihr weg, hat die Fläche die maximale Helligkeit. Ist der Winkel des Normalen-Vektors zur Blickrichtung 90°, ist der Anteil der Kamera-Beleuchtung Null.

Resultat = CamLight * AreaColor * CamRefl * (Normalen-Vektor * Vektor-zur-Kamera)

Zeigt der Normalen-Vektor einer Fläche in Richtung der Kamera, wird die Beleuchtung für die Flächenvorderseite angewandt. Zeigt der Vektor von der Kamera weg, wird die Beleuchtung der Flächenrückseite angewandt.

Um starke Kontraste zwischen Flächen-Elementen zu vermeiden, kann die Kamera-Beleuchtung mit der Ambient-Beleuchtung kombiniert werden (sieh Demo). Je grösser der Anteil der AmbiRefl im Verhältnis zur CamRefl ist, umso kleiner der Kontrast.

Code

var resolution = 20;

var par = {
  CamLightCol: 1/3,
  AmbiLightCol: 0,
  LightSat: 1,
  AreaColSat: 0.85,
  CamRefl: 1,
  AmbiRefl: 0.1,
  Dimm: 1,
  Aperture: 0.9,
  DrawMode: 2
};

var myGraph = CreateGraph();

function CreateGraph() {
  var g3d = NewGraph3D( { SyncMode: true } );

  g3d.SetCamera( {
    SceneSize: 3,
    CamHAng: 10,
    CamVAng: 35,
    CamDist: 5,
    CamViewCenter: JsgVect3.New( 0, 0, -0.2 ),
    Zoom: 1.2,
    Aperture: par.Aperture
  } );

  g3d.SetLight( {
    CamLight: JsgColor.HL( par.CamLightCol, par.LightSat ),
    AmbientLight: JsgColor.HL( par.AmbiLightCol, par.LightSat )
  } );

  g3d.SetDefaultEleData( {
    AreaDrawMode: par.DrawMode,
    Attr: {
      AreaColor: JsgColor.HL( 4/6, par.AreaColSat ),
      AreaBackColor: JsgColor.HL( 1, par.AreaColSat )
    },
    Lighting: {
      ApplyPhong: false,
      ApplyCamLight: true,
      ApplyAmbient: true,
      CamRefl: par.CamRefl,
      AmbiRefl: par.AmbiRefl
    },
    BackLighting: {
      Dimm: par.Dimm
    }
  } );

  var pi = Math.PI, pi2 = 2 * pi;

  g3d.AddAreasFrom3DFunc( {
    Func: function( a, b, p ) {
      var rx = p.Radius1 - Math.cos(b) * p.Radius2;
      var x = rx * Math.sin(a);
      var y = rx * Math.cos(a);
      var z = p.Radius2 * Math.sin(b);
      return [ x, y, z ];
    },
    Min: pi/3,
    Max: pi2,
    Min2: 0,
    Max2: pi2,
    Steps: 2 * resolution,
    Steps2: resolution,
    Radius1: 1,
    Radius2: 0.5
  } );

  return g3d;
}

var panel = ControlPanels.NewPanel( { 
  ModelRef: 'par', NCols: 2, PanelFormat: 'Slider', 
  OnModelChange: Update, 
  Format: 'fix0', Digits: 2, ReadOnly: true
} );

panel.AddSliderField( { Name: 'CamLightCol', ColSpan: 2, Min: 0, Max: 1 } );
panel.AddTextField( { Name: 'CamLightCol' } );

panel.AddSliderField( { Name: 'AmbiLightCol', ColSpan: 2, Min: 0, Max: 1 } );
panel.AddTextField( { Name: 'AmbiLightCol' } );

panel.AddSliderField( { Name: 'LightSat', ColSpan: 2, Min: 0, Max: 1 } );
panel.AddTextField( { Name: 'LightSat' } );

panel.AddSliderField( { Name: 'AreaColSat', ColSpan: 2, Min: 0, Max: 1 } );
panel.AddTextField( { Name: 'AreaColSat' } );

panel.AddSliderField( { Name: 'CamRefl', ColSpan: 2, Min: 0, Max: 1 } );
panel.AddTextField( { Name: 'CamRefl' } );

panel.AddSliderField( { Name: 'AmbiRefl', ColSpan: 2, Min: 0, Max: 1 } );
panel.AddTextField( { Name: 'AmbiRefl' } );

panel.AddSliderField( { Name: 'Dimm', ColSpan: 2, Min: 0, Max: 1.5 } );
panel.AddTextField( { Name: 'Dimm' } );

panel.AddSliderField( { Name: 'Aperture', ColSpan: 2, Min: 0, Max: 2 } );
panel.AddTextField( { Name: 'Aperture' } );

var panel2 = ControlPanels.NewPanel( { 
  ModelRef: 'par',
  OnModelChange: Update
} );

panel2.AddRadiobuttonField( {
  Name: 'DrawMode', ValueType: 'int',
  Items: [
    { Name: '1: Grid', Value: 1 },
    { Name: '2: Area', Value: 2 },
    { Name: '3: Beide', Value: 3 }
  ]
} );

panel.Render();
panel2.Render();

function Update() {
  panel.Update();
  panel2.Update();

  var g3d = myGraph;

  g3d.SetLight( {
    CamLight: JsgColor.HL( par.CamLightCol, par.LightSat ),
    AmbientLight: JsgColor.HL( par.AmbiLightCol, par.LightSat )
  } );

  g3d.ChangeDefaultEleData( {
    AreaDrawMode: par.DrawMode,
    Attr: {
      AreaColor: JsgColor.HL( 4/6, par.AreaColSat ),
      AreaBackColor: JsgColor.HL( 1, par.AreaColSat )
    },
    Lighting: {
      CamRefl: par.CamRefl,
      AmbiRefl: par.AmbiRefl
    },
    BackLighting: {
      Dimm: par.Dimm
    }
  } );

  g3d.SetCameraAperture( par.Aperture );
  g3d.DrawDisplayList();
}

Weitere Infos zur Seite
Erzeugt Sonntag, 10. August 2014
von wabis
Zum Seitenanfang
Geändert Sonntag, 21. August 2016
von wabis