Hi everyone,
Actually i have two questions about it.
- Question
I tried to use outlinepass for my project. According to example outlinepass there is a new composer. and if i use it in my project outlinepass works. But render quality drops. How can i fix it.
Reference: https://prnt.sc/tfxyeq
2.Question
Outline appears around child meshes so actually i want it to be appear whole object. How can i make it i couldnt figure it out.
My Codes:
var scene, camera, renderer, controls, container;
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var selectedObjects = [];
var composer, effectFXAA, outlinePass;
var model;
var models = new THREE.Group();
init();
animate();
function init() {
scene = new THREE.Scene();
// Environment
loadEnvironment("textures/venice_sunset_1k.hdr").then(function (envMap) {
scene.background = envMap;
scene.environment = envMap;
});
camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
1,
2000
);
var ambient = new THREE.AmbientLight(0x404040, 5); // soft white light
scene.add(ambient);
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
container = document.getElementById("container");
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 0.85;
container.appendChild(renderer.domElement);
controls = new IndoorControls(camera, renderer.domElement);
//Mouse Helper
let helperMaterial = new THREE.MeshBasicMaterial();
helperMaterial.transparent = true;
helperMaterial.opacity = 0.2;
let helperGeometry = new THREE.CircleBufferGeometry(0.2, 64);
let mouseHelper = new THREE.Mesh(helperGeometry, helperMaterial);
let ringMaterial = new THREE.MeshBasicMaterial();
ringMaterial.transparent = true;
ringMaterial.opacity = 0.8;
let ringGeometry = new THREE.RingBufferGeometry(0.2, 0.22, 64);
let ring = new THREE.Mesh(ringGeometry, ringMaterial);
mouseHelper.add(ring);
mouseHelper.visible = false;
mouseHelper.renderOrder = 1;
scene.add(mouseHelper);
//
controls.addEventListener("move", function (event) {
let intersect = event.intersect;
let normal = intersect.face.normal;
if (normal.y !== 1) {
mouseHelper.visible = false;
controls.enabled_move = false;
} else {
mouseHelper.position.set(0, 0, 0);
mouseHelper.lookAt(normal);
mouseHelper.position.copy(intersect.point);
mouseHelper.position.addScaledVector(normal, 0.001);
mouseHelper.visible = true;
controls.enabled_move = true;
}
});
//Load meshes here
// Sahne Oda
const loader = new GLTFLoader();
loader.load("models/room5.glb", function (object) {
object.scene.traverse(function (child) {
if (child.isMesh) {
child.casæßtShadow = true;
child.receiveShadow = true;
}
if (child.name === "Floor") controls.ground.push(child);
});
var showroom = new THREE.Object3D();
scene.add(showroom);
showroom.add(object.scene);
setModelConfig(showroom);
});
//Modeller
//setModel("models/products/ritual-luxury1.glb", "Ritual", -3.2, 9);
var manager = new THREE.LoadingManager();
manager.onProgress = function (item, loaded, total) {
console.log(item, loaded, total);
};
loader.load("models/products/ritual-luxury1.glb", function (object) {
var ritual = object.scene;
ritual.traverse(function (child) {
if (child.isMesh) {
child.receiveShadow = true;
child.castShadow = true;
}
});
ritual.name = "Ritual";
ritual.position.z = 9;
ritual.position.x = -3.2;
models.add(ritual);
scene.add(models);
});
setModel("models/products/tv.glb", "Tv", -5.5, 11.2, 0);
console.log(models);
composer = new EffectComposer(renderer);
var renderPass = new RenderPass(scene, camera);
composer.addPass(renderPass);
outlinePass = new OutlinePass(
new THREE.Vector2(window.innerWidth, window.innerHeight),
scene,
camera
);
composer.addPass(outlinePass);
window.addEventListener("resize", onWindowResize, false);
window.addEventListener("mousemove", onTouchMove);
window.addEventListener("touchmove", onTouchMove);
function onTouchMove(event) {
var x, y;
if (event.changedTouches) {
x = event.changedTouches[0].pageX;
y = event.changedTouches[0].pageY;
} else {
x = event.clientX;
y = event.clientY;
}
mouse.x = (x / window.innerWidth) * 2 - 1;
mouse.y = -(y / window.innerHeight) * 2 + 1;
checkIntersection();
}
function addSelectedObject(object) {
selectedObjects = [];
selectedObjects.push(object);
}
function checkIntersection() {
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects([models], true);
if (intersects.length > 0) {
var selectedObject = intersects[0].object;
addSelectedObject(selectedObject);
outlinePass.selectedObjects = selectedObjects;
} else {
// outlinePass.selectedObjects = [];
}
}
}
function setModel(url, modelName, pX = 0, pZ = 0, rY = 0) {
const gltfLoader = new GLTFLoader();
gltfLoader.load(url, function (object) {
let gltf = object.scene || object.scenes[0];
gltf.traverse(function (node) {
// Gölge almak ve oluşturmak için modelin tüm düğümlerini ayarlayın
node.receiveShadow = true;
if (node.isMesh || node.isLight) node.castShadow = true;
});
gltf.position.x = pX;
gltf.position.z = pZ;
gltf.rotation.y = rY;
model = gltf;
gltf.name = modelName;
models.add(gltf);
});
}
function setModelConfig(sceneImport) {
// İçe aktarılan modele aralık kutusu alın
let boxSize = new THREE.Vector3();
const roomBox = new THREE.Box3().setFromObject(sceneImport);
const size = roomBox.getSize(boxSize).length();
const center = roomBox.getCenter(new THREE.Vector3());
camera.near = size / 100;
camera.far = size * 100;
camera.position.copy(center);
// Nesnenin İçinde
camera.position.y -= 0.9;
camera.position.z += 14; //Dikine sahne uzaklığını belirle
let cameraLook = camera.position.clone();
cameraLook.x += boxSize.x * 0.02;
cameraLook.y -= boxSize.y * 0.02;
cameraLook.z += boxSize.z * -1; // Sağa sola kamera dönüşü sağla
camera.lookAt(cameraLook);
camera.updateProjectionMatrix();
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
controls.reset(camera, renderer.domElement);
}
// Environment Loader
function loadEnvironment(url) {
let rgbeLoader = new RGBELoader();
rgbeLoader.setDataType(THREE.UnsignedByteType);
return new Promise((resolve) => {
rgbeLoader.load(url, function (texture) {
let pmremGenerator = new THREE.PMREMGenerator(renderer);
pmremGenerator.compileEquirectangularShader();
let envMap = pmremGenerator.fromEquirectangular(texture).texture;
pmremGenerator.dispose();
resolve(envMap);
});
});
}
function animate() {
requestAnimationFrame(animate);
controls.update();
composer.render();
renderer.render(camera, scene);
}
Thanks…