Collision with Particles

I realy like this examle and I want to import my glb model in scene and use this effect.

I add in glb loader function

const loader = new GLTFLoader();
loader.load(‘./obj/moj.glb’, function ( gltf ) {

//gltf.scene.scale.set(10,10,10)

let pts = [];
let v3 = new THREE.Vector3();
gltf.scene.traverse(child => {
    if (child.isMesh){
        let pos = child.geometry.attributes.position;
        for (let i = 0; i < pos.count; i++){
            v3.fromBufferAttribute(pos, i);
            pts.push(v3.clone());
        }
    }
});

g = new THREE.BufferGeometry().setFromPoints(pts);
g.center();

m = new THREE.PointsMaterial({color: "red", size: 0.125});
m.onBeforeCompile = shader => {
    shader.uniforms.mouse = uniforms.mouse;
    shader.uniforms.radius = uniforms.radius;
    //console.log(shader.vertexShader);
    shader.vertexShader = `
        uniform vec3 mouse;
        uniform float radius;
    ` + shader.vertexShader;
    shader.vertexShader = shader.vertexShader.replace(
        `#include <begin_vertex>`,
        `#include <begin_vertex>
            
        vec3 dir = transformed - mouse;
        
        float dist = length(dir);
                
        if (dist < radius){
            float ratio = 1. - dist / radius;
    
            vec3 shift = dir * 2. * (ratio * ratio);
    
            transformed += shift;
        }
        
        `
    );
}

model = new THREE.Points(g, m);
scene.add(model);
},
function ( xhr ) {

    console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );

},
function ( error ) {

    console.log( error );

}

);


but i do not know why my object looks different in threejs. I want same model like in blender

I have to agree.
It’s only a few lines of code.
That the hand of god, or pretty close.

1 Like

Then why do you use a solution for points? :thinking:

Because i want same effect like cylinder on mouse hover. Is posible with some other material

So you’ve got the effect you want, as you chose Points :thinking:

Try to apply the same modifications to the material of the model, using .onBeforeCompile()

I would prefer to use the material that my glb object has. but that’s my problem i don’t know how

You already use .traverse() for the model, so, when child.isMesh is true, it means you’ve got a mesh object, that has both a geometry and a material, thus child.material is the thing you’re looking for.

let m;
let g;
let p;

let materialTest;

var model;

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 100);

camera.position.z = 0.02;

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

const light = new THREE.AmbientLight( 0x404040 );
scene.add( light );

const controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener(“end”, event => {

plane.normal.copy( camera.position );
plane.normal.y = 0;
plane.normal.normalize();

});

var texture = new THREE.TextureLoader().load(“./js/a.png”);//https://threejs.org/examples/textures/sprites/circle.png

const loader = new GLTFLoader();
loader.load(‘./obj/moj66.glb’, function ( gltf ) {

gltf.scene.scale.set(100, 100, 100); 

let pts = [];
let v3 = new THREE.Vector3();
gltf.scene.traverse(child => {
    if (child.isMesh){
        console.log(child.material);
        materialTest = child.material;
        let pos = child.geometry.attributes.position;
        //pos.setX( 1, 2 );
        //console.log(pos);
        for (let i = 0; i < pos.count; i++){
            v3.fromBufferAttribute(pos, i);
            pts.push(v3.clone());
        }
    }
});

g = new THREE.BufferGeometry().setFromPoints(pts);
g.center();

m = new THREE.PointsMaterial({
    size: 0.0003, //0.0125
    map: texture,
    blending: THREE.AdditiveBlending,
    transparent: true,
    depthTest: false,
    sizeAttenuation: true,
    opacity: 1 //3
});
m.onBeforeCompile = shader => {
    shader.uniforms.mouse = uniforms.mouse;
    shader.uniforms.radius = uniforms.radius;
    //console.log(shader.vertexShader);
    shader.vertexShader = `
        uniform vec3 mouse;
        uniform float radius;
    ` + shader.vertexShader;
    shader.vertexShader = shader.vertexShader.replace(
        `#include <begin_vertex>`,
        `#include <begin_vertex>
            
        vec3 dir = transformed - mouse;
        
        float dist = length(dir);
                
        if (dist < radius){
            float ratio = 1. - dist / radius;
    
            vec3 shift = dir * 2. * (ratio * ratio);
    
            transformed += shift;
        }
        
        `
    );
}

model = new THREE.Points(g, m);
scene.add(model);
},
function ( xhr ) {

    console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );

},
function ( error ) {

    console.log( error );

}

);

var uniforms = {
mouse: {
value: new THREE.Vector3()
},
radius: {
value: 0.01
}
};

var plane = new THREE.Plane( new THREE.Vector3(0, 0, 1), 0 );
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
window.addEventListener(“mousemove”, event => {

mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

raycaster.setFromCamera(mouse, camera);

raycaster.ray.intersectPlane(plane, uniforms.mouse.value);

});

window.addEventListener(‘resize’, () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
render();
}, false);

var animate = function() {
requestAnimationFrame(animate);

controls.update();
render();

};

function render() {
renderer.render(scene, camera);
}

animate();

Where I have to make changes?

That’s impressive bedsheet of code. Any chance to provide a working codepen or codesandbox?

Could you explain, for yourself in the first place, what and why each line of code does inside onLoad callback?
Why do you still use Points and that modified PointsMaterial with the new geometry there?
You’ve set materialTest = child.material;. Okay. What and where do you do with it?

1 Like