1

ユーザーが表示されるマテリアル、ライト、およびオブジェクトを変更できるインタラクティブなプログラムを作成しています。ユーザー インタラクションを処理するためにすべての HTML テーブルと JavaScript イベントを記述する部分は、問題なく動作すると思うので、関連する部分だけをここに投稿し、ファイル全体へのリンクを追加します。

ここでは、シーン、オブジェクト、ライト、およびレンダリング関数を作成します。

var scene= new THREE.Scene();
var camera= new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);
var renderer= new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth,window.innerHeight);
document.body.appendChild(renderer.domElement);
camera.position.z=5;


var geometry= new THREE.SphereGeometry(1,15,15);
var material= new THREE.MeshLambertMaterial({color:0xffffff, ambient:0xffffff, emissive:0xffffff});
var object= new THREE.Mesh(geometry,material);
material.name= "lambert";
object.name= "sphere";
scene.add(object);

var light= new THREE.PointLight(0xffffff);
light.position.set(0,0,20);
light.name= "point";
scene.add(light);


var render= function() {
    requestAnimationFrame(render);
    renderer.render(scene,camera);
}
render();

次に、ユーザーがボタンを使用してパラメーターを変更するたびに、これらの関数を使用してマテリアルとライトの特性を変更します。

function changeLightParameters() {
    var lightParameters= getLightParameters();
    if(lightParameters== null) {
        alert("Invalid values");
        return;
    }
    if(light.name!= lightParameters.type) {
        scene.remove(light);
        if(lightParameters.type== "spot") {
            light= new THREE.SpotLight(lightParameters.color);
        }
        else if(lightParameters.type== "point") {
            light= new THREE.PointLight(lightParameters.color);
        }
        else if(lightParameters.type== "ambient") {
            light= new THREE.AmbientLight(lightParameters.color);
        }
        else if(lightParameters.type== "area") {
            light= new THREE.AreaLight(lightParameters.color);
        }
        else if(lightParameters.type== "directional") {
            light= new THREE.DirectionalLight(lightParameters.color);
        }
        light.position.set(lightParameters.position.x, lightParameters.position.y, lightParameters.position.z);
        light.name= lightParameters.name;
        scene.add(light);
    }
    else {
        light.position= lightParameters.position;
        light.color= new THREE.Color(lightParameters.color);
    }
}


function changeMaterialParameters() {
    var materialParameters= getMaterialParameters();
    if(materialParameters== null) {
        alert("Invalid values");
        return;
    }
    if(materialParameters.type!= material.name) {
        scene.remove(object);
        if(materialParameters.type== "lambert") {
            material= new THREE.MeshLambertMaterial({
        color:materialParameters.diffuse, 
                ambient:materialParameters.ambient,
                emissive:materialParameters.emissive });
        }
        else if(materialParameters.type== "normal") {
            material= new THREE.MeshNormalMaterial();
        }
        else if(materialParameters.type== "phong") {
            material= new THREE.MeshPhongMaterial({
                color:materialParameters.diffuse,
                ambient:materialParameters.ambient,
                emissive:materialParameters.emissive,
                specular:materialParameters.specular,
                shininess:materialParameters.shininess });
        }
        material.name= materialParameters.type;
        object= new THREE.Mesh(geometry,material);
        scene.add(object);
    }
    else {
        material.color= new THREE.Color(materialParameters.diffuse);
        material.ambient= new THREE.Color(materialParameters.ambient);
        material.emissive= new THREE.Color(materialParameters.emissive);
        material.specular= new THREE.Color(materialParameters.specular);
        material.shininess= new THREE.Color(materialParameters.shininess);
        material.needsUpdate= true;
    }
}

これらの関数では、 と を使用getMaterialParameters()getLightParameters()て、値を処理するテキスト フィールドを含む 2 つのテーブルに渡されたすべてのパラメータを取得します。これらの関数は既にテスト済みで動作するので、コードを見る必要はありません。これらの関数は、次の構造を持つオブジェクトを返します。

Light : color (number)
        position (THREE.Vector3)
        type (string, possibile values "ambient", "point", "spot", "point", "directional")

Material: diffuse (number)
          ambient (number)
          emissive (number)
          specular (number)
          shininess (number)
          type (string, possible values "phong", "normal", "lambert")

マテリアル タイプが変更された場合はマテリアル プロパティを取得したら、新しいマテリアルを最初から作成し、プロパティだけが変更された場合は更新します。ライトも同じ。

問題は、オブジェクトが光の変化に反応しないように見えることです。光の位置/色を変更しても何も起こりません。また、何も変わらないライトの z を -1000 に設定することもできます。Phong モデルは私には正しくないように思えます。オブジェクトは本来あるべきように輝いていません。例:

ここに画像の説明を入力

パラメータは次のとおりです。Phong マテリアル、輝き 100、拡散光 0x00abb1、放射光 0x006063、鏡面光 0xa9fcff、輝き光 100。ホワイト ポイント ライトの位置 (20,20,200)。光を (0,0,0) に移動すると、球は同じように見えます。本来あるべきように現実的ではないようです。私は何か間違ったことをしていると思います。

詳細を追加する必要がある場合は教えてください。完全なコードは次のとおりです: http://pastebin.com/3uwgwvfE

アップデート

問題は、シーンが既に初期化されているときに新しいライトを追加できないという事実にあることがわかりました。問題を再現する方法の例として、新しいプログラムを作成しました。スポット ライトの使用を開始し、ユーザーがキャンバスをクリックすると、シーンからライトが削除され、新しいライト (指向性) が追加されます。しかし、うまくいきません。照明がなく、アンビエント コンポーネントが表示されるだけです。コードはこちら: http://pastebin.com/BVU0dPi3

4

1 に答える 1

0

問題は、ライトの種類を変更するときに、マテリアルを更新する必要があったことです。ライトを動かすときも同じではありません。したがって、プログラムは次の行を追加することで機能しました。

// Change type of light and add it to the scene
material.needsUpdate= true;
于 2013-10-13T10:21:58.373 に答える