Phần 8 (tt) : Hiệu ứng - Effect
17.Lighting :
Hiệu ứng Lighting giả lập một nguồn chiếu sáng trên node, để cho ra node có dạng 3D. Để sử dụng hiệu ứng lighting cho node hoặc group, chúng ta sử dụng lớp Lighting thuộc gói javafx.scene.effect và đưa vào node hoặc group qua phương thức setEffect().
a.Các thuộc tính :
kiểu
|
Tên thuộc tính
|
Giá trị mặc định
|
Miêu tả
|
Light
|
Light
|
DistantLight
|
Kiểu Light nào được sử dụng.
|
Effect
|
bumpInput
|
null
|
Sử dụng bump map
|
Effect
|
contentInput
|
null
|
Sử dụng content input
|
DoubleProperty
|
diffuseConstant
|
1.0
|
Cường độ khuếch tán, giá trị từ 0 đến 2.
|
DoubleProperty
|
specularConstant
|
0.3
|
Cường độ phản chiếu, giá trị từ 0 đến 2.
|
DoubleProperty
|
specularExponent
|
2.0
|
Độ sáng chói, giá trị từ 0 đến 4.
|
DoubleProperty
|
surfaceScale
|
1.5
|
Chiều cao được gán đến các pixel, giá trị từ 0 đến 10.
|
b. Thuộc tính surfaceScale :
Để tạo ra hiệu ứng 3D trên bề mặt 2D, lighting dựa vào giá trị opacity của mỗi pixel để xác định chiều cao mỗi pixel sẽ như thế nào khi được chiếu sáng. Transparent pixels (pixel trong suốt) xuất hiện chìm và opaque pixels (pixel không trong suốt) xuất hiện nổi. Để tăng hoặc giảm độ chìm nổi của các pixel, chúng ta sử dụng thuộc tính surfaceScale, giá trị của nó nằm trong khoảng từ 0 đến 10. Giá trị surfaceScale càng cao, thì cảm giác 3D càng rõ nét.
Sử dụng hiệu ứng Lighting với surfaceScale = 10
c. Thuộc tính bumpInput :
BumpInput là input mà thuộc tính surfaceScale chỉ tác động lên input này, những phần khác ngoài bumpInput surfaceScale không tác động đến. Tức là độ chìm nổi chỉ thể hiện trên input này. Mặc định, nếu bumInput là null, node sẽ là bumpInput.
BumpInput là 1 effect thuộc gói javafx.scene.effect. Theo quan điểm của tôi, các effect làm bumpInput phải có input là ImageInput, nhưng bắt buộc Image đó phải có nền là trong suốt.
Ví dụ :
Đây là image có nền trong suốt
Sử dụng image làm input cho DropShadow và DropShadow này làm bumpInput
Code :
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.effect.DropShadow;
import javafx.scene.effect.ImageInput;
import javafx.scene.effect.Lighting;
import javafx.scene.image.Image;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class exampleLighting extends Application {
@Override
public void start(Stage primaryStage) {
Image image = new Image("graphics/javafx1.gif", 180, 100, true, true);
// Tạo hiệu ứng DropShadow
DropShadow dropShadow = new DropShadow();
dropShadow.setInput(new ImageInput(image, 0, 45));
// Hiệu ứng lighting
Lighting lighting = new Lighting();
lighting.setSurfaceScale(10);
// định nghĩa BumpInput
lighting.setBumpInput(dropShadow);
Circle circle = new Circle(100, 100, 100);
circle.setFill(Color.YELLOW);
circle.setEffect(lighting);
Group root = new Group();
root.getChildren().add(circle);
Scene scene = new Scene(root, 400, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
|
d. Thuộc tính ContentInput :
ContentInput cũng là 1 input và input này cũng là 1 effect, nhưng thuộc tính surfaceScale không tác động đến nó. Mục đích của nó dùng để làm nền thay thế nền của node.
e. Thuộc tính Light :
JavaFX cung cấp 3 kiểu Light được xây dựng sẵn : distant light, point light, và spot light.
** * Distant light :
Distant light còn được gọi là directional light (chiếu sáng định hướng) hay linear light (chiếu sáng tuyến tính). Distant light phát ra các tia sáng song song theo hướng định sẵn chiếu lên node.
Distant light được Sun xây dựng trong Distant class thuộc gói javafx.scene.effect.Light.
Các thuộc tính của Distant :
kiểu
|
Tên thuộc tính
|
Giá trị mặc định
|
Miêu tả
|
DoubleProperty
|
azimuth
|
45
|
Phương chiếu sáng.
|
DoubleProperty
|
elevation
|
45
|
Điểm chiếu sáng.
|
Azimuth là phương chiếu sáng, được tính bằng độ. Ý nghĩa là nó sẽ lệch bao nhiêu độ so với node được chiếu sáng. Giá trị 0 độ được đặt ở vị trí 3 giờ của đồng hồ, 90 độ ở vị trí 6 giờ, 180 ở vị trí 9 giờ, 270 độ ở vị trí 12 giờ tương đương giá trị -90 độ.
Azimuth cắt node tại 2 điểm A, B (hình minh họa bên dưới). Với AB là giao tuyến, chúng ta vẽ một mặt phẳng vuông góc với mặt phẳng chứa node. Trên mặt phẳng này, chúng ta vẽ tiếp 1 đường tròn có đường kính AB. Đường tròn này được gọi là tập hợp điểm elevation. Elevation là 1 điểm nằm trên đường tròn này. Giá trị của elevation được tính bằng độ, ý nghĩa là nó sẽ lệch bao nhiêu độ so với phương chiếu sáng. Tại elevation, các tia sáng song song sẽ chiếu sáng lên node hoặc group.
Cách sử dụng Distant Light :
// Tạo đối tượng Distant với giá trị thuộc tính mặc định
Light.Distant distant = new Light.Distant();
// Tạo đối tượng Distant với giá trị Azimuth = 30, Elevation = 60, Color = Green. Color là màu chiếu sáng dành cho node. Nếu không định nghĩa biến Color, màu chiếu sáng là màu của node
Light.Distant distant = new Light.Distant(30,60, Color.GREEN);
|
Một số phương thức của Distant Light :
kiểu trả về
|
Phương thức
|
Miêu tả
|
void
|
setAzimuth(double value)
|
Thiết lập giá trị thuộc tính azimuth
|
double
|
getAzimuth()
|
Trả về giá trị thuộc tính azimuth
|
void
|
setElevation(double value)
|
Thiết lập giá trị thuộc tính elevation
|
double
|
getElevation()
|
Trả về giá trị thuộc tính elevation
|
Ví dụ : Tạo 1 circle với hiệu ứng Lighting có thuộc tính Light là Distant
Code:
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.effect.Light;
import javafx.scene.effect.Light.Distant;
import javafx.scene.effect.Lighting;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class exampleDistantLight extends Application {
Distant distant;
public void start(Stage primaryStage) {
// Circle
Circle circle = new Circle(200, 180, 150, Color.YELLOW);
// Slider dành cho Arimuth
Label labelArimuth = new Label("Arimuth : ");
labelArimuth.setLayoutX(10);
labelArimuth.setLayoutY(340);
Slider slideArimuth = new Slider(0, 360, 45);
slideArimuth.setLayoutX(65);
slideArimuth.setLayoutY(340);
slideArimuth.setPrefWidth(300);
slideArimuth.setShowTickLabels(true);
slideArimuth.setShowTickMarks(true);
// Slider dành cho Elevation
Label labelElevation = new Label("Elevation : ");
labelElevation.setLayoutX(10);
labelElevation.setLayoutY(370);
Slider sliderElevation = new Slider(0, 360, 45);
sliderElevation.setLayoutX(65);
sliderElevation.setLayoutY(370);
sliderElevation.setPrefWidth(300);
sliderElevation.setShowTickLabels(true);
sliderElevation.setShowTickMarks(true);
// Định nghĩa đối tượng Distant
distant = new Light.Distant();
distant.setAzimuth(45);
distant.setElevation(45);
// Định nghĩa hiệu ứng Lighting
Lighting lighting = new Lighting();
lighting.setLight(distant);
lighting.setSurfaceScale(10);
//Áp dụng hiệu ứng Lighting vào Circle
circle.setEffect(lighting);
// Event khi thay đổi giá trị Arimuth
slideArimuth.valueProperty().addListener((observable, oldValue, newValue) -> distant.setAzimuth(newValue.doubleValue()));
// Event khi thay đổi giá trị Elevation
sliderElevation.valueProperty().addListener((observable, oldValue, newValue) -> distant.setElevation(newValue.doubleValue()));
Group root = new Group();
root.getChildren().addAll(circle, slideArimuth, sliderElevation, labelArimuth, labelElevation);
Scene scene = new Scene(root, 400, 450);
scene.setFill(Color.GREEN);
primaryStage.setTitle("HeWorld !");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
|
*** Point light :
Point light là một điểm chiếu sáng mà tại đó các tia sáng sẽ chiếu lên node theo dạng lan tỏa, chứ không phải song song như distant light. Mặt trời là 1 ví dụ điển hình của Point light, mặt trời là điểm chiếu sáng mà tại đó phát ra các tia sáng.
Các thuộc tính của Point light :
kiểu
|
Tên thuộc tính
|
Giá trị mặc định
|
Miêu tả
|
DoubleProperty
|
x
|
0
|
Tọa độ x của điểm sáng
|
DoubleProperty
|
y
|
0
|
Tọa độ y của điểm sáng
|
DoubleProperty
|
z
|
0
|
Độ lan tỏa ánh sáng.
|
Cách sử dụng Point Light :
// Tạo đối tượng Point với giá trị thuộc tính mặc định
Light.Point point = new Light. Point();
// Tạo đối tượng Point với giá trị x = 30, y = 60, z= 40 ,Color = Green. Color là màu chiếu sáng dành cho node. Nếu không định nghĩa biến Color, màu chiếu sáng là màu của node
Light.Point point = new Light. Point(30,60,40, Color.GREEN);
|
Một số phương thức của Point Light :
kiểu trả về
|
Phương thức
|
Miêu tả
|
void
|
setX(double value)
|
Thiết lập giá trị thuộc tính x
|
double
|
getX()
|
Trả về giá trị thuộc tính x
|
void
|
setY(double value)
|
Thiết lập giá trị thuộc tính y
|
double
|
getY()
|
Trả về giá trị thuộc tính y
|
void
|
setZ(double value)
|
Thiết lập giá trị thuộc tính z
|
double
|
getZ()
|
Trả về giá trị thuộc tính z
|
Ví dụ : Tạo 1 circle với hiệu ứng Lighting có thuộc tính Light là Point
Code :
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.effect.Light;
import javafx.scene.effect.Lighting;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class examplePointLight extends Application {
Light.Point point;
@Override
public void start(Stage primaryStage) {
// Circle
Circle circle = new Circle(200, 180, 150, Color.YELLOW);
// Slider dành cho Arimuth
Label labelX = new Label("X : ");
labelX.setLayoutX(30);
labelX.setLayoutY(340);
Slider slideX = new Slider(0, 360, 45);
slideX.setLayoutX(45);
slideX.setLayoutY(340);
slideX.setPrefWidth(300);
slideX.setShowTickLabels(true);
slideX.setShowTickMarks(true);
// Slider dành cho Y
Label labelY = new Label("Y : ");
labelY.setLayoutX(30);
labelY.setLayoutY(370);
Slider sliderY = new Slider(0, 360, 45);
sliderY.setLayoutX(45);
sliderY.setLayoutY(370);
sliderY.setPrefWidth(300);
sliderY.setShowTickLabels(true);
sliderY.setShowTickMarks(true);
// Slider dành cho Z
Label labelZ = new Label("Z : ");
labelZ.setLayoutX(30);
labelZ.setLayoutY(400);
Slider sliderZ = new Slider(0, 360, 45);
sliderZ.setLayoutX(45);
sliderZ.setLayoutY(400);
sliderZ.setPrefWidth(300);
sliderZ.setShowTickLabels(true);
sliderZ.setShowTickMarks(true);
// Định nghĩa đối tượng Point light
point = new Light.Point(50, 50, 50, Color.YELLOW);
// Định nghĩa hiệu ứng Lighting
Lighting lighting = new Lighting();
lighting.setLight(point);
//Áp dụng hiệu ứng Lighting vào Circle
circle.setEffect(lighting);
// Event khi thay đổi giá trị X
slideX.valueProperty().addListener((observable, oldValue, newValue) -> point.setX(newValue.doubleValue()));
// Event khi thay đổi giá trị Y
sliderY.valueProperty().addListener((observable, oldValue, newValue) -> point.setY(newValue.doubleValue()));
// Event khi thay đổi giá trị Z
sliderZ.valueProperty().addListener((observable, oldValue, newValue) -> point.setZ(newValue.doubleValue()));
Group root = new Group();
root.getChildren().addAll(circle, slideX, sliderY, labelX, labelY, sliderZ, labelZ);
Scene scene = new Scene(root, 400, 450);
scene.setFill(Color.GREEN);
primaryStage.setTitle("HeWorldssdsfffdllo !");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
|
***Spot light :
Spot light hoạt động giống như Point Light, trong khi điểm chiếu sáng của Point Light phát ra các tia sáng khắp bốn hướng, thì Spot Light bị hạn chế chỉ chiếu sáng ở 1 vùng nào đó trên node. Các tia sáng của spot light được giới hạn trong khuôn khổ hình nón có đỉnh là điểm chiếu sáng.
Spot light được định nghĩa trong javafx.scene.effect.Light.Spot class và là lớp con của Point. Do đó, Spot class cũng kế thừa các thuộc tính và phương thức của Point.
Các thuộc tính của Spot :
kiểu
|
Tên thuộc tính
|
Giá trị mặc định
|
Miêu tả
|
DoubleProperty
|
pointAtX
|
0
|
Tọa độ x của tâm mặt nón
|
DoubleProperty
|
pointAtY
|
0
|
Tọa độ y của tâm mặt nón
|
DoubleProperty
|
pointAtZ
|
0
|
Tọa độ z của tâm mặt nón
|
DoubleProperty
|
specularExponent
|
1.0
|
Chiều rộng của mặt nón, giá trị từ 0 đến 4
|
Thuộc tính x,y,z của Point class là đỉnh của hình nón, cũng là điểm chiếu sáng. Nó kết hợp với điểm có tọa độ (pointAtX, pointAtY, pointAtZ) tạo thành trục hình nón, còn chiều rộng của hình nón phụ thuộc vào thuộc tính specularExponent. Giá trị thuộc tính specularExponent càng lớn thì chiều rộng mặt nón càng nhỏ.
Cách sử dụng Spot Light :
// Tạo đối tượng Point với giá trị thuộc tính mặc định
Light.Point.Spot spot = new Light. Point.Spot();
// Tạo đối tượng Spot với điểm chiếu sáng có giá trị x = 30, y = 60, z= 40 ,Color = Green. Color là màu chiếu sáng dành cho node. Nếu không định nghĩa biến Color, màu chiếu sáng là màu của node
Light.Point.Spot spot = new Light. Point.Spot(30,60,40, Color.GREEN);
|
Một số phương thức của Point Light :
kiểu trả về
|
Phương thức
|
Miêu tả
|
void
|
setPointAtX(double value)
|
Thiết lập giá trị thuộc tính pointAtX
|
double
|
getPointAtX()
|
Trả về giá trị thuộc tính pointAtX
|
void
|
setPointAtY(double value)
|
Thiết lập giá trị thuộc tính pointAtY
|
double
|
getPointAtY()
|
Trả về giá trị thuộc tính pointAtY
|
void
|
setPointAtZ(double value)
|
Thiết lập giá trị thuộc tính pointAtZ
|
double
|
getPointAtZ()
|
Trả về giá trị thuộc tính pointAtZ
|
Ví dụ : Tạo 1 circle với hiệu ứng Lighting có thuộc tính Light là Spot
Code :
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.effect.Light;
import javafx.scene.effect.Lighting;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class exampleSpotLight extends Application {
Light.Point.Spot spot;
@Override
public void start(Stage primaryStage) {
// Circle
Circle circle = new Circle(200, 180, 150, Color.YELLOW);
// Slider dành cho PointAtX
Label labelPointAtX = new Label("PointAtX : ");
labelPointAtX.setLayoutX(10);
labelPointAtX.setLayoutY(340);
Slider slidePointAtX = new Slider(-300, 300, 0);
slidePointAtX.setLayoutX(75);
slidePointAtX.setLayoutY(340);
slidePointAtX.setPrefWidth(300);
slidePointAtX.setShowTickLabels(true);
slidePointAtX.setShowTickMarks(true);
// Slider dành cho PointAtY
Label labelPointAtY = new Label("PointAtY : ");
labelPointAtY.setLayoutX(10);
labelPointAtY.setLayoutY(370);
Slider slidePointAtY = new Slider(-300, 300, 0);
slidePointAtY.setLayoutX(75);
slidePointAtY.setLayoutY(370);
slidePointAtY.setPrefWidth(300);
slidePointAtY.setShowTickLabels(true);
slidePointAtY.setShowTickMarks(true);
// Slider dành cho PointAtZ
Label labelPointAtZ = new Label("PointAtZ : ");
labelPointAtZ.setLayoutX(10);
labelPointAtZ.setLayoutY(400);
Slider sliderPointAtZ = new Slider(-300, 300, 0);
sliderPointAtZ.setLayoutX(75);
sliderPointAtZ.setLayoutY(400);
sliderPointAtZ.setPrefWidth(300);
sliderPointAtZ.setShowTickLabels(true);
sliderPointAtZ.setShowTickMarks(true);
// Slider dành cho SpecularExponent
Label labelSpecularExponent = new Label("SpecularExponent : ");
labelSpecularExponent.setLayoutX(10);
labelSpecularExponent.setLayoutY(430);
Slider sliderSpecularExponent = new Slider(0, 4, 1);
sliderSpecularExponent.setLayoutX(120);
sliderSpecularExponent.setLayoutY(430);
sliderSpecularExponent.setPrefWidth(250);
sliderSpecularExponent.setShowTickLabels(true);
sliderSpecularExponent.setShowTickMarks(true);
// Định nghĩa đối tượng Distant
spot = new Light.Spot(100, 100, 100, 4 , Color.YELLOW);
// Định nghĩa hiệu ứng Lighting
Lighting lighting = new Lighting();
lighting.setLight(spot);
lighting.setSurfaceScale(5);
//Áp dụng hiệu ứng Lighting vào Circle
circle.setEffect(lighting);
// Event khi thay đổi giá trị PointAtX
slidePointAtX.valueProperty().addListener((observable, oldValue, newValue)
-> spot.setPointsAtX(newValue.doubleValue()));
// Event khi thay đổi giá trị PointAtY
slidePointAtY.valueProperty().addListener((observable, oldValue, newValue)
-> spot.setPointsAtY(newValue.doubleValue()));
// Event khi thay đổi giá trị PointAtZ
sliderPointAtZ.valueProperty().addListener((observable, oldValue, newValue)
-> spot.setPointsAtZ(newValue.doubleValue()));
// Event khi thay đổi giá trị SpecularExponent
sliderSpecularExponent.valueProperty().addListener((observable, oldValue, newValue)
-> spot.setSpecularExponent(newValue.doubleValue()));
Group root = new Group();
root.getChildren().addAll(circle, slidePointAtX, slidePointAtY, labelPointAtX, labelPointAtY, sliderPointAtZ, labelPointAtZ, sliderSpecularExponent, labelSpecularExponent);
Scene scene = new Scene(root, 400, 480);
scene.setFill(Color.GREEN);
primaryStage.setTitle("HeWorldssdsfffdllo !");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
|
Không có nhận xét nào:
Đăng nhận xét