<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@0.147/build/three.module.js",
"three/addons/": "https://unpkg.com/three@0.147/examples/jsm/"
}
}
</script>
<div class="container">
body {
margin: 0px;
overflow: hidden;
}
.container{
position:fixed;
top:0;
left:0;
width:100%;
height:100%;
background-color:#030303;
}
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { TransformControls } from 'three/addons/controls/TransformControls.js'
let mesh, renderer, scene, camera, controls, transformControl, sp, bo;
let container = document.querySelector('.container')
let anim = true
const vsShader = `
varying vec4 pos;
void main() {
pos = modelMatrix * vec4(position, 1.0);
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`;
const fragmentShader = `
uniform vec3 boxMin;
uniform vec3 boxMax;
uniform vec3 boxColor;
varying vec4 pos;
void main() {
vec3 color1 = vec3(1.0, 0.0, 0.0); // red
vec3 color2 = vec3(1.0, 0.5, 0.0); // orange
vec3 color3 = vec3(1.0, 1.0, 0.0); // yellow
vec3 color4 = vec3(0.0, 1.0, 0.0); // green
vec3 color5 = vec3(0.0, 0.0, 1.0); // blue
float gradientOffset = (pos.y / (boxMax.y * 2.0)) - 0.1;
vec3 startColor;
vec3 endColor;
if (gradientOffset < -0.4) {
startColor = color5;
endColor = color4;
} else if (gradientOffset < -0.2) {
startColor = color4;
endColor = color3;
} else if (gradientOffset < 0.0) {
startColor = color3;
endColor = color2;
} else if (gradientOffset < 0.2) {
startColor = color2;
endColor = color1;
}else if (gradientOffset < 0.4) {
startColor = color1;
endColor = color1;
};
vec3 gradientColor = mix(startColor, endColor, fract(gradientOffset * 5.0));
// Check if the model vertex is outside the box range
if (pos.x < boxMin.x || pos.x > boxMax.x ||
pos.y < boxMin.y || pos.y > boxMax.y ||
pos.z < boxMin.z || pos.z > boxMax.z) {
// If it is outside the range, use the mesh colour
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
} else {
// If it is within the range, use gradient color
gl_FragColor = vec4(gradientColor, 1.0);
}
}
`;
init();
function init() {
// renderer
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 0.1, 10000);
camera.position.set(300, 300, 300);
// controls
controls = new OrbitControls(camera, renderer.domElement);
// ambient
scene.add(new THREE.AmbientLight(0x222222));
// light
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(20, 20, 0);
scene.add(light);
const box = new THREE.BoxGeometry(
192,
124,
220
);
const lineMaterial = setLineMaterial();
const lineSegments = new THREE.LineSegments(box, lineMaterial);
const boxMesh = new THREE.Mesh(box, new THREE.MeshBasicMaterial({
transparent: true,
opacity: 0.1
}));
const box3 = new THREE.Box3();
box3.setFromObject(boxMesh);
console.log(box3);
scene.add(lineSegments);
scene.add(boxMesh);
// geometry
const geometry = new THREE.ConeGeometry(
40,
200,
32
);
const sGeometry = new THREE.SphereGeometry(
40,
200,
32
);
const bGeometry = new THREE.BoxGeometry(
40,
200,
40
);
// material
const material = new THREE.ShaderMaterial({
uniforms: {
boxMin: {
value: new THREE.Vector3(box3.min.x, box3.min.y, box3.min.z)
},
boxMax: {
value: new THREE.Vector3(box3.max.x, box3.max.y, box3.max.z)
},
boxColor: {
value: new THREE.Vector3(1.0, 0.0, 0.0)
},
res: {
value: new THREE.Vector2(1,1)
}
},
vertexShader: vsShader,
fragmentShader: fragmentShader
});
// mesh
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
sp = new THREE.Mesh(sGeometry, material.clone());
bo = new THREE.Mesh(bGeometry, material.clone());
sp.position.z = 70
bo.position.z = -80
scene.add(sp, bo);
// TransformControls
transformControl = new TransformControls(camera, renderer.domElement);
transformControl.addEventListener('dragging-changed', function(event) {
controls.enabled = !event.value;
anim = !event.value;
});
transformControl.attach(mesh);
scene.add(transformControl);
console.log(transformControl.object)
animate();
}
function animate(t) {
if(anim){
transformControl.object.position.y = (Math.sin(t / 1000) * 60) - 100;
}
sp.position.y = (Math.sin((t / 1000) + 10) * 60) - 50;
bo.position.y = (Math.sin((t / 1000) + 5) * 60) - 100;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
function setLineMaterial() {
return new THREE.LineBasicMaterial({
color: 0xffffff,
linewidth: 1,
transparent: true,
opacity: 0.5
});
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.