What’s on our mind?

Collection of articles, design, site, and resources made by designers and publisher @Menu View

* index10.html
//화면 생성
const scene = new THREE.Scene();

//카메라 설정
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(2, 3, 5);

//렌더링 설정
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);

//컨트롤 설정
const controls = new THREE.OrbitControls(camera, renderer.domElement);

//조명 설정
const light = new THREE.DirectionalLight(0xffffff, 0.875);
light.position.set(0, 1, 0);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.125));
//scene.add(new THREE.GridHelper(10, 10));

var spheresAmount = 10;
var spheres = [];
var corpuscules = [];

var sGeom = new THREE.SphereBufferGeometry(0.0625, 8, 8);
var sMat = new THREE.MeshLambertMaterial({color: "red"});
for (let i = 0; i < spheresAmount; i++) {
    let sphere = new THREE.Mesh(sGeom, sMat);
    spheres.push(sphere);
    scene.add(sphere);
    corpuscules.push(sphere.position);
}

var mainSphereGeom = new THREE.SphereBufferGeometry(2, 144, 144).toNonIndexed();
var vertAfter = [];
var vecAfter = new THREE.Vector3();
var vertBefore = [];
var vecBefore = new THREE.Vector3();

var pos = mainSphereGeom.attributes.position;
for (let i = 0; i < pos.count; i++){
    let face = Math.floor(i / 3);
    let afterIdx = (i % 3) + 1;
    afterIdx = afterIdx > 2 ? 0 : afterIdx;
    vecAfter.fromBufferAttribute(pos, (face * 3) + afterIdx);
    vertAfter.push(vecAfter.x, vecAfter.y, vecAfter.z);

    let beforeIdx = (i % 3) - 1;
    beforeIdx = beforeIdx < 0 ? 2 : beforeIdx;
    vecBefore.fromBufferAttribute(pos, (face * 3) + beforeIdx);
    vertBefore.push(vecBefore.x, vecBefore.y, vecBefore.z)
}
mainSphereGeom.setAttribute("vertAfter", new THREE.Float32BufferAttribute(vertAfter, 3));
mainSphereGeom.setAttribute("vertBefore", new THREE.Float32BufferAttribute(vertBefore, 3));

var path = "img";
var format = '.jpg';
var urls = [
    path + 'px' + format, path + 'nx' + format,
    path + 'py' + format, path + 'ny' + format,
    path + 'pz' + format, path + 'nz' + format
];

var cubeTextureLoader = new THREE.CubeTextureLoader();
var reflectionCube = cubeTextureLoader.load(urls);
//scene.background = reflectionCube;

var mainSphereMat = new THREE.MeshStandardMaterial({
    envMap: reflectionCube,
    metalness: 0.01,
    roughness: 4,
    wireframe: true
});
var uniforms = {corpuscules: {value: corpuscules}};
mainSphereMat.onBeforeCompile = shader => {
    shader.uniforms.corpuscules = uniforms.corpuscules;
    shader.vertexShader = `
        uniform vec3 corpuscules[${spheresAmount}];
        attribute vec3 vertAfter;
        attribute vec3 vertBefore;

        vec3 getShiftedPoint(vec3 p){
            vec3 accumulate = vec3(0);

            for(int i = 0; i < ${spheresAmount}; i++){
            vec3 sPos = corpuscules[i];
            vec3 diff = sPos - p;
            vec3 dir = normalize(diff);
            float dist = length(diff);

            float force = .025 / pow(dist, 2.);
            vec3 forceVec = dir * clamp(force, 0., dist);

            accumulate += forceVec;
        }
        return p + accumulate;
    }
` + shader.vertexShader;
shader.vertexShader = shader.vertexShader.replace(
    `#include <begin_vertex>`,
    `#include <begin_vertex>
        transformed = getShiftedPoint(transformed);
        vec3 pointAfter = getShiftedPoint(vertAfter);
        vec3 pointBefore = getShiftedPoint(vertBefore);
        vec3 cb = normalize(pointAfter - transformed);
        vec3 ab = normalize(pointBefore - transformed);
        transformedNormal = cross(cb, ab);
    `
    );
}
var mainSphere = new THREE.Mesh(mainSphereGeom, mainSphereMat);
scene.add(mainSphere);

var clock = new THREE.Clock();

//애니메이션 설정
function animate(a) {
    requestAnimationFrame(animate);

    let t = clock.getElapsedTime() * 0.5;
    spheres.forEach((s, idx) => {
        let angle = Math.PI * (1 / spheresAmount) * 4 * idx + t;
        s.position.set(
            Math.sin(angle) * 3,
            idx * 0.5 - 1,
            idx * 0.5 - 1
        );
    });
    renderer.render(scene, camera);
}
animate();

//화면 사이즈 설정
function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
}
window.addEventListener('resize', onWindowResize);