Skip to content

Instantly share code, notes, and snippets.

@FadedWeiss
Created August 16, 2023 13:50
Show Gist options
  • Save FadedWeiss/62526630277460b1094e294376cac9d7 to your computer and use it in GitHub Desktop.
Save FadedWeiss/62526630277460b1094e294376cac9d7 to your computer and use it in GitHub Desktop.
Clipping Box
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.3/dat.gui.min.js"></script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, 1, 1, 1000);
camera.position.set(0, 120, 90);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setClearColor(0x606060);
var canvas = renderer.domElement;
document.body.appendChild(canvas);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.target = new THREE.Vector3(0, 50, 0);
controls.update();
scene.add(new THREE.GridHelper(50, 50));
let xSize = 50;
let ySize = 100;
let zSize = 50;
let n = xSize * ySize * zSize;
let geometry = new THREE.BufferGeometry();
let positions = [];
for (let i = 0; i < n * 2; i++) {
positions.push(
Math.random() * xSize,
Math.random() * ySize,
Math.random() * zSize
);
}
let positionAttribute = new THREE.Float32BufferAttribute(positions, 3);
geometry.addAttribute("position", positionAttribute);
geometry.center();
geometry.translate(0, ySize * 0.5, 0);
let points = new THREE.Points(
geometry,
new THREE.ShaderMaterial({
uniforms:{
box: {
value: {
size: new THREE.Vector3(10, 10, 10),
position: new THREE.Vector3(0, -5, 0),
rotation: new THREE.Vector3()
}
},
size: {
value: 0.75
}
},
vertexShader:`
uniform float size;
varying vec3 vPos;
void main(){
vPos = position;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_PointSize = size * ( 300.0 / length( mvPosition.xyz ) );
gl_Position = projectionMatrix * mvPosition;
}
`,
fragmentShader: `
struct boxParams {
vec3 size;
vec3 position;
vec3 rotation;
};
uniform boxParams box;
varying vec3 vPos;
mat3 rotationMatrix(vec3 axis, float angle)
{
axis = normalize(axis);
float s = sin(angle);
float c = cos(angle);
float oc = 1.0 - c;
return mat3(
oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s,
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s,
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c
);
}
bool isInside(boxParams box, vec3 pt){
vec3 nullVector0 = - box.size * 0.5;
vec3 nullVectorX = nullVector0 + vec3(box.size.x, 0, 0);
vec3 nullVectorY = nullVector0 + vec3(0, box.size.y, 0);
vec3 nullVectorZ = nullVector0 + vec3(0, 0, box.size.z);
mat3 matX = rotationMatrix(vec3(1, 0, 0), box.rotation.x);
mat3 matY = rotationMatrix(vec3(0, 1, 0), box.rotation.y);
mat3 matZ = rotationMatrix(vec3(0, 0, 1), box.rotation.z);
mat3 mat = matX * matY * matZ;
nullVector0 = nullVector0 * mat + box.position;
nullVectorX = nullVectorX * mat + box.position;
nullVectorY = nullVectorY * mat + box.position;
nullVectorZ = nullVectorZ * mat + box.position;
vec3 ptPos = pt - nullVector0;
vec3 nullX = nullVectorX - nullVector0;
vec3 nullY = nullVectorY - nullVector0;
vec3 nullZ = nullVectorZ - nullVector0;
float dotX = dot(nullX, ptPos);
float dotY = dot(nullY, ptPos);
float dotZ = dot(nullZ, ptPos);
float dotNullX = dot(nullX, nullX);
float dotNullY = dot(nullY, nullY);
float dotNullZ = dot(nullZ, nullZ);
bool isX = (0.0 <= dotX) && (dotX <= dotNullX);
bool isY = (0.0 <= dotY) && (dotY <= dotNullY);
bool isZ = (0.0 <= dotZ) && (dotZ <= dotNullZ);
return isX && isY && isZ;
}
void main(){
if (isInside(box, vPos) == false) discard;
gl_FragColor = vec4(0.0, 1.0, 1.0, 1.0);
}
`})
);
scene.add(points);
var box3 = new THREE.Box3().setFromObject(points);
var box3Helper = new THREE.Box3Helper(box3, 0x404040);
scene.add(box3Helper);
var clock = new THREE.Clock();
var delta = 0;
var time = 0;
var boxSpeed = 12.5;
var boxRotation = new THREE.Vector3(Math.PI * 0.5, Math.PI, Math.PI * 0.25);
var gui = new dat.GUI();
var linearSpeed = gui.addFolder("linear speed");
linearSpeed.add(window, "boxSpeed", 0, 25).name("y");
linearSpeed.open();
var rotationSpeed = gui.addFolder("rotation speed")
rotationSpeed.add(boxRotation, "x", -Math.PI, Math.PI).name("x");
rotationSpeed.add(boxRotation, "y", -Math.PI, Math.PI).name("y");
rotationSpeed.add(boxRotation, "z", -Math.PI, Math.PI).name("z");
rotationSpeed.open();
render();
function resize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
function render() {
if (resize(renderer)) {
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
delta = clock.getDelta();
time += delta;
points.material.uniforms.box.value.position.y += boxSpeed * delta;
points.material.uniforms.box.value.rotation.addScaledVector(boxRotation, delta);
if (points.material.uniforms.box.value.position.y >= ySize + (points.material.uniforms.box.value.size.y * 0.5)){
points.material.uniforms.box.value.size.set(
THREE.Math.randInt(5, 30),
THREE.Math.randInt(5, 30),
THREE.Math.randInt(5, 30)
);
points.material.uniforms.box.value.position.x = THREE.Math.randFloatSpread(50);
points.material.uniforms.box.value.position.z = THREE.Math.randFloatSpread(50);
points.material.uniforms.box.value.position.y = -points.material.uniforms.box.value.size.y * 0.5;
}
renderer.render(scene, camera);
requestAnimationFrame(render);
}
html, body {
height: 100%;
margin: 0;
overflow: hidden;
}
canvas {
width: 100%;
height: 100%;
display; block;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment