JavaFX material's bump and spec maps

北慕城南 提交于 2019-12-04 15:37:45

Bump map for JavaFX is a normal map, not a height map, for more info see: normal map and height map info.

Here is a sample you can try.

The images for the maps are pretty large, so it might take a little while to download them before your scene shows.

Source I used for images was => Bored? Then Create a Planet

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;

public class EarthViewer extends Application {

  private static final double EARTH_RADIUS  = 400;
  private static final double VIEWPORT_SIZE = 800;
  private static final double ROTATE_SECS   = 30;

  private static final double MAP_WIDTH  = 8192 / 2d;
  private static final double MAP_HEIGHT = 4092 / 2d;

  private static final String DIFFUSE_MAP =
      "http://planetmaker.wthr.us/img/earth_gebco8_texture_8192x4096.jpg";
  private static final String NORMAL_MAP =
      "http://planetmaker.wthr.us/img/earth_normalmap_flat_8192x4096.jpg";
  private static final String SPECULAR_MAP =
      "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;
  }

  public static void main(String[] args) {
    launch(args);
  }
}

Normal? Why????

The JavaDoc states for the PhongMaterial bumpMapProperty states:

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

A normal map is used rather than a height map because:

[normal maps] are much more accurate, as rather than only simulating the pixel being away from the face along a line, they can simulate that pixel being moved at any direction, in an arbitrary way.

A brief description of both normal mapping and height mapping is provided in the wikipedia bump mapping article.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!