Top Description Fields Constructors Methods
javafx.scene.paint

public non-sealed Class PhongMaterial

extends Material
Class Inheritance
Imports
com.sun.javafx.beans.event.AbstractNotifyListener, com.sun.javafx.scene.paint.MaterialHelper, com.sun.javafx.sg.prism.NGPhongMaterial, com.sun.javafx.tk.Toolkit, javafx.beans.Observable, javafx.beans.property.DoubleProperty, .ObjectProperty, .SimpleDoubleProperty, .SimpleObjectProperty, javafx.scene.AmbientLight, .LightBase, javafx.scene.image.Image, .WritableImage, javafx.scene.shape.Shape3D, .TriangleMesh

A material based on the Phong shading model. This material has several independent components that together give an object its appearance using the Phong shading model. The material interacts with each illuminating light separately, and the contribution from each light is summed.

The diffuse and specular components can be specified by a (solid) color and/or a texture map (represented as an image). If both are applied, their values are multiplied. For example:
Color#LIMEGREEN * Rainbow gradient = Green gradient

Color#CYAN * Map = Tinted map

Note

the self-illumination component can not currently be specified as a color. However, a color behaves like a map (of any size) of a single color. Creating a 1x1 pixel map of that color will have the same effect.

PhongMaterial is not suitable for surfaces that act like mirrors and reflect their environment, such as reflective metals, water, and reflective ceramics. Neither does light refract (bend) when passing through transparent or translucent materials such as water, glass, or ice. These materials rely on Fresnel effects that are not implemented for this material.

Components

Incident ray schematic While in the physical world each light ray goes through a single path of reflection, transmission, or absorption, in the computational world a number of adjacent rays are averaged into a single one that can split into multiple paths. This approximation simplifies the computation model greatly while still allowing realistic rendering. The validity of this approximation depends on microscopic details of the material, but it holds well for the vast majority of cases. When an averaged incident ray (blue) hits the surface, it can split into many rays depending on the values of the components of the material: rays that are either transmitted through the material (green) or reflected in all directions via scattering (purple) depend on the diffuse component; rays that are reflected (orange), which depend on the incident angle, are controlled by the specular component.
Material types
Transparent schematic Lambertian schematic Reflective schematic
Transparent Lambertian Reflective

Materials whose diffuse component allows only transmitted rays are transparent. These still have a specular component, otherwise they will be invisible (no such material exists). Materials without a specular component and whose diffuse component allows only reflected rays exhibit Lambertian reflectance. Lambertian materials reflect light in all directions equally. Materials with a specular component and a diffuse component that only allows weak reflectance are reflective.

Diffuse

The diffuse component, sometimes called albedo, serves as the base color of the surface. It represents light that is not reflected directly from the surface and instead enters the material.
The alpha channel of the diffuse component controls the light that passes through it (transmitted). Decreasing the alpha value increases the transparency of the material and causes the object to appear translucent, and ultimately makes it transparent. Materials such as glass and plastics can be simulated with a low alpha value.
Light that isn't transmitted undergoes subsurface scattering that causes it to be absorbed in the material or be reflected back to the surface, exiting in (approximately) all directions (irrespective of the incident angle). The RGB channels of the diffuse component controls which colors are absorbed and which are reflected, giving the material its base color. The higher one of the RGB values is, the more that material reflects that color.

The diffuse component interacts with all lights - both those that have directionality and AmbientLight, which simulates a light that comes from all directions.

Important Note

there is currently a bug that causes objects with 0 opacity to not render at all (despite having a specular or a self-illumination component). Setting the opacity to 1/255 instead will give the desirable result.

Specular

The specular component represents light that is reflected directly from the surface. For most materials, the color of the specular component is on the gray scale regardless of the diffuse component's color. This means that the specular highlight will be the light's color and not the material's color. These materials are sometimes called dielectrics. Metals, on the other hand, reflect a color similar to their diffuse color (like yellow for gold or reddish for copper) and get most of their appearance from the specular color. These materials are sometimes called conductors.

The spread of the surface-reflected rays simulates the microgeometry that causes adjacent beams to be reflected in different directions. Smooth surfaces' microgeometry varies little, causing them to have a strong specular component that results in a glossy look, such as plastics, finished wood, and polished metals. Conversely, rough surfaces have a varying microgeometry, weak specular component, and a matte look, such as unfinished wood, fabric, and cardboard. This spread is controlled by the specular power, sometimes called smoothness or, conversely, roughness. A larger specular power simulates a smoother object, which results in a smaller reflection.

The specular component interacts only with lights that have directionality (not AmbientLight) as it depends on the incident ray direction, and also on the viewer (camera) position since it depends on the reflectance direction.

The alpha component of the specular color is not used at this time.

Self-Illumination

The self-illumination component, also called emissive, represents light emitted by the object. It does not interact with light sources and as such the viewer position does not matter. Specifying this component does not cause the object to serve as a light source - a light has to be added at the position of the object with a color that matches this color. If a multi-colored map is used, several lights of matching colors can be positioned appropriately in the object's volume to give a realistic appearance.

The alpha component of the self-illumination color is not used at this time.

Bump

The bump component gives the illusion of small height changes on the surface, like bumps and ridges. It is a normal map (not a height map or a displacement map), which works by modifying the normals of surfaces on the object, causing light to interact differently with the surface than it would have without it. Tree trunks and rough stones can be simulated with a bump map.

Bump maps are less expensive than changing a mesh by subdividing a surface into many polygons facing different ways. If the physical geometry of the surface is not important (for example, for intersection calculations), it's advised to use a bump map.

The alpha component of the bump map is not used at this time.

Mathematical Model

Vectors in the Phong model The image on the left depicts a standard schematic of a scene with a mesh, a light source, and a camera. The black curve is the required geometry, and the blue lines are the polygons (mesh) representing this geometry. Four normalized vectors are considered for each point on the surface:
L - the vector from the surface to the light source;
N - the normal vector of the surface;
V - the vector from the surface to the viewer (camera);
R - the reflection vector of L from the surface. R can be calculated from L and N: R=2(L⋅N)N - L.

The diffuse and specular components are comprised of 3 factors: the geometry, the light's color, and the material's color, each considered at every point on the surface. The light's color computation is described in LightBase (and its subclasses). The material's color computation, as described above, is the multiplication of the color and map properties. These factors are multiplied to get the final color.

Bump

The default normal vector of a point on the polygon is N=(0, 0, 1) (facing away from the surface). If a bump map is specified, this vector will have a different value based on the RGB values in the bump map: N=2 * RGB - 1. The default value for a bump map (corresponding to the default normal) is RGB=(0.5, 0.5, 1), which is why bump maps tend to be blueish.

We will treat N as the normal vector after applying a bump map, if available.

Diffuse

The diffuse component represents light scattered from the surface in all directions, hence, it depends on the interaction between the light and the surface (and independent of the viewer position): L⋅N. L⋅N is the geometric factor of the diffuse component. It moderates the intensity of the color resulting from the light hitting the surface at different angles. If the light ray is parallel to the surface, L⋅N=0 and the diffuse contribution of the light will be 0; if the light ray is perpendicular to the surface (coincides with the normal vector), L⋅N=1 and no reduction in intensity occurs.

Defining the light's color as CL, and the material's diffuse color as CDM, we multiply the 3 factors described above: L⋅N * CL * CDM. For i lights illuminating the surface, the contribution of each light is summed:
Σi(Li⋅N * CLi * CDM) = Σi(Li⋅N * CLi) * CDM (since CDM is a property of the material and is the same for all lights).

Since AmbientLight simulates a light coming from and scattered in all directions, it contributes fully to the diffuse component (L⋅N=1). We will define all the ambient lights' contribution as A=Σi(CLi) and all the other lights' (that have a light vector) as D=Σi(Li⋅N * CLi). The total diffuse component contribution is then (A+D) * CDM.

Specular

The specular component represents light reflected from the surface in a mirror-like reflection, hence, it depends on the interaction between the reflected light and the viewer position: R⋅V. As similarly explained in the diffuse component section, the geometric contribution is strongest when the viewer is aligned with the reflection vector and is non-existent when they are perpendicular.

High specular power Low specular power The specular power, P, represents the smoothness of the surface. Smoother surfaces have more narrow reflections and their specular power is smaller (right image), while rougher surfaces have more dispersed reflections and their specular power is larger (left image). Since 0≤R⋅V≤1, the term (R⋅V)P decreases as P increases, giving a smaller contribution.

Like with the diffuse component, the resulting specular color is computed by multiplying the geometric factor, the light's color, and the material's specular color, CSM, for each light:
Σi((Ri⋅V)P * CLi) * CSM, and defining the specular lights' contribution as S=Σi((Ri⋅V)P * CLi), the total specular component contribution is S * CSM.

Self-Illumination

The self-illumination component represents light emanating from the surface, hence, it is not affected by lights, the geometry, or the viewer position. Its contribution is just the material's self-illumination color, CLM.

Summary

The final color at the point of the computation is then: (A+D) * CDM + S * CSM + CLM.

Examples

This section shows examples for simulating various common materials. Each image will be accompanied by the values used for the material. Values that aren't specified are the default ones.

Gloss

The specular power controls the size of specular highlights, which changes the gloss or smoothness look. Lower powers create larger highlights and vice versa. Some plastics and marble exhibit this behavior, as shown here with 2 billiard balls:
Materials values
Image Yellow ball with low specular power Red ball with high specular power
Diffuse color Color.YELLOW.darker() Color.RED.darker()
Specular color Color.WHITE Color.WHITE
Specular power 10 150

Transparency

Some materials are transparent/translucent, allowing most of the light through, like glass and plastics. This is achieved with low diffuse opacity (alpha) values. Tint can be achieved with small RGB values in addition. The smoothness of these materials also means a specular component is present with strength that depends on the finish/polish of the material. A high brightness specular color gives a more glossy look and a low brightness one gives a more matte look.
Material values
Image Transparency with no specular reflection Transparency with low specular reflection Transparency with high specular reflection Tinted transparency with low specular reflection
Diffuse color Color.rgb(0, 0, 0, 0.3) Color.rgb(0, 0, 0, 0.3) Color.rgb(0, 0, 0, 0.3) Color.rgb(75, 0, 0, 0.15)
Specular color Color.hsb(0, 0, 0) Color.hsb(0, 0, 45) Color.hsb(0, 0, 90) Color.hsb(0, 0, 45)

Specular Color

Metals reflect their own color rather than the light's full color. In this case, the specular color should be similar to the diffuse color, with its brightness affecting the shininess/polish levels. Copper and gold are shown here.
Material values
Image Copper with low specular reflection Copper with medium specular reflection Copper with high specular reflection Gold with low specular reflection Gold with high specular reflection
Diffuse color Color.hsb(20, 85, 70) Color.hsb(20, 85, 70) Color.hsb(20, 85, 70) Color.hsb(41, 82, 92) Color.hsb(41, 82, 92)
Specular color Color.hsb(20, 85, 40) Color.hsb(20, 85, 70) Color.hsb(20, 85, 100) Color.hsb(41, 82, 30) Color.hsb(41, 82, 92)

Maps and Surface Detail

The specular and bump maps can provide surface details that make the object look more realistic. A tree trunk, which has none-to-low specularity, has a lot of grooves that can be emphasized with a bump map:
Diffuse map
Diffuse map
Bump map
Bump map
Model with maps applied
Tree trunk with bump map Tree trunk with diffuse map Tree trunk with diffuse and bump maps
Bump Diffuse Bump+Diffuse
A diffuse color of HSB=(0, 0, 60) has been used to darken the wood.

Polished wood, like that used in housing, has a strong specular component due to the finish and buff. A combination of a specular and a bump map highlights the details in the wood:

Diffuse map
Diffuse map
Specular map
Specular map
Bump map
Bump map
Model with maps applied
Finished wood with diffuse map Finished wood with diffuse and specular maps Finished wood with diffuse and bump maps Finished wood with diffuse, specular, and bump maps
Diffuse Diffuse+Specular Diffuse+Bump Diffuse+Specular+Bump
A specular power of 100 has been used to give a more smooth look.

Texture Animation

Texture animation and runtime effects can be achieved in different ways. Firstly, an animated GIF can be used as the Image for texture maps, as demonstrated here when used as a diffuse map:
Animation gif Animation gif as map

Secondly, by using a WritableImage, the pixel values can be changed programmatically, creating a live texture as demonstrated for the diffuse map by this code snippet that repaints the image left to right and top to bottom:

Writable image as map
WritableImage diffuseMap = ...
material.setDiffuseMap(diffuseMap);
var timer = new AnimationTimer() {
    int x, y;

    @Override
    public void handle(long now) {
        diffuseMap.getPixelWriter().setColor(x, y, Color.color(0, 0, 1, 0.5));
        x++;
        if (x > diffuseMap.getWidth() - 1) {
            x = 0;
            y++;
            if (y > diffuseMap.getHeight() - 1) {
                stop();
            }
        }
    }
};
timer.start();
Other maps can be modified as well, producing various effects.
Another way to animate textures is done through changing the texture coordinates of the mesh, the explanation for which is out of scope for this class.
Since
JavaFX 8.0
See Also
LightBase, Shape3D

Field Summary

Modifier and TypeField and Description
private ObjectProperty<Image>
bumpMap

The bump map of this PhongMaterial, which is a normal map stored as an RGB image.

private boolean
private ObjectProperty<Color>
diffuseColor

The diffuse color of this PhongMaterial.

private boolean
private ObjectProperty<Image>
diffuseMap

The diffuse map of this PhongMaterial.

private boolean
private Image
private Image
private Image
private Image
private NGPhongMaterial
peer

The peer node created by the graphics Toolkit/Pipeline implementation

private final AbstractNotifyListener
private ObjectProperty<Image>
selfIlluminationMap

The self illumination map of this PhongMaterial.

private boolean
private ObjectProperty<Color>
specularColor

The specular color of this PhongMaterial.

private boolean
private ObjectProperty<Image>
specularMap

The specular map of this PhongMaterial.

private boolean
private DoubleProperty
specularPower

The specular power of this PhongMaterial.

private boolean

Constructor Summary

AccessConstructor and Description
public
PhongMaterial()

Creates a new instance of PhongMaterial class with a default Color.WHITE diffuseColor property.

public
PhongMaterial(Color
the color of the diffuseColor property
diffuseColor
)

Creates a new instance of PhongMaterial class using the specified color for its diffuseColor property.

public
PhongMaterial(Color
the color of the diffuseColor property
diffuseColor
,
Image
the image of the diffuseMap property
diffuseMap
,
Image
the image of the specularMap property
specularMap
,
Image
the image of the bumpMap property
bumpMap
,
Image
the image of the selfIlluminationMap property
selfIlluminationMap
)

Creates a new instance of PhongMaterial class using the specified colors and images for its diffuseColor properties.

Method Summary

Modifier and TypeMethod and Description
public final ObjectProperty<Image>
public final ObjectProperty<Color>
public final ObjectProperty<Image>
public final Image
public final Color
public final Image
pack-priv NGPhongMaterial
public final Image
public final Color
public final Image
public final double
public final ObjectProperty<Image>
public final void
public final void
public final void
pack-priv void
public final void
public final void
public final void
public final void
setSpecularPower(double value)

public final ObjectProperty<Color>
public final ObjectProperty<Image>
public final DoubleProperty
public String
toString()

Overrides java.lang.Object.toString.

Returns a string representation of the object.

pack-priv void
Inherited from javafx.scene.paint.Material:
dirtyPropertyisDirty

Field Detail

bumpMapback to summary
private ObjectProperty<Image> bumpMap

The bump map of this PhongMaterial, which is a normal map stored as an RGB image.

Default Value
null
bumpMapDirtyback to summary
private boolean bumpMapDirty
diffuseColorback to summary
private ObjectProperty<Color> diffuseColor

The diffuse color of this PhongMaterial.

Default Value
Color.WHITE
diffuseColorDirtyback to summary
private boolean diffuseColorDirty
diffuseMapback to summary
private ObjectProperty<Image> diffuseMap

The diffuse map of this PhongMaterial.

Default Value
null
diffuseMapDirtyback to summary
private boolean diffuseMapDirty
oldBumpMapback to summary
private Image oldBumpMap
oldDiffuseMapback to summary
private Image oldDiffuseMap
oldSelfIlluminationMapback to summary
private Image oldSelfIlluminationMap
oldSpecularMapback to summary
private Image oldSpecularMap
peerback to summary
private NGPhongMaterial peer

The peer node created by the graphics Toolkit/Pipeline implementation

platformImageChangeListenerback to summary
private final AbstractNotifyListener platformImageChangeListener
selfIlluminationMapback to summary
private ObjectProperty<Image> selfIlluminationMap

The self illumination map of this PhongMaterial.

Default Value
null
selfIlluminationMapDirtyback to summary
private boolean selfIlluminationMapDirty
specularColorback to summary
private ObjectProperty<Color> specularColor

The specular color of this PhongMaterial.

Default Value
null
specularColorDirtyback to summary
private boolean specularColorDirty
specularMapback to summary
private ObjectProperty<Image> specularMap

The specular map of this PhongMaterial.

Default Value
null
specularMapDirtyback to summary
private boolean specularMapDirty
specularPowerback to summary
private DoubleProperty specularPower

The specular power of this PhongMaterial.

Default Value
32.0
specularPowerDirtyback to summary
private boolean specularPowerDirty

Constructor Detail

PhongMaterialback to summary
public PhongMaterial()

Creates a new instance of PhongMaterial class with a default Color.WHITE diffuseColor property.

PhongMaterialback to summary
public PhongMaterial(Color diffuseColor)

Creates a new instance of PhongMaterial class using the specified color for its diffuseColor property.

Parameters
diffuseColor:Color

the color of the diffuseColor property

PhongMaterialback to summary
public PhongMaterial(Color diffuseColor, Image diffuseMap, Image specularMap, Image bumpMap, Image selfIlluminationMap)

Creates a new instance of PhongMaterial class using the specified colors and images for its diffuseColor properties.

Parameters
diffuseColor:Color

the color of the diffuseColor property

diffuseMap:Image

the image of the diffuseMap property

specularMap:Image

the image of the specularMap property

bumpMap:Image

the image of the bumpMap property

selfIlluminationMap:Image

the image of the selfIlluminationMap property

Method Detail

bumpMapPropertyback to summary
public final ObjectProperty<Image> bumpMapProperty()
diffuseColorPropertyback to summary
public final ObjectProperty<Color> diffuseColorProperty()
diffuseMapPropertyback to summary
public final ObjectProperty<Image> diffuseMapProperty()
getBumpMapback to summary
public final Image getBumpMap()
getDiffuseColorback to summary
public final Color getDiffuseColor()
getDiffuseMapback to summary
public final Image getDiffuseMap()
getNGMaterialback to summary
pack-priv NGPhongMaterial getNGMaterial()

Implements abstract javafx.scene.paint.Material.getNGMaterial.

Annotations
@Override
getSelfIlluminationMapback to summary
public final Image getSelfIlluminationMap()
getSpecularColorback to summary
public final Color getSpecularColor()
getSpecularMapback to summary
public final Image getSpecularMap()
getSpecularPowerback to summary
public final double getSpecularPower()
selfIlluminationMapPropertyback to summary
public final ObjectProperty<Image> selfIlluminationMapProperty()
setBumpMapback to summary
public final void setBumpMap(Image value)
setDiffuseColorback to summary
public final void setDiffuseColor(Color value)
setDiffuseMapback to summary
public final void setDiffuseMap(Image value)
setDirtyback to summary
pack-priv void setDirty(boolean value)

Overrides javafx.scene.paint.Material.setDirty.

Annotations
@Override
setSelfIlluminationMapback to summary
public final void setSelfIlluminationMap(Image value)
setSpecularColorback to summary
public final void setSpecularColor(Color value)
setSpecularMapback to summary
public final void setSpecularMap(Image value)
setSpecularPowerback to summary
public final void setSpecularPower(double value)
specularColorPropertyback to summary
public final ObjectProperty<Color> specularColorProperty()
specularMapPropertyback to summary
public final ObjectProperty<Image> specularMapProperty()
specularPowerPropertyback to summary
public final DoubleProperty specularPowerProperty()
toStringback to summary
public String toString()

Overrides java.lang.Object.toString.

Doc from java.lang.Object.toString.

Returns a string representation of the object. Satisfying this method's contract implies a non-null result must be returned.

Annotations
@Override
updatePGback to summary
pack-priv void updatePG()

Implements abstract javafx.scene.paint.Material.updatePG.

Annotations
@Override