Monday, March 28, 2022

spring TX trip

expense

March 28 - plane ticket, hotel
March 29 - hotel, ziptie
March 31 - hotel
April 1 - plane ticket, gas, rental car

timesheet
March 28 - travel - 8h
March 29 - install - 8h
March 30 - bundle - 10h
March 31 - training - 8h
April 1 - travel - 8h

Thursday, March 24, 2022

Ridgecrest trip

Expense
March 24 - antigen test, dinner
March 25 - luggage, Uber, phone
March 27 - hotel, rental car, gas x 2

Timesheet
March 24 - preparation - 8h
March 25 - ferry to ridgecrest - 8h
March 26 - troubleshoot - 8h
March 27 - travel - 4h

Rebuilding 10-Speed Manual Transmission

Wednesday, March 23, 2022

topoflight

navigator

planner

download

threejs space warp



//main.js

import './style.css'
import { THREEx } from './threex.js'
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { SpotLight } from 'three';
import {
  GodRaysEffect, BloomEffect, BlendFunction, KernelSize,
  SMAAEffect, EffectComposer, EffectPass, RenderPass
} from 'postprocessing';

// Setup

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);

const renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector('#bg'),
});

renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
camera.position.set(0, 0, 1);
camera.rotation.x = Math.PI / 2;

THREEx.WindowResize(renderer, camera)


const spaceTexture = new THREE.TextureLoader().load('space.jpg');
scene.background = spaceTexture;

const rainDrops = []

for (let j = 0; j < 6000; j++) {
  const rainDrop = new THREE.Vector3(
    Math.random() * 600 - 300,
    Math.random() * 600 - 300,
    Math.random() * 600 - 300
  )

  rainDrop.velocity = 0;
  rainDrop.acceleration = 0.02;
  rainDrops.push(rainDrop);
}

let rainGeo = new THREE.BufferGeometry().setFromPoints(rainDrops);

const rainTexture = new THREE.TextureLoader().load('circle.png');

const rainDropMaterial = new THREE.PointsMaterial({
  color: 0xaaaaaa,
  size: 0.7,
  transparent: true,
  map: rainTexture
})

let rain = new THREE.Points(
  rainGeo,
  rainDropMaterial
)

scene.add(rain)

function animate() {
  requestAnimationFrame(animate);

  scene.remove(rain)

  rainDrops.forEach(p => {
    //console.log(p)
    p.velocity += p.acceleration;
    p.y -= p.velocity;

    if (p.y < -200) {
      p.y = 200;
      p.velocity = 0;
    }
  })

  rainGeo = new THREE.BufferGeometry().setFromPoints(rainDrops);

  rain = new THREE.Points(
    rainGeo,
    rainDropMaterial
  )

  rain.rotation.y += 0.002;
  scene.add(rain)

  renderer.render(scene, camera);
}

animate()

-----------------------
//index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="favicon.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
      <title>Jeff's Website</title>
  </head>
  <body>

    <canvas id="bg"></canvas>   
    <main class="login-form">
      <div>
      <h2>TO INFINITY AND BEYOND</h2>
      <div style="justify-content: space-around; display: flex;">
        <div class="outline-btn">Contact Us</div>
        <div class="outline-btn">Learn More</div>
      </div>
    </div>
    </main>
 
    <script type="module" src="/main.js"></script>

  </body>
  </html>

-----------------------
//style.css

 .login-form {
    width: 100vw;
    height: 100vh;
    margin: 0;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .outline-btn {
    border: 1px solid white;
    background-color: transparent;
    color: white;
    padding: 3px 6px;
    font-size: 20px;
    cursor: pointer;
  }

reference:

Tuesday, March 22, 2022

threejs resize window


--threejs
    --main.js
    --threex.js

//threex.js

// This THREEx helper makes it easy to handle window resize.
// It will update renderer and camera when window is resized.
//
// # Usage
//
// **Step 1**: Start updating renderer and camera
//
// ```var windowResize = new THREEx.WindowResize(aRenderer, aCamera)```
//    
// **Step 2**: stop updating renderer and camera
//
// ```windowResize.destroy()```
// # Code

//

/** @namespace */
var THREEx = THREEx || {}

/**
 * Update renderer and camera when the window is resized
 * 
 * @param {Object} renderer the renderer to update
 * @param {Object} Camera the camera to update
 * @param {Function} dimension callback for renderer size
*/
THREEx.WindowResize = function (renderer, camera, dimension) {
    dimension = dimension || function () { return { width: window.innerWidth, height: window.innerHeight } }
    var callback = function () {
        // fetch target renderer size
        var rendererSize = dimension();
        // notify the renderer of the size change
        renderer.setSize(rendererSize.width, rendererSize.height)
        // update the camera
        camera.aspect = rendererSize.width / rendererSize.height
        camera.updateProjectionMatrix()
    }
    // bind the resize event
    window.addEventListener('resize', callback, false)
    // return .stop() the function to stop watching window resize
    return {
        trigger: function () {
            callback()
        },
        /**
         * Stop watching window resize
        */
        destroy: function () {
            window.removeEventListener('resize', callback)
        }
    }
}

export { THREEx }

---------------------------
//main.js

import './style.css'
import { THREEx } from './threex.js'
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { SpotLight } from 'three';
import {
  GodRaysEffect, BloomEffect, BlendFunction, KernelSize,
  SMAAEffect, EffectComposer, EffectPass, RenderPass
} from 'postprocessing';


const scene = new THREE.Scene();

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

const renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector('#bg'),
});

renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
camera.position.set(0, 0, 1);
camera.rotation.x = 1.3;
camera.rotation.y = -0.075;
camera.rotation.z = 0.65;

THREEx.WindowResize(renderer, camera)

const ambientLight = new THREE.AmbientLight(0x555555);
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xff8c19);
directionalLight.position.set(0, 0, 1);
scene.add(directionalLight)

const orangeLight = new THREE.PointLight(0xcc6600, 1, 400, 1.7)
orangeLight.position.set(-200, 300, -200)
scene.add(orangeLight)

const redLight = new THREE.PointLight(0xd8547e, 1, 400, 1.7)
redLight.position.set(0, 300, 0)
scene.add(redLight)

const blueLight = new THREE.PointLight(0x3677ac, 1, 400, 1.7)
blueLight.position.set(200, 300, 200)
scene.add(blueLight)

scene.fog = new THREE.FogExp2(0x03544e, 0.001)
renderer.setClearColor(scene.fog.color)

const bloom = new BloomEffect({
  blendFunction: BlendFunction.COLOR_DODGE,
  kernelSize: KernelSize.SMALL,
  useLuminanceFilter: true,
  luminanceThreshold: 0.3,
  luminanceSmoothing: 0.75
})
bloom.blendMode.opacity.value = 1.5

const composer = new EffectComposer(renderer);
composer.addPass(new RenderPass(scene, camera));
composer.addPass(new EffectPass(camera, bloom));

const spaceTexture = new THREE.TextureLoader().load('space.jpg');
scene.background = spaceTexture;

const dustCloud = []

const smokeTexture = new THREE.TextureLoader().load('smoke particle.png');

for (let i = 0; i < 50; i++) {
  const smoke = new THREE.Mesh(
    new THREE.PlaneBufferGeometry(500, 500),
    new THREE.MeshStandardMaterial({
      map: smokeTexture,
      transparent: true
    })
  )

  smoke.position.set(
    Math.random() * 800 - 400,
    500,
    Math.random() * 500 - 400
  )

  smoke.rotation.x = 1.16;
  smoke.rotation.y = -0.12;
  smoke.rotation.z = Math.random() * 2 * Math.PI;
  smoke.material.opacity = 0.6;

  scene.add(smoke)
  dustCloud.push(smoke)
}

function moveCamera() {
  const t = document.body.getBoundingClientRect().top;

  camera.position.x = t * -0.002;
  camera.rotation.y = t * -0.002;
  camera.position.z = 30 - t * 0.01;
}

function animate() {
  requestAnimationFrame(animate);

  dustCloud.forEach(p => {
    p.rotation.z -= 0.001;
  })

  composer.render();
}

animate()

reference:

Monday, March 21, 2022

Chicago SEAFOOD TOWER

DOE

expense

March 16 - Memory express
March 17 - dinner
March 18 - dinner, Canadian tire, driving 150km
March 19 - lunch, driving 150km
March 21 - lunch x 2, nofrill, dinner, fuel

timesheet
March 15 - preparation - 7h
March 16 - preparation -12h
March 17 - preparation - 12h
March 18 - installation - 12h
March 19 - installation - 6h - Houston preparation - 4h
March 21 - bundle - 10h

Saturday, March 12, 2022

Reno trip

expense
March 12 - antigen test, parking, dinner, plane ticket, driving 50km
March 13 - baggage, hotel, phone, uber
March 14 - antigen test, parking, gas, hotel, plane ticket
March 15 - rental car, gas, baggage, uber

timesheet
March 12 - preparation - 12h
March 13 - travel, troubleshoot - 14h
March 14 - travel, calibration - 14h
March 15 - ferry back - 8h

Thursday, March 10, 2022

threejs nebular



//main.js

import './style.css'
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { SpotLight } from 'three';
import {
  GodRaysEffect, BloomEffect, BlendFunction, KernelSize,
  SMAAEffect, EffectComposer, EffectPass, RenderPass
} from 'postprocessing';

// Setup

const scene = new THREE.Scene();

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

const renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector('#bg'),
});

renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
camera.position.set(0, 0, 1);
camera.rotation.x = 1.3;
camera.rotation.y = -0.075;
camera.rotation.z = 0.65;

renderer.render(scene, camera);

const ambientLight = new THREE.AmbientLight(0x555555);
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xff8c19);
directionalLight.position.set(0, 0, 1);
scene.add(directionalLight)

const orangeLight = new THREE.PointLight(0xcc6600, 1, 400, 1.7)
orangeLight.position.set(-200, 300, -200)
scene.add(orangeLight)

const redLight = new THREE.PointLight(0xd8547e, 1, 400, 1.7)
redLight.position.set(0, 300, 0)
scene.add(redLight)

const blueLight = new THREE.PointLight(0x3677ac, 1, 400, 1.7)
blueLight.position.set(200, 300, 200)
scene.add(blueLight)

scene.fog = new THREE.FogExp2(0x03544e, 0.001)
renderer.setClearColor(scene.fog.color)

const bloom = new BloomEffect({
  blendFunction: BlendFunction.COLOR_DODGE,
  kernelSize: KernelSize.SMALL,
  useLuminanceFilter: true,
  luminanceThreshold: 0.3,
  luminanceSmoothing: 0.75
})
bloom.blendMode.opacity.value = 1.5

const composer = new EffectComposer(renderer);
composer.addPass(new RenderPass(scene, camera));
composer.addPass(new EffectPass(camera, bloom));

const spaceTexture = new THREE.TextureLoader().load('space.jpg');
scene.background = spaceTexture;

const dustCloud = []

const smokeTexture = new THREE.TextureLoader().load('smoke particle.png');

for (let i = 0; i < 50; i++) {
  const smoke = new THREE.Mesh(
    new THREE.PlaneBufferGeometry(500, 500),
    new THREE.MeshStandardMaterial({
      map: smokeTexture,
      transparent: true
    })
  )

  smoke.position.set(
    Math.random() * 800 - 400,
    500,
    Math.random() * 500 - 400
  )

  smoke.rotation.x = 1.16;
  smoke.rotation.y = -0.12;
  smoke.rotation.z = Math.random() * 2 * Math.PI;
  smoke.material.opacity = 0.6;

  scene.add(smoke)
  dustCloud.push(smoke)
}

function moveCamera() {
  const t = document.body.getBoundingClientRect().top;

  camera.position.x = t * -0.002;
  camera.rotation.y = t * -0.002;
  camera.position.z = 30 - t * 0.01;
}

function animate() {
  requestAnimationFrame(animate);

  dustCloud.forEach(p => {
    p.rotation.z -= 0.001;
  })

  composer.render();
}

animate()

---------------------
//index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="favicon.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
      <title>Jeff's Website</title>
  </head>
  <body>

    <canvas id="bg"></canvas>   
    <main>
      <div class="login-form">
    <div class="login-div">
      <div class="row">
        <div class="logo"></div>
      </div>
      <div class="row center-align">
        <h5>Sign in</h5>
        <h6>Use your Red Stapler Account</h6>
      </div>
      <div class="row">
        <div class="input-field col s12">
          <input id="email_input" type="email" class="validate">
          <label for="email_input">Email</label>
        </div>
      </div>
      <div class="row">
        <div class="input-field col s12">
          <input id="password_input" type="password" class="validate">
          <label for="password_input">Password</label>
          <div><a href="#"><b>Forgot password?</b></a></div>
        </div>
      </div>
      <div class="row">
        <div class="col s12">Not your computer? Use a Private Window to sign in. <a href="#"><b>Learn more</b></a></div>
      </div>
      <div class="row"></div>
      <div class="row">
        <div class="col s6"><a href="#">Create account</a></div>
        <div class="col s6 right-align"><a class="waves-effect waves-light btn">Login</a></div>
      </div>
    </div>
  </div>
  </main>
    <!--
    <main>

    <script type="module" src="/main.js"></script>

  </body>
  </html>

----------------------
//style.css

  .login-div {
    max-width: 430px;
    padding: 35px;
    border: 1px solid #ddd;
    border-radius: 8px;
    background: rgba(8,8,8,0.7);
    box-shadow: 1px 1px 20px rgba(0,0,0,0.5);
  }
  .logo {
    background-image: url("Logo.png");
    width:100px;
    height:100px;
    border-radius: 50%;
    margin:0 auto;
  }
  .login-form {
    width: 100vw;
    height: 100vh;
    margin: 0;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
  }

reference:

黑虎虾,皮皮虾

普丁節奏

Tuesday, March 8, 2022

threejs godrays



//terminal
npm install postprocessing

//main.js

import './style.css'
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { SpotLight } from 'three';
import { GodRaysEffect, SMAAEffect, EffectComposer, EffectPass, RenderPass } from 'postprocessing';

// Setup

const scene = new THREE.Scene();
scene.background = new THREE.Color(0x020202);

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

const renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector('#bg'),
});

renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
camera.position.set(0, 0, 1000);

renderer.render(scene, camera);

const directionalLight = new THREE.DirectionalLight(0xffffff, 100);
directionalLight.position.set(0, 0, -1);
scene.add(directionalLight)

const circleGeo = new THREE.CircleGeometry(220, 50);
const circleMaterial = new THREE.MeshBasicMaterial({ color: 0xffccaa });
const circle = new THREE.Mesh(circleGeo, circleMaterial);
circle.position.set(0, 0, -500)
circle.scale.setX(1.2)
scene.add(circle)

const areaImage = new Image();
areaImage.src = SMAAEffect.areaImageDataURL;
const searchImage = new Image();
searchImage.src = SMAAEffect.searchImageDataURL;
const smaa = new SMAAEffect(searchImage, areaImage);

const godrays = new GodRaysEffect(camera, circle, {
  resolutionScale: 1,
  density: 0.6,
  decay: 0.95,
  weight: 0.9,
  samples: 100
})

const composer = new EffectComposer(renderer);
composer.addPass(new RenderPass(scene, camera));
composer.addPass(new EffectPass(camera, smaa, godrays));

const controls = new OrbitControls(camera, renderer.domElement);

// Instantiate a loader
const blenderLoader = new GLTFLoader();

var batman;

blenderLoader.load('batman_logo/scene.gltf', function (gltf) {

  batman = gltf.scene;
  batman.scale.set(100, 100, 100)
  batman.position.set(170, -200, 0)

  scene.add(batman)

}, undefined, function (error) {

  console.error(error);

});


function animate() {
  requestAnimationFrame(animate);

  controls.update();

  composer.render();
}

animate()

reference:

Monday, March 7, 2022

欧洲:为什么受伤的总是我?

threejs skybox



//main.js

import './style.css'
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { SpotLight } from 'three';

// Setup

const scene = new THREE.Scene();

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

const renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector('#bg'),
});

renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
camera.position.set(-900, -200, -900);

renderer.render(scene, camera);

const materials = []
const texture_ft = new THREE.TextureLoader().load('skybox/arid2_ft.jpg')
const texture_bk = new THREE.TextureLoader().load('skybox/arid2_bk.jpg')
const texture_up = new THREE.TextureLoader().load('skybox/arid2_up.jpg')
const texture_dn = new THREE.TextureLoader().load('skybox/arid2_dn.jpg')
const texture_rt = new THREE.TextureLoader().load('skybox/arid2_rt.jpg')
const texture_lf = new THREE.TextureLoader().load('skybox/arid2_lf.jpg')

materials.push(new THREE.MeshBasicMaterial({ map: texture_ft }))
materials.push(new THREE.MeshBasicMaterial({ map: texture_bk }))
materials.push(new THREE.MeshBasicMaterial({ map: texture_up }))
materials.push(new THREE.MeshBasicMaterial({ map: texture_dn }))
materials.push(new THREE.MeshBasicMaterial({ map: texture_rt }))
materials.push(new THREE.MeshBasicMaterial({ map: texture_lf }))

for (let i = 0; i < 6; i++) {
  materials[i].side = THREE.BackSide;
}

const skyboxGeo = new THREE.BoxGeometry(10000, 10000, 10000);
const skybox = new THREE.Mesh(skyboxGeo, materials)

scene.add(skybox)

const controls = new OrbitControls(camera, renderer.domElement);
controls.minDistance = 500
controls.maxDistance = 1500

function animate() {
  requestAnimationFrame(animate);

  controls.update();

  renderer.render(scene, camera);
}

animate()

reference:

Follow Your Cat

Saturday, March 5, 2022

threejs rain


each raindrop is a vector
Vector3 {x: 2.0756558940764194, y: -88.44726970939564, z: -72.53420307492986, velocity: 0}

//main.js

import './style.css'
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { SpotLight } from 'three';

// Setup

const scene = new THREE.Scene();

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

const renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector('#bg'),
});

renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
camera.position.z = 1;
camera.rotation.x = 1.02;
camera.rotation.y = 0.1584;
camera.rotation.z = -0.2511;

renderer.render(scene, camera);

const pointLight = new THREE.PointLight(0x062d89, 5, 500, 1.7);
pointLight.position.set(200, 300, 100);

const ambientLight = new THREE.AmbientLight(0x555555);
scene.add(pointLight, ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffeedd);
directionalLight.position.set(0, 0, 1);
scene.add(directionalLight)

const lightHelper = new THREE.PointLightHelper(pointLight);
scene.add(lightHelper);

const dustCloud = []

const smokeTexture = new THREE.TextureLoader().load('smoke particle.png');

for (let i = 0; i < 25; i++) {
  const smoke = new THREE.Mesh(
    new THREE.PlaneBufferGeometry(500, 500),
    new THREE.MeshStandardMaterial({
      map: smokeTexture,
      transparent: true
    })
  )

  smoke.position.set(
    Math.random() * 800 - 400,
    500,
    Math.random() * 500 - 400
  )

  smoke.rotation.x = 1.16;
  smoke.rotation.y = 0.12;
  smoke.rotation.z = Math.random() * 360;
  smoke.material.opacity = 0.6;

  scene.add(smoke)
  dustCloud.push(smoke)
}

const rainDrops = []

for (let j = 0; j < 1000; j++) {
  const rainDrop = new THREE.Vector3(
    Math.random() * 400 - 200,
    Math.random() * 500 - 250,
    Math.random() * 400 - 200
  )

  rainDrop.velocity = 0;
  rainDrops.push(rainDrop);
}

let rainGeo = new THREE.BufferGeometry().setFromPoints(rainDrops);

const rainDropMaterial = new THREE.PointsMaterial({
  color: 0xaaaaaa,
  size: 1,
  transparent: true
})

let rain = new THREE.Points(
  rainGeo,
  rainDropMaterial
)

scene.add(rain)

function animate() {
  requestAnimationFrame(animate);

  dustCloud.forEach(p => {
    p.rotation.z -= 0.002;
  })

  if (Math.random() > 0.93 || pointLight.power > 100) {
    if (pointLight.power < 100) {
      pointLight.position.set(
        Math.random() * 400,
        300 + Math.random() * 200,
        100
      );
    }
    pointLight.power = 50 + Math.random() * 500;
  }

  scene.remove(rain)

  rainDrops.forEach(p => {
    p.velocity -= 0.1 + Math.random() * 0.1;
    p.y += p.velocity;

    if (p.y < -200) {
      p.y = 200;
      p.velocity = 0;
    }
  })

  rainGeo = new THREE.BufferGeometry().setFromPoints(rainDrops);

  rain = new THREE.Points(
    rainGeo,
    rainDropMaterial
  )

  scene.add(rain)

  renderer.render(scene, camera);
}

animate()

reference:

Friday, March 4, 2022

threejs thunder cloud


use orbit control to find camera rotation for cloud, then disable orbit control
//main.js

import './style.css'
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { SpotLight } from 'three';

// Setup

const scene = new THREE.Scene();

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

const renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector('#bg'),
});

renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
camera.position.z = 1;
camera.rotation.x = 1.02;
camera.rotation.y = 0.1584;
camera.rotation.z = -0.2511;

renderer.render(scene, camera);

const pointLight = new THREE.PointLight(0x062d89, 5, 500, 1.7);
pointLight.position.set(200, 300, 100);

const ambientLight = new THREE.AmbientLight(0x555555);
scene.add(pointLight, ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffeedd);
directionalLight.position.set(0, 0, 1);
scene.add(directionalLight)

const lightHelper = new THREE.PointLightHelper(pointLight);
scene.add(lightHelper);

//const controls = new OrbitControls(camera, renderer.domElement);

const dustCloud = []

const smokeTexture = new THREE.TextureLoader().load('smoke particle.png');

for (let i = 0; i < 25; i++) {
  const smoke = new THREE.Mesh(
    new THREE.PlaneBufferGeometry(500, 500),
    new THREE.MeshStandardMaterial({
      map: smokeTexture,
      transparent: true
    })
  )

  smoke.position.set(
    Math.random() * 800 - 400,
    500,
    Math.random() * 500 - 400
  )

  smoke.rotation.x = 1.16;
  smoke.rotation.y = 0.12;
  smoke.rotation.z = Math.random() * 360;
  smoke.material.opacity = 0.6;

  scene.add(smoke)
  dustCloud.push(smoke)
}

function animate() {
  requestAnimationFrame(animate);

  //console.log(camera.rotation.x, camera.rotation.y, camera.rotation.z)
  //controls.update();
  
  dustCloud.forEach(p => {
    p.rotation.z -= 0.002;
  })

  if (Math.random() > 0.93 || pointLight.power > 100) {
    if (pointLight.power < 100) {
      pointLight.position.set(
        Math.random() * 400,
        300 + Math.random() * 200,
        100
      );
    }
    pointLight.power = 50 + Math.random() * 500;
  }

  renderer.render(scene, camera);
}

animate()

reference:

Wednesday, March 2, 2022

threejs Thanos Portal Effect



smoke particle
//main.js

import './style.css'
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { SpotLight } from 'three';

// Setup

const scene = new THREE.Scene();

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

const renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector('#bg'),
});

renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
camera.position.setZ(1000);

renderer.render(scene, camera);

const pointLight = new THREE.PointLight(0x062d89, 5, 1000, 1.7);
pointLight.position.set(0, 0, 250);

const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(pointLight, ambientLight);

const lightHelper = new THREE.PointLightHelper(pointLight);
scene.add(lightHelper);

const controls = new OrbitControls(camera, renderer.domElement);

const spaceTexture = new THREE.TextureLoader().load('space.jpg');
scene.background = spaceTexture;

const dustCloud = []

const smokeTexture = new THREE.TextureLoader().load('smoke particle.png');

for (let i = 880; i > 250; i--) {
  const smoke = new THREE.Mesh(
    new THREE.PlaneBufferGeometry(350, 350),
    new THREE.MeshStandardMaterial({
      map: smokeTexture,
      transparent: true
    })
  )

  smoke.position.set(
    0.5 * i * Math.cos((4 * i * Math.PI) / 180),
    0.5 * i * Math.sin((4 * i * Math.PI) / 180),
    0.1 * i
  )

  smoke.rotation.z = Math.random() * 360;

  scene.add(smoke)
  dustCloud.push(smoke)
}

function moveCamera() {
  const t = document.body.getBoundingClientRect().top;

  camera.position.x = t * -0.002;
  camera.rotation.y = t * -0.002;
  camera.position.z = 30 - t * 0.01;
}

document.body.onscroll = moveCamera

let clock = new THREE.Clock();

function animate() {
  requestAnimationFrame(animate);

  let delta = clock.getDelta();

  dustCloud.forEach(p => {
    p.rotation.z -= delta * 1.5;
  })

  if (Math.random() > 0.5) {
    pointLight.power = 50 + Math.random() * 20;
  }

  controls.update();

  renderer.render(scene, camera);
}

animate()

reference:

Tuesday, March 1, 2022

threejs import model from blender


in blender export as gltf

check export only visible object
copy exported donut.glb to threejs directory
//threejs/main.js

import './style.css'
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

// Setup

const scene = new THREE.Scene();

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

const renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector('#bg'),
});

renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
camera.position.setZ(30);

renderer.render(scene, camera);

const pointLight = new THREE.PointLight(0xffffff);
pointLight.position.set(20, 20, 20);

const ambientLight = new THREE.AmbientLight(0xffffff);
scene.add(pointLight, ambientLight);

const lightHelper = new THREE.PointLightHelper(pointLight);
scene.add(lightHelper);

const controls = new OrbitControls(camera, renderer.domElement);

function addStar() {
  const geometry = new THREE.SphereGeometry(0.25, 24, 24);
  const material = new THREE.MeshStandardMaterial({ color: 0xffffff });
  const star = new THREE.Mesh(geometry, material);

  const [x, y, z] = Array(3).fill().map(() => THREE.MathUtils.randFloatSpread(100))

  star.position.set(x, y, z);
  scene.add(star);
}

Array(200).fill().forEach(addStar);

const spaceTexture = new THREE.TextureLoader().load('space.jpg');
scene.background = spaceTexture;


// Instantiate a loader
const blenderLoader = new GLTFLoader();

var donut;

blenderLoader.load('donut.glb', function (gltf) {

  donut = gltf.scene;

  scene.add(donut)

}, undefined, function (error) {

  console.error(error);

});


function moveCamera() {
  const t = document.body.getBoundingClientRect().top;

  donut.rotation.x += 0.05;
  donut.rotation.y += 0.075;
  donut.rotation.z += 0.05;
  const scale = 100
  donut.scale.x = scale
  donut.scale.y = scale
  donut.scale.z = scale

  camera.position.x = t * -0.002;
  camera.rotation.y = t * -0.002;
  camera.position.z = 30 - t * 0.01;
}

document.body.onscroll = moveCamera

function animate() {
  requestAnimationFrame(animate);

  controls.update();

  renderer.render(scene, camera);
}

animate()

reference: