Reputation: 131
I am Japanese, not good at English, sorry.
I am studying Three.js.
I want to set Plane as a background right in front of the camera.
And I want the Plane background to be completely filling the window(renderer).
But now it's like this.
The Plane is blue.
It is little bit small.
Here is the code.
function init() {
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
scene.add(camera);
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 100;
camera.lookAt(scene.position); // (0, 0, 0)
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0xe3e3e3));
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(50, 50, 50);
spotLight.castShadow = true;
scene.add(spotLight);
// I want to put Plane's size as full background. not (82, 82 * window.innerHeight / window.innerWidth)
var planeGeometry = new THREE.PlaneGeometry(82, 82 * window.innerHeight / window.innerWidth);
var planeMaterial = new THREE.MeshLambertMaterial({color: 0x123abc});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.receiveShadow = true;
plane.position.x = 0;
plane.position.y = 0;
plane.position.z = 0;
scene.add(plane);
var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff0000});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.x = 2
cube.position.y = 10
cube.position.z = 2
cube.castShadow = true
scene.add(cube);
document.getElementById("WebGL-output").appendChild(renderer.domElement);
renderer.render(scene, camera);
}
window.onload = init;
<script src="https://rawcdn.githack.com/mrdoob/three.js/r113/build/three.js"></script>
<div id="WebGL-output"></div>
I want to use the plane as a completely filled background of window.
My camera position is
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 100;
So it is watching the seen from perfectly front.
And the reason why I set 82 as Plane's width sample is this
I set camera.position.z = 100;
and fov is 45deg.
So I thought if you make a triangle like the image and calculate, the full width of (0, 0, 0) should be like that.
I get the 82.842... from some website that can calculate triangle from is's shape and degree.
Upvotes: 4
Views: 2889
Reputation: 210889
82.842 is correct, but the field of view angle of the PerspectiveCamera
is the angle on the y-axis (vertical).
To compute the field of view you have to use the tangents (tan
). The field of view along the y axis is
fov_y = z * tan(angle / 2) * 2
Apply that to your code:
let ang_rad = 45.0 * Math.PI / 180;
let fov_y = 100 * Math.tan(ang_rad / 2) * 2;
var planeGeometry =
new THREE.PlaneGeometry(fov_y * window.innerWidth / window.innerHeight, fov_y);
Respectively
let ang_rad = camera.fov * Math.PI / 180;
let fov_y = camera.position.z * Math.tan(ang_rad / 2) * 2;
var planeGeometry = new THREE.PlaneGeometry(fov_y * camera.aspect, fov_y);
You can simplify the computation by retrieving the focal length (.getFocalLength ()
) and the film height (.getFilmHeight()
):
let fov_y = camera.position.z * camera.getFilmHeight() / camera.getFocalLength();
var planeGeometry = new THREE.PlaneGeometry(fov_y * camera.aspect, fov_y);
function init() {
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
scene.add(camera);
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 100;
camera.lookAt(scene.position); // (0, 0, 0)
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0xe3e3e3));
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(50, 50, 50);
spotLight.castShadow = true;
scene.add(spotLight);
// I want to put Plane's size as full background. not (82, 82 * window.innerHeight / window.innerWidth)
let ang_rad = camera.fov * Math.PI / 180;
let fov_y = camera.position.z * Math.tan(ang_rad / 2) * 2;
var planeGeometry = new THREE.PlaneGeometry(fov_y * camera.aspect, fov_y);
var planeMaterial = new THREE.MeshLambertMaterial({color: 0x123abc});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.receiveShadow = true;
plane.position.x = 0;
plane.position.y = 0;
plane.position.z = 0;
scene.add(plane);
var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff0000});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.x = 2
cube.position.y = 10
cube.position.z = 2
cube.castShadow = true
scene.add(cube);
document.getElementById("WebGL-output").appendChild(renderer.domElement);
renderer.render(scene, camera);
}
window.onload = init;
<script src="https://rawcdn.githack.com/mrdoob/three.js/r113/build/three.js"></script>#
<div id="WebGL-output"></div>
Upvotes: 6