gau*_*lla 1 javascript 3d three.js
我想知道如何获取场景中给定点的光强度和/或像素值(rgba)。
例如,我有一个场景,移动的光照射在立方体上,并且想要测量立方体上某些点的亮度:
// 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() {
requestAnimationFrame( animate );
light.position.set(lightX,lightY,1);
renderer.render( scene, camera );
}
function mousemove_handler(event)
{
// get Mouse Coords mapped to the 3D Vector
var vector = new THREE.Vector3();
vector.set(
(event.clientX/window.innerWidth) * 2 - 1,
- (event.clientY/window.innerHeight) * 2 + 1,
0.5);
vector.unproject(camera);
var dir = vector.sub(camera.position).normalize();
var distance = - camera.position.z / dir.z;
var pos = camera.position.clone().add(dir.multiplyScalar(distance));
lightX = pos.x;
lightY = pos.y;
}
Run Code Online (Sandbox Code Playgroud)
body { margin: 0; }
canvas { width: 100%; height: 100% }
Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<title>My first three.js app</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.min.js"></script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
这里有很多事情需要考虑。
从显而易见的开始:
现实生活中的光计算取决于干涉、坎德拉、波长等。我不建议使用 webGL 灯进行科学计算,例如太阳能性能。
更远:
3d 中的光使用着色器通道。这意味着照明是对场景的传递。根据场景中的物体(例如窗户等半透明物体),您需要将相机直接移动到相关点上方,从而尽可能清晰地渲染该点。重要的是,我们只能测量面向相机的点。但如果您的场景很简单,那么除非您有剧烈的雾设置,否则这没什么大不了的。
获取特定像素上的光强度如下:
但仍然有一个问题:
转换为灰度并不像看起来那么简单。回想一下 Photoshop 如何为您提供不同的方法来转换为灰度。你有平均值、亮度、强度、亮度等。
这是一个向您显示 onclick 的小提琴。这些值显示为 0-1 浮点数。0 为黑色。
工作小提琴:
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);
Run Code Online (Sandbox Code Playgroud)
走完剩下的路:
要将世界中的特定点获取到屏幕像素而不是鼠标位置,请参阅此 stackoverflow:将 3D 位置转换为 2d 屏幕位置 [r69!]
归档时间: |
|
查看次数: |
1027 次 |
最近记录: |