Light
為將3D物體模擬使其接近真實世界的樣子,除了顏色、貼圖、材質之外,光 (Light) 也是相當重要的元素之一。
光依性質可區分為Ambient Light、Diffuse Light與Specular Light。
Ambient Light (環境光),如同大自然的光源一般來自四面八方,因此稱為環境光。光源由四面八方均勻照射在物體上,其中一部分光源會被物體吸收,而未被吸收的光源,則會均勻向四面八方反射出去,因此不論物體位在何處,所得到的反射光強度均是一樣。在處理3D物體渲染 (Rendering) 時,環境光以指定強度與顏色的光影響物體,經過渲染之後,被照射的物體,在每個方向與角度上均受到等量的光線。
Diffuse Light (漫射光),Diffuse是指物體在光源下的實際呈現,除了少數物體如鏡子會完全反射射入的光源之外,大部分的物體會漫射射入的光源,這是由於物體常具有粗糙的表面,粗糙的表面則會造成射入光源產生漫射的效果,漫射光的特性是具有方向性且均勻照射到物體表面。
Specular Light (反射光),是指射入的光源對物體產生反射的情形,反射光的特性是具有方向性並使射入的光源以某個角度反射。
任何光源均由以上三種光所組成,只是所佔的比例不同而已。Phong Reflection Model則是由Ambient Light、Diffuse Light與Specular Light所組成。
光依來源可區分為Ambient Light、Directional Light、Point Light與Spot Light。
Directional Light (方向光),光源來自同一方向,如下圖所示。方向光通常用來模擬遠處或光源方向對物體表面一致性影響的情況,例如太陽光。
Point Light (點光),光源來自於一點,並向四面八方擴散,如下圖所示。點光通常用來場景中的任何光源,例如燈光。
Spot Light (聚光),類似於點光,光源同樣來自於一點,但限定向某一角度擴散,如下圖所示。
其中Diffuse Light與Specular Light分別由PhongMaterial
類別的下列方法處理:
getDiffuseColor()
:取得漫射光的顏色。setDiffuseColor()
:設定漫射光的顏色。getSpecularColor()
:取得反射光的顏色。setSpecularColor()
:設定反射光的顏色。getSpecularPower()
:取得反射光的強度。setSpecularPower()
:設定反射光的強度。
其次JavaFX支援Ambient Light與Point Light光源,分別由AmbientLight
與PointLight
類別處理,兩者皆繼承自LightBase
抽象類別。LightBase
抽象類別為處理光源的基礎類別,分別定義以下屬性:
color
:定義光源的顏色。lightOn
:定義是否開啟或關閉光源。
其方法包括:
getColor()
:取得光源的顏色。setColor()
:設定光源的顏色。isLightOn()
:判斷是否開啟或關閉光源,預設為true。setLightOn()
:設定是否開啟或關閉光源。
接著介紹AmbientLight
與PointLight
類別。
AmbientLight類別用以處理環境光,其建構函式如下,其中參數color
設定環境光的顏色:
public AmbientLight()
public AmbientLight(Color color)
請參考以下範例。
程式說明
範例加入AmbientLight
類別處理環境光,並設定環境光的顏色為黃色:
// 建立環境光
AmbientLight ambientlight = new AmbientLight();
ambientlight.setColor(Color.YELLOW);
ambientlight.getScope().add(sphere);
Group group = new Group();
group.getChildren().addAll(sphere, ambientlight);
...
執行結果
PointLight類別用以處理點光,其建構函式如下,其中參數color
設定點光的顏色:
public PointLight()
public PointLight(Color color)
請參考以下範例。
程式說明
範例加入PointLight
類別處理點光,為強調點光的來源,範例分別以setLayoutX()
與setLayoutY()
方法平移點光水平與垂直的位置,並以setTranslateZ()
方法設定點光的深度,產生點光來自遠方的效果:
// 建立點光
PointLight pointlight = new PointLight();
pointlight.setColor(Color.rgb(255, 255, 255, 1));
pointlight.setLayoutX(50);
pointlight.setLayoutY(50);
pointlight.setTranslateZ(-1000);
pointlight.getScope().add(sphere);
Group group = new Group();
group.getChildren().addAll(sphere, pointlight, ambientlight);
...