4

に配置された多数のオブジェクトがあり、THREE.scene各オブジェクトが 1 つの光源から受ける光の量を示す相対値を計算または取得したいと考えていますPointLight。簡単な例:

ブロックの例

ライトがカメラに配置されている場合、ブロック1の値は 0.50 になる可能性があります。これは、6 つの面のうち 3 つが完全に露出されているためです。一方、2は ~0.33、3~1.67 です。

おそらく、ライトから各面の中心に向かって光線を描画し、交差を確認するという難しい方法でこれを行うことができますが、各面のライト レベルを直接取得することは可能であると想定しています。

4

3 に答える 3

7

このコードは、オブジェクトのグローバル マトリックスを考慮します。

var amount = 0;

var rotationMatrix = new THREE.Matrix4();
var vector = new THREE.Vector3();
var centroid = new THREE.Vector3();
var normal = new THREE.Vector3();

for ( var i = 0; i < objects.length; i ++ ) {

    var object = objects[ i ];

    rotationMatrix.extractRotation( object.matrixWorld );

    for ( var j = 0; j < object.geometry.faces.length; j ++ ) {

        var face = object.geometry.faces[ j ];

        centroid.copy( face.centroid );
        object.matrixWorld.multiplyVector3( centroid );

        normal.copy( face.normal );
        rotationMatrix.multiplyVector3( normal );

        vector.sub( light.position, centroid ).normalize();

        if ( normal.dot( vector ) > 0 ) amount ++;

    }

}
于 2012-05-24T21:12:02.523 に答える
4

このようなことがうまくいくはずだと思います。

var amount = 0;
var faces = mesh.geometry.faces;
for ( var i = 0; i < geometry.faces.length; i ++ ) {

    if ( geometry.faces[ i ].normal.dot( light.position ) > 0 ) amount ++;

}
于 2012-05-24T17:54:02.257 に答える
1

(警告: 強引な方法です!)

これは、質問に記載されているすべての要件を満たすために現在使用しているものであるため、参照用に含めています。この関数は、面の中心がライトの位置から直接見えない場合、その面は照らされていないと見なします。

アプリケーションで考慮すべき回転行列がありません。

function getLightLevel(obj) {
    /* Return percentage of obj.geometry faces exposed to light */
    var litCount = 0;

    var faces = obj.geometry.faces;
    var faceCount = faces.length; 
    var direction = new THREE.Vector3();
    var centroid = new THREE.Vector3();

    for (var i=0; i < faceCount; i++) {
        // Test only light-facing faces (from mrdoob's first answer).
        if (faces[i].normal.dot(light.position) > 0) {
            centroid.add(obj.position, faces[i].centroid);
            direction.sub(centroid, light.position).normalize();

            // Exclude face if centroid is obscured by another object.
            var ray = new THREE.Ray(light.position, direction);
            var intersects = ray.intersectObjects(objects);

            if (intersects.length > 0 && intersects[0].face === faces[i]) {
                litCount ++;
            }
        }
    }
    return litCount / faceCount;
}
于 2012-05-25T17:09:44.657 に答える