I display the plane with an orthographicCamera in one renderer,
Project a line using a perspective camera
I would like to implement a line being drawn on that plane.
ow can we implement it?
The current state of the code is this:
Adding a camera does not work.
const container = document.getElementById('webgl-container');
let renderer;
const scene = new THREE.Scene();
const gui = new GUI();
const orthographicCamera = setupOrthographicCamera();
scene.add(orthographicCamera);
const perspectiveCamera = setupPerspectiveCamera();
scene.add(perspectiveCamera);
function init() {
renderer = new THREE.WebGL1Renderer({ antialias: true, logarithmicDepthBuffer: true });
renderer.shadowMap.enabled = true;
renderer.setPixelRatio(window.devicePixelRatio);
container.appendChild(renderer.domElement);
const controller = setupControls(orthographicCamera, container);
const cube = setupModel();
scene.add(cube);
setupLine();
render();
}
function setupLine() {
const PATH_SEGMENTS = 32;
const THICKNESS = 0.5;
const SHADER_THICKNESS = 0.4;
const Roundness = 12;
const IS_Closed = false;
const linePoints = [new THREE.Vector3(0, 0, 0).multiplyScalar(2.5)];
const lineMaterial = new THREE.ShaderMaterial({
uniforms: {
color: { value: new THREE.Color("red") },
maxZ: { value: 0.0 }, // 초기값으로 0.0 설정
minZ: { value: 0.0 } // 초기값으로 0.0 설정
},
vertexShader: `
uniform float maxZ;
uniform float minZ;
varying float alpha;
void main() {
float range = maxZ - minZ;
alpha = smoothstep(0.7, 1.0, (abs(position.z - minZ) / range));
alpha = min(alpha, 0.7); // 최대 0.7까지 제한
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
fragmentShader: `
uniform vec3 color;
varying float alpha;
void main() {
gl_FragColor = vec4(color, 1.0 - alpha); // 처음이 밝고 뒷부분이 어둡게
}
`,
transparent: true,
depthTest: false // 선이 다른 객체를 가리지 않도록 depthTest를 비활성화
});
for (let i = 0; i < trajectory.length; i++) {
linePoints.push( new THREE.Vector3(trajectory[i].x, trajectory[i].z, -trajectory[i].y).multiplyScalar(1));
}
let maxZ = Math.max(...linePoints.map(point => point.z));
let minZ = Math.min(...linePoints.map(point => point.z));
lineMaterial.uniforms.maxZ = { value: maxZ };
lineMaterial.uniforms.minZ = { value: minZ };
const tubeGeometry = new THREE.TubeGeometry(
new THREE.CatmullRomCurve3(linePoints),
PATH_SEGMENTS,
THICKNESS,
Roundness,
IS_Closed //closed
);
const line = new THREE.Mesh(tubeGeometry, lineMaterial);
line.layers.set(2);
scene.add(line)
}
function setupOrthographicCamera() {
const camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
camera.layers.enable(1);
camera.layers.set(1);
const f2 = gui.addFolder('OrthographicCamera Controls');
f2.add(camera, 'left', 1, 1000);
f2.add(camera, 'right', 1, 1000);
f2.add(camera, 'top', 1, 1000);
f2.add(camera, 'bottom', 1, 1000);
f2.add(camera, 'near', 1, 1000);
f2.add(camera, 'far', 1, 1000);
f2.add(camera.position, 'z', -1000, 1000);
const cameraHelper = new THREE.CameraHelper(camera);
scene.add(cameraHelper);
return camera
}
function setupPerspectiveCamera() {
const width = window.innerWidth;
const height = window.innerHeight;
const fov = 75;
const near = 0.1;
const far = 1000;
const camera = new THREE.PerspectiveCamera(
fov,
width / height,
near,
far,
);
camera.layers.enable(2);
camera.layers.set(2);
camera.position.z = 10;
const f1 = gui.addFolder('PerspectiveCamera Controls');
f1.add(camera, 'fov', 1, 1000);
f1.add(camera, 'aspect', 1, 1000);
f1.add(camera, 'near', 1, 1000);
f1.add(camera, 'far', 1, 1000);
f1.add(camera.position, 'z', 1, 1000)
const cameraHelper = new THREE.CameraHelper(camera);
scene.add(cameraHelper);
return camera;
}
function setupModel() {
const textureLoader = new THREE.TextureLoader();
const imageTexture = textureLoader.load('./assets/textures/FrontViewTexture/BG8.jpg');
imageTexture.encoding = THREE.sRGBEncoding;
const geometry = new THREE.PlaneGeometry(2, 2);
const planeMaterial = new THREE.MeshBasicMaterial({ map: imageTexture });
const cube = new THREE.Mesh(geometry, planeMaterial);
cube.layers.set(1);
return cube;
}
function setupControls(camera, container) {
const controller = new OrbitControls(camera, container);
return controller;
}
function render() {
const width = container.clientWidth;
const height = container.clientHeight;
renderer.setSize(width, height);
renderer.render(scene, perspectiveCamera);
renderer.render(scene, orthographicCamera);
requestAnimationFrame(render);
}
function resize() {
const width = container.clientWidth;
const height = container.clientHeight;
orthographicCamera.updateProjectionMatrix();
perspectiveCamera.updateProjectionMatrix();
renderer.setSize(width, height);
}
window.addEventListener('resize', resize);
init();