three模拟下雨天路灯三维场景效果代码

代码语言:html

所属分类:三维

代码描述:three模拟下雨天路灯三维场景效果代码

代码标签: three 模拟 下雨 路灯 三维 场景

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>

  <meta charset="UTF-8">
  

  
  
<style>
body {
  min-height: 100vh;
  background: black;
  display: flex;
  align-items: center;
  justify-content: center;
}

canvas {
  max-width: 100vw;
  max-height: 100vh;
  width: auto !important;
  height: auto !important;
}
</style>




</head>

<body >
  <canvas id="canvas"></canvas>

<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/es-module-shims.1.6.3.js"></script>
<script type="importmap">
  {
    "imports": {
      "three": "https://unpkg.com/three@0.147.0/build/three.module.js",
      "three/examples/": "https://unpkg.com/three@0.147.0/examples/",
      "meshline": "https://unpkg.com/meshline@3.1.6/dist/index.js",
      "@/utils/": "https://unpkg.com/@callumacrae/utils@0.6.0/built/",
      "seed-random": "https://cdn.skypack.dev/seed-random@2.2.0",
        "tweakpane": "https://cdn.skypack.dev/tweakpane@3.1.1",
          "@tweakpane/plugin-essentials": "https://cdn.skypack.dev/@tweakpane/plugin-essentials@0.1.5",
          "d3-ease": "https://cdn.skypack.dev/d3-ease@3.0.1",
          "matter-js": "https://cdn.skypack.dev/matter-js@0.18.0",
          "simplex-noise": "https://cdn.skypack.dev/simplex-noise@3.0.1"
    }
  }
</script>

      <script  type="module">
import SimplexNoise from 'simplex-noise';
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass';
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass';
import { extendMaterial } from '@/utils/three-extend-material';
import * as random from '@/utils/random';
import { toVanillaCanvas } from '@/utils/renderers/vanilla';
const glsl = String.raw;
const sketchConfig = {
    light: {
        color: 0xe2af6c,
        brightness: 0.8,
        decay: 3,
    },
    toneMappingExposure: 1.2,
    toneMapping: THREE.ReinhardToneMapping,
    rain: {
        maxSpeed: 6,
        drops: 7000,
        width: 0.0015,
        lightFactor: 0.3,
    },
    wind: {
        direction: Math.PI * (14 / 8),
        windStrength: 2,
        // Variation 1 = random variation per individual raindrop
        strengthVariation1: 0.2,
        // Variation 2 = variation in overall wind speed applied to all raindrops
        strengthVariation2In: 0.25,
        strengthVariation2Out: 1,
        gustFrequency: 5,
        gustStrength: 5,
    },
    bloom: {
        enabled: true,
        threshold: 0,
        strength: 1.8,
        radius: 1,
    },
};
const presets = {
    default: Object.assign(Object.assign({}, sketchConfig.rain), sketchConfig.wind),
    'light rain': Object.assign(Object.assign(Object.assign(Object.assign({}, sketchConfig.rain), { maxSpeed: 4, drops: 4000 }), sketchConfig.wind), { windStrength: 1.5, strengthVariation1: 0.3, strengthVariation2In: 0.2, strengthVariation2Out: 0.6, gustFrequency: 2.5, gustStrength: 1.52 }),
    'snow?': Object.assign(Object.assign(Object.assign(Object.assign({}, sketchConfig.rain), { maxSpeed: 0.6, drops: 12000, width: 0.0025 }), sketchConfig.wind), { windStrength: 1.8, strengthVariation1: 0.55, strengthVariation2In: 0.25, strengthVariation2Out: 0.55, gustStrength: 0 }),
};
const sketchbookConfig = {
    type: 'threejs',
    showLoading: true,
    postprocessing: true,
    sketchConfig,
};
function initCamera(scene, { renderer, width, height }) {
    if (!renderer)
        throw new Error('???');
    const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 100);
    camera.position.y = 4.6;
    camera.position.x = -2.8;
    scene.add(camera);
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.target = new THREE.Vector3(0, 4.6, 0);
    controls.update();
    return { camera };
}
const lightGeometry = new THREE.SphereGeometry(0.3, 16, 16);
const lightMaterial = new THREE.MeshStandardMaterial();
async function initLighting(scene, { config }) {
    const loader = new GLTFLoader();
    const lampModel = await loader.loadAsync('//repo.bfw.wiki/bfwrepo/threemodel/rain_scene.gltf');
    lampModel.scene.scale.set(0.305, 0.305, 0.305);
    const sceneLamps = lampModel.scene.getObjectByName('Object_3');
    if (sceneLamps)
        sceneLamps.visible = false;
    scene.add(lampModel.scene);
    const leftLamp = new THREE.Group();
    const leftLampObject = new THREE.Mesh(lightGeometry, lightMaterial);
    leftLamp.add(leftLampObject);
    const pointLightLeft = new THREE.PointLight(0xf6f5af, 1);
    leftLamp.add(pointLightLeft);
    leftLamp.position.set(0, 4.925, -0.82);
    scene.add(leftLamp);
    const rightLamp = new THREE.Group();
    const rightLampObject = new THREE.Mesh(lightGeometry, lightMaterial);
    rightLamp.add(rightLampObject);
    const pointLightRight = pointLightLeft.clone();
    rightLamp.add(pointLightRight);
    rightLamp.position.set(0, 4.925, 0.82);
    scene.add(rightLamp);
    const frame = (props) => {
        if (props.hasChanged && config) {
            lightMaterial.emissive = new THREE.Color(config.light.color);
            lightMaterial.emissiveIntensity = config.light.brightness;
            pointLightLeft.color.set(config.light.color);
            pointLightLeft.intensity = config.light.brightness;
            pointLightLeft.decay = config.light.decay;
            pointLightRight.color.set(config.light.color);
            pointLightRight.intensity = config.light.brightness;
            pointLightRight.decay = config.light.decay;
        }
    };
    return { frame };
}
const rainGeometry = new THREE.CylinderGeometry(1, 1, 1, 4, 1, true);
let oldRainGeometryScale = 1;
const rainMaterial = extendMaterial(THREE.MeshLambertMaterial, {
    class: THREE.ShaderMaterial,
    header: glsl `
    varying float vIsBelowLight;
  `,
    vertexHeader: glsl `
    uniform float uCount;
    uniform float uTime;
    uniform float uMaxSpeed;
    uniform float uWindDirection;
    uniform float uWindStrength;
    uniform float uWindStrengthVariation1;
    uniform float uGustFrequency;
    uniform float uGustStrength;
    uniform vec3 uPointLightPositions[NUM_POINT_LIGHTS];

    attribute vec2 aRandom;

    mat4 translationMatrix(vec3 translation) {
      return mat4(
        1.0, 0.0, 0.0, 0.0,
        0.0, 1.0, 0.0, 0.0,
        0.0, 0.0, 1.0, 0.0,
        translation.x, translation.y, translation.z, 1.0
      );
    }

    mat4 scaleMatrix(vec3 scale) {
      return mat4(
        scale.x, 0.0, 0.0, 0.0,
        0.0, scale.y, 0.0, 0.0,
        0.0, 0.0, scale.z, 0.0,
        0.0, 0.0, 0.0, 1.0
      );
    }

    mat4 rotationXMatrix(float angle) {
      float s = sin(angle);
      float c = cos(angle);

      return mat4(
        1.0, 0.0, 0.0, 0.0,
        0.0, c, s, 0.0,
        0.0, -s, c, 0.0,
        0.0, 0.0, 0.0, 1.0
      );
    }

    mat4 rotationYMatrix(float angle) {
      float s = sin(angle);
      float c = cos(angle);

      return mat4(
        c, 0.0, s, 0.0,
        0.0, 1.0, 0.0, 0.0,
        -s, 0.0, c, 0.0,
        0.0, 0.0, 0.0, 1.0
      );
    }

    // https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83
    vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); }
    float snoise(vec2 v){ const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439); vec2 i  = floor(v + dot(v, C.yy) ); vec2 x0 = v -   i + dot(i, C.xx); vec2 i1; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; i = mod(i, 289.0); vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ; m = m*m ; vec3 x = 2.0 * fract(p * C.www) - 1.0; vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5); vec3 a0 = x - ox; m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); vec3 g; g.x  = a0.x  * x0.x  + h.x  * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); }
  `,
    vertex: {
        project_vertex: {
            '@mvPosition = instanceMatrix * mvPosition;': glsl `
        float positionBeforeWindY = rand(fract(aRandom + 0.2)) * 6.0 + 1.83;

        float size = rand(fract(aRandom + 0.1)) * 0.4 + 0.6;

        float speed = uMaxSpeed * (rand(fract(aRandom + 0.6)) * 0.4 + 0.6) * (size / 2.0 + 0.5);
        positionBeforeWindY -= uTime * speed;
        float fallNum = floor(positionBeforeWindY / 6.0);
        float fallNumRand = fract(fallNum / 12345.678);
        positionBeforeWindY = mod(positionBeforeWindY, 6.0) + 1.83;

        int lightIndex = int(floor(rand(fract(aRandom + fallNumRand + 0.34)) * float(NUM_POINT_LIGHTS)));
        vec3 lightPosition = uPointLightPositions[lightIndex];
        float distFromLight = rand(fract(aRandom + fallNumRand));
        float angleAroundLight = rand(fract(aRandom + fallNumRand + 0.4)) * PI2;

        vec3 positionBeforeWind = vec3(
          lightPosition.x + distFromLight * sin(angleAroundLight),
          positionBeforeWindY,
          lightPosition.z + distFromLight * cos(angleAroundLight)
        );

        float gustNoise = snoise(vec2(
          uTime * 0.2 * pow(uGustFrequency / 4.0, 0.5)
          + positionBeforeWind.z / 100.0 * speed
          + positionBeforeWindY / 100.0 * speed
        ));
        float gustStrength = smoothstep(1.0 - uGustFrequency * 0.15, 1.0, gustNoise) * uGustStrength;
        float windStrength = uWindStrength + gustStrength;
        float angle = PI / 2.5 * (1.0 - pow(1.0 - saturate(windStrength / 10.0), 3.0))
          + (rand(fract(aRandom + 0.87)) - 0.5) * uWindStrengthVariation1;

        // The ideal shutter speed is apparently twice the frame rate (120fps),
        // but setting it to the same as the fra.........完整代码请登录后点击上方下载按钮下载查看

网友评论0