2017-09-21 1 views
1

シーン内の特定の点の光度やピクセル値(rgba)を取得する方法が不思議です。例えばThreeJS - x/y/zの任意の点で光強度/ピクセル値を測定するにはどうすればよいですか?

私は、キューブの上に輝いて移動する光でシーンを持っていると、キューブの特定のポイントはどのように明るい測定したい:

// Our Javascript will go here. 
 
var scene = new THREE.Scene(); 
 
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000); 
 

 
var renderer = new THREE.WebGLRenderer({ preserveDrawingBuffer: true }); 
 
renderer.setSize(window.innerWidth, window.innerHeight); 
 
document.body.appendChild(renderer.domElement); 
 

 
var geometry = new THREE.BoxGeometry(1, 1, 1); 
 
var material = new THREE.MeshLambertMaterial(); 
 
var cube = new THREE.Mesh(geometry, material); 
 
cube.rotation.x += 0.4; 
 
cube.rotation.y += 0.4; 
 
scene.add(cube); 
 

 
var plane_geo = new THREE.PlaneGeometry(2,2,2); 
 
var plane = new THREE.Mesh(plane_geo, material); 
 
plane.rotation.x = -1; 
 
plane.position.y = -0.5; 
 
scene.add(plane); 
 

 
var light = new THREE.SpotLight(0xff0000, 1, 100); 
 
//var light = new THREE.PointLight(0xff0000, 1, 100); 
 
light.position.set(3, 2, 2); 
 
scene.add(light); 
 

 
var sphereSize = 0.1; 
 
var pointLightHelper = new THREE.PointLightHelper(light, sphereSize); 
 
scene.add(pointLightHelper); 
 

 
var lightX = 0.5; 
 
var lightY = 0.5; 
 

 
camera.position.z = 5; 
 

 

 

 
animate(); 
 

 

 
document.addEventListener("mousemove",mousemove_handler); 
 

 

 
function animate() { 
 
\t requestAnimationFrame(animate); 
 

 

 
\t light.position.set(lightX,lightY,1); 
 

 
\t renderer.render(scene, camera); 
 

 
} 
 

 
function mousemove_handler(event) 
 
{ 
 

 
\t // get Mouse Coords mapped to the 3D Vector 
 
\t var vector = new THREE.Vector3(); 
 

 
\t vector.set(
 
\t  (event.clientX/window.innerWidth) * 2 - 1, 
 
\t  - (event.clientY/window.innerHeight) * 2 + 1, 
 
\t  0.5); 
 

 
\t vector.unproject(camera); 
 

 
\t var dir = vector.sub(camera.position).normalize(); 
 

 
\t var distance = - camera.position.z/dir.z; 
 

 
\t var pos = camera.position.clone().add(dir.multiplyScalar(distance)); 
 

 
\t lightX = pos.x; 
 
\t lightY = pos.y; 
 

 

 
}
body { margin: 0; } 
 
\t \t \t canvas { width: 100%; height: 100% }
<!DOCTYPE html> 
 
<html> 
 

 
\t <head> 
 
\t \t <meta charset=utf-8> 
 
\t \t <title>My first three.js app</title> 
 
\t \t <style> 
 
\t \t \t body { margin: 0; } 
 
\t \t \t canvas { width: 100%; height: 100% } 
 
\t \t </style> 
 
\t </head> 
 

 

 
\t <body> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.min.js"></script> 
 
    </body> 
 
</html>

+1

r71を使用するのは良い考えではない可能性があります。それを指摘するために、r87 https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.min.js – Radio

+1

thxにアップグレードする方が良いでしょう。完了しました。 – gauguerilla

答えて

3

考慮するので、多くのものがありますここに。明らかと

スタート:実際の生活の中で

ライトの計算は、私が言う、太陽のパフォーマンスのための科学的CALCSを行うにはWebGLのライトを使用することはお勧めできませんなどの干渉、カンデラ、波長に依存します。また

光3Dのシェーダが通過する使用します。これは、照明がシーンを渡ることを意味します。ウィンドウのような半透明なもののようなシーン内のものに応じて、問題のポイントを直接移動してポイントをできるだけ明確にする必要があります。重要なのは、カメラが向いているポイントだけを測定できることです。しかし、あなたのシーンがシンプルな場合は、積極的な霧の設定がない限り、大きな問題にはなりません。次のように特定のピクセル上の光強度を取得

は次のとおりです。

  • は、あなたが知りたい表面のポイントを取得します。
  • そのピクセルのスクリーン位置を取得します。
  • キャンバスコンテキストを取得します。
  • 画素
  • のRGBA値はグレースケールにRGBA値を変換取得コンテキスト画素位置
  • を取得します。

しかし、キャッチがまだあります:グレースケールに変換

はとしてまっすぐ進むそれはそうとではありません。 Photoshopがどのようにグレースケールに変換するためのさまざまな方法を提供するかを思い出してください。あなたは平均、輝度、強度、軽さ、など

ここでのonclickを示しますフィドルだを持っています。値は0〜1の浮動小数点として表示されます。 0は黒である。このstackoverflowのを参照して、スクリーンピクセルの代わりに、マウス位置に、世界の特定のポイントを取得するには

https://jsfiddle.net/schnfteb/

//assumes wegbGL renderer 
renderer.domElement.addEventListener("click",function(event){ 

    var mousePos = getMousePos(this, event); 
    var y = mousePos.y; 
    var x = mousePos.x; 

    var offscreenCanvas = document.createElement("canvas"); 
    offscreenCanvas.width = this.width; 
    offscreenCanvas.height = this.height; 
    var ctx = offscreenCanvas.getContext("2d"); 

    ctx.drawImage(this,0,0); 
    var imageData = ctx.getImageData(x,y, 1, 1); 
    var c = imageData.data; 
    c = [c[0], c[1],c[2]]; 
    var lightness = ((Math.max.apply(null, c) + Math.min.apply(null, c))/2)/255; 
    var intensity = (65536 * c[0] + 256 * c[1] + c[2])/16777216; 
    var average = ((c[0]+c[1]+c[2])/3)/255; 
    var luminosity = ((0.21 * c[0]) + (0.72 * c[1]) + (0.07 * c[2]))/255; 
    console.log(lightness, intensity, average, luminosity); 

},false); 

は、道の残りの部分を行く:フィドル作業

Converting 3D position to 2d screen position [r69!]

+0

'body {margin:0}'はマウスクリックの精度に役立つかもしれません。キューブの色を '0xffffff'に設定すると、より直感的な結果が得られます。 – WestLangley

+0

ええ、より明るい光を得るために、グレースケールへの変換を赤色に設定しました。しかし、ええ。私はOPがマージンを作る位置リンクをスクリーンするために3dの位置に従うと考えました。しかし、完全に、はい、答えはコンセプトを示し、文脈上の調整が必要です。 – Radio

+1

ありがとうございます。それはすごく助けになった! あなたのコードで私が理解していないことが1つ考えられます。 あなたは.setPixelRatioをコメントアウトしました。私はこれをコメントを外すと、私はもはや適切な価値を得ることができません。どうして? – gauguerilla

関連する問題