首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 3D 平行光投影實現:陰影生成算法與完整代碼範例

     編輯:Java 相關知識

數學原理:平行光投影到平面

已知:

  • 光線方向向量 v = (-1, -1, -1)(歸一化後)。
  • 投影平面:XZ 平面(y = 0),法向量 n = (0, 1, 0),過原點。
  • 頂點 P = (x₀, y₀, z₀)。

光線參數方程:P + t·v。與平面 y = 0 交點:

y₀ + t·v.y = 0  →  t = -y₀ / v.y
投影座標:
x = x₀ + v.x * (-y₀ / v.y)
z = z₀ + v.z * (-y₀ / v.y)

代碼中簡化為 shadow.set(vertex.x - (vertex.y - height), height + 0.0001f, vertex.z - (vertex.y - height)),其中 height = -0.5f 為地面 Y 座標,0.0001f 偏移避免 Z-fighting。

完整可運行範例

import java.applet.Applet;
import java.awt.BorderLayout;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import javax.media.j3d.*;
import javax.vecmath.*;

public class SimpleShadow extends Applet {
    
    // 三角形平面(可見物體)
    public class TriPlane extends Shape3D {
        public TriPlane(Point3f A, Point3f B, Point3f C) {
            setGeometry(createGeometry3(A,B,C));
            setAppearance(createAppearance());
        }
        private Geometry createGeometry3(Point3f A, Point3f B, Point3f C) {
            TriangleArray ta = new TriangleArray(3, 
                GeometryArray.COORDINATES | GeometryArray.NORMALS);
            ta.setCoordinate(0, A); ta.setCoordinate(1, B); ta.setCoordinate(2, C);
            Vector3f a = new Vector3f(A.x-B.x, A.y-B.y, A.z-B.z);
            Vector3f b = new Vector3f(C.x-B.x, C.y-B.y, C.z-B.z);
            Vector3f n = new Vector3f(); n.cross(b, a); n.normalize();
            ta.setNormal(0, n); ta.setNormal(1, n); ta.setNormal(2, n);
            return ta;
        }
        private Appearance createAppearance() {
            Appearance ap = new Appearance();
            ap.setMaterial(new Material());
            return ap;
        }
    }
    
    // 四邊形平面(地面/投影面)
    public class QuadPlane extends Shape3D {
        public QuadPlane(Point3f A, Point3f B, Point3f C, Point3f D) {
            setGeometry(createGeometry4(A,B,C,D));
            setAppearance(createAppearance());
        }
        private Geometry createGeometry4(Point3f A, Point3f B, Point3f C, Point3f D) {
            QuadArray qa = new QuadArray(4, 
                GeometryArray.COORDINATES | GeometryArray.NORMALS);
            qa.setCoordinate(0, A); qa.setCoordinate(1, B); 
            qa.setCoordinate(2, C); qa.setCoordinate(3, D);
            Vector3f a = new Vector3f(A.x-B.x, A.y-B.y, A.z-B.z);
            Vector3f b = new Vector3f(C.x-B.x, C.y-B.y, C.z-B.z);
            Vector3f n = new Vector3f(); n.cross(b, a); n.normalize();
            for (int i=0;i<4;i++) qa.setNormal(i, n);
            return qa;
        }
        private Appearance createAppearance() {
            Appearance ap = new Appearance();
            ap.setMaterial(new Material());
            return ap;
        }
    }
    
    // 陰影幾何體生成
    public class Shadow3D extends Shape3D {
        public Shadow3D(GeometryArray geom, Vector3f dir, Color3f color, float groundY) {
            int vCount = geom.getVertexCount();
            TriangleArray shadowGeom = new TriangleArray(vCount,
                GeometryArray.COORDINATES | GeometryArray.COLOR_3);
            Point3f vertex = new Point3f();
            Point3f shadow = new Point3f();
            for (int i=0; i

關鍵技術點解析

擴展方向

  • 點光源/聚光燈投影:投影中心為光源位置,需透視除法。
  • Shadow Mapping (GPU):深度圖紋理比較,適用複雜場景、動態物體。
  • Java 3D 影子節點:com.sun.j3d.utils.shadow.Shadow 類提供更高層封裝。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
技術點實現細節
幾何體建模TriangleArray/QuadArray + COORDINATES|NORMALS 支援光照
法向量計算叉積 b × a → 歸一化,決定光照明暗
Material 元件必須設定 Appearance.setMaterial() 否則光照無效果
平行光DirectionalLight + 歸一化方向向量
陰影生成CPU 端逐頂點投影計算,生成新 TriangleArray,顏色設為深灰
Z-fighting 避免陰影 Y 座標 groundY + 0.0001f 微量抬高