2015-12-26 32 views
4

我目前正在學習JavaFX 3D功能,並且我想模擬太陽系。我很成功地創建了類型PointLight的光源,並將其座標綁定到太陽座標。現在我想看看太陽作爲光源發出光芒。我會怎麼做?JavaFX中的可見光源3D

@Component 
public class RootPane extends StackPane { 

    @Inject 
    protected Scene scene; 

    @Inject 
    protected PerspectiveCamera camera; 

    @Inject 
    protected LightBase lightBase; 

    @PostConstruct 
    public void init() { 
     setBackground(new Background(new BackgroundFill(
       Color.TRANSPARENT, CornerRadii.EMPTY, Insets.EMPTY))); 
     setAlignment(Pos.CENTER); 
     setPadding(new Insets(20)); 

     Sphere sunSphere = new Sphere(80); 
     sunSphere.setEffect(new Glow(5)); 

     Sphere mercurySphere = new Sphere(40); 
     mercurySphere.translateZProperty().bind(sunSphere.translateZProperty() 
       .add(200)); 

     Sphere venusSphere = new Sphere(40); 
     venusSphere.translateXProperty().bind(sunSphere.translateXProperty() 
       .subtract(300)); 
     venusSphere.translateZProperty().bind(sunSphere.translateZProperty() 
       .subtract(300)); 

     Sphere earthSphere = new Sphere(40); 
     earthSphere.translateXProperty().bind(sunSphere.translateXProperty() 
       .add(300)); 
     earthSphere.translateZProperty().bind(sunSphere.translateZProperty() 
       .subtract(400)); 

     Rotate rotateX = new Rotate(0, Rotate.X_AXIS); 
     Rotate rotateY = new Rotate(0, Rotate.Y_AXIS); 
     Rotate rotateZ = new Rotate(0, Rotate.Z_AXIS); 

     Translate translate = new Translate(0, 0, -3000); 

     camera.getTransforms().addAll(rotateX, rotateY, rotateZ, translate); 

     scene.addEventHandler(
       KeyEvent.KEY_PRESSED, 
       event -> { 
        if (Objects.equals(event.getCode(), KeyCode.D)) { 
         rotateY.setAngle(rotateY.getAngle() - 
           (event.isShiftDown() ? 5 : 0.1)); 
        } else if (Objects.equals(event.getCode(), KeyCode.A)) { 
         rotateY.setAngle(rotateY.getAngle() + 
           (event.isShiftDown() ? 5 : 0.1)); 
        } 
       }); 
     scene.addEventHandler(
       KeyEvent.KEY_PRESSED, 
       event -> { 
        if (Objects.equals(event.getCode(), KeyCode.W)) { 
         rotateX.setAngle(rotateX.getAngle() - 
           (event.isShiftDown() ? 5 : 0.1)); 
        } else if (Objects.equals(event.getCode(), KeyCode.S)) { 
         rotateX.setAngle(rotateX.getAngle() + 
           (event.isShiftDown() ? 5 : 0.1)); 
        } 
       }); 

     lightBase.translateXProperty().bind(sunSphere.translateXProperty()); 
     lightBase.translateYProperty().bind(sunSphere.translateYProperty()); 
     lightBase.translateZProperty().bind(sunSphere.translateZProperty()); 

     getChildren().addAll(sunSphere, mercurySphere, venusSphere, 
       earthSphere, camera, lightBase); 
    } 

} 
+1

這是您的完整碼?你可以包括你正在初始化場景,相機,燈箱等場合。 – Amber

+2

你看不到點光源。這是一個點,它有0個區域。你看到太陽,因爲它面積約爲2.35×10^12平方英里,其中一半正在散發你的路。你需要使用同樣的方法模擬外觀,也許增加一些效果,如光環,眩光等。 – IceGlow

+0

哦,我看到你有一個sunSphere。也許你的意思是'上帝之光'效應? – IceGlow

回答

1

沒有你正在尋找實現它的影響的例子是很難提供一個答案,但這裏有兩個選擇:

創建粒子效果從太陽發射與添加劑混合

使用高光貼圖創建材質。

+0

我在'sunSphere'中添加了一個'Color.YELLOW'的'PhongMaterial'作爲它的漫反射顏色,但是在打開燈時不可見。 ('PointLight'的座標綁定到'sunSphere'。 –

1

PhongMaterial JavaDoc

顏色由以下等式計算:

for each ambient light source i { 
    ambient += lightColor[i] 
} 
for each point light source i { 
    diffuse += (L[i] . N) * lightColor[i] 
    specular += ((R[i] . V)^(specularPower * intensity(specularMap))) * lightColor[i] 
} 
color = (ambient + diffuse) * diffuseColor * diffuseMap 
     + specular * specularColor * specularMap 
     + selfIlluminationMap 

其中:

lightColor [i]是光源i的顏色,

L [i]是從表面到光源i的矢量,

N是法線矢量(考慮到該帳戶的bumpMap如果存在的話),

- [R [i]是對於L歸一化的反射矢量[I]關於表面法線,

,V是規範化視圖向量。

如果您的PointLight座標匹配您的Sun的球體座標,則L [i]。 N < 0並且您沒有瀰漫性貢獻。所以,如果沒有環境光線,它會顯得黑色。

嘗試添加他們提到的使用太陽紋理的selfIlluminationMap。它應該有所幫助。

在谷歌的一個簡短的搜索給了我這個鏈接,可能是有用的:planets and sun maps。但是,請注意許可證,但應該有免費資源。