3 D Graphics / Imaging With Phong Shading

Joe

Thành viên VIP
21/1/13
2,935
1,304
113
Hi everyone,

This week I show you an unique JFX feature that bases on the Ph.D work of a Vietnamese American Computer Scientist: Dr. Bui Tuong Phong. His ingenious work was honored as the Phong Shading. If you have interests on this Phong Shading you could learn from the following Video Clips.



JavaFX supports Phong Shading with the API javafx.scene.paint.PhongMaterial. The API description gives you roughly a knowledge about Phong technique how to use it and for what it is good. Phong Shading is built on 3 following "shadings":
  • Ambient: the surrounding shade
  • Diffuse: the unsharp shade
  • Specular: the shining shade
When the 3 shadings are merged together the Phong Shading emerges.


(Source: Wikipedia)

Tutorial: Click HERE

Example with PhongMaterial
PHP:
import javafx.animation.*;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.image.Image;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.*;
import javafx.scene.shape.Sphere;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;
// Source: https://gist.github.com/jewelsea/7206287
// modified by Joe Nartca for JFX 8
public class EarthViewer extends Application {

  private static final double EARTH_RADIUS  = 300;
  private static final double VIEWPORT_SIZE = 700;
  private static final double ROTATE_SECS   = 30;

  private static final double MAP_WIDTH  = 8192 / 2d;
  private static final double MAP_HEIGHT = 4092 / 2d;
  // for the quick access time download the images and use them as local files
  private static final String DIFFUSE_MAP = "earth1.jpg";
  //	"http://planetmaker.wthr.us/img/earth_gebco8_texture_8192x4096.jpg";
  private static final String NORMAL_MAP = "earth2.jpg";
  //	"http://planetmaker.wthr.us/img/earth_normalmap_flat_8192x4096.jpg";
  private static final String SPECULAR_MAP = "earth3.jpg";
  //	"http://planetmaker.wthr.us/img/earth_specularmap_flat_8192x4096.jpg";

  private Group buildScene() {
	Sphere earth = new Sphere(EARTH_RADIUS);
	earth.setTranslateX(VIEWPORT_SIZE / 2d);
	earth.setTranslateY(VIEWPORT_SIZE / 2d);

	PhongMaterial earthMaterial = new PhongMaterial();
	earthMaterial.setDiffuseMap(
	  new Image(
		DIFFUSE_MAP,
		MAP_WIDTH,
		MAP_HEIGHT,
		true,
		true
	  )
	);
	earthMaterial.setBumpMap(
	  new Image(
		NORMAL_MAP,
		MAP_WIDTH,
		MAP_HEIGHT,
		true,
		true
	  )
	);
	earthMaterial.setSpecularMap(
	  new Image(
		SPECULAR_MAP,
		MAP_WIDTH,
		MAP_HEIGHT,
		true,
		true
	  )
	);

	earth.setMaterial(
		earthMaterial
	);

	return new Group(earth);
  }

  @Override
  public void start(Stage stage) {
	Group group = buildScene();

	Scene scene = new Scene(
	  new StackPane(group),
	  VIEWPORT_SIZE, VIEWPORT_SIZE,
	  true,
	  SceneAntialiasing.BALANCED
	);

	scene.setFill(Color.rgb(10, 10, 40));

	scene.setCamera(new PerspectiveCamera());

	stage.setScene(scene);
	stage.show();

	stage.setFullScreen(true);

	rotateAroundYAxis(group).play();
  }

  private RotateTransition rotateAroundYAxis(Node node) {
	RotateTransition rotate = new RotateTransition(
	  Duration.seconds(ROTATE_SECS), 
	  node
	);
	rotate.setAxis(Rotate.Y_AXIS);
	rotate.setFromAngle(360);
	rotate.setToAngle(0);
	rotate.setInterpolator(Interpolator.LINEAR);
	rotate.setCycleCount(RotateTransition.INDEFINITE);

	return rotate;
  }
}
And here is the EarthViewer with PhongMaterial
 
  • Like
Reactions: Thanhpv