一个炎爆术分享给大家~

先来强势围观:
在这里插入图片描述
再看代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r120/three.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.7/dat.gui.min.js"></script>
  <style>
    * {
      
      
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
  </style>
</head>
<body>
<div id="world"></div>
</body>
<script type="module">
  import {
      
       EffectComposer } from "https://unpkg.com/[email protected]/examples/jsm/postprocessing/EffectComposer.js";
  import {
      
       RenderPass } from "https://unpkg.com/[email protected]/examples/jsm/postprocessing/RenderPass.js";
  import {
      
       UnrealBloomPass } from "https://unpkg.com/[email protected]/examples/jsm/postprocessing/UnrealBloomPass.js";
  import {
      
       OrbitControls } from "https://unpkg.com/[email protected]/examples/jsm/controls/OrbitControls.js";

  const ENTIRE_SCENE = 0,
          BLOOM_SCENE = 1;

  const bloomLayer = new THREE.Layers();
  bloomLayer.set(BLOOM_SCENE);
  const materials = {
      
      };
  const darkMaterial = new THREE.MeshBasicMaterial({
      
       color: "black" });

  const vert = `
    varying vec3 vNormal;
    varying vec3 camPos;
    varying vec2 vUv;

    void main() {
    vNormal = normal;
    vUv = uv;
    camPos = cameraPosition;
    gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
    }
`;

  const frag = `
#define NUM_OCTAVES 5
#define M_PI 3.1415926535897932384626433832795
uniform vec4 resolution;
varying vec3 vNormal;
uniform sampler2D perlinnoise;
uniform sampler2D sparknoise;
uniform float time;
uniform vec3 color0;
uniform vec3 color1;
uniform vec3 color2;
uniform vec3 color3;
uniform vec3 color4;
uniform vec3 color5;
varying vec3 camPos;
varying vec2 vUv;

float setOpacity(float r, float g, float b, float tonethreshold) {
  float tone = (r + g + b) / 3.0;
  float alpha = 1.0;
  if(tone<tonethreshold) {
    alpha = 0.0;
  }
  return alpha;
}

vec3 rgbcol(vec3 col) {
  return vec3(col.r/255.0,col.g/255.0,col.b/255.0);
}

vec2 rotate(vec2 v, float a) {
  float s = sin(a);
  float c = cos(a);
  mat2 m = mat2(c, -s, s, c);
  return m * v;
}

vec2 UnityPolarCoordinates (vec2 UV, vec2 Center, float RadialScale, float LengthScale){
  //https://twitter.com/Cyanilux/status/1123950519133908995/photo/1
  vec2 delta = UV - Center;
  float radius = length(delta) * 2. * RadialScale;
  float angle = atan(delta.x, delta.y) * 1.0/6.28 * LengthScale;
  return vec2(radius, angle);
}

void main() {
  vec2 olduv = gl_FragCoord.xy/resolution.xy ;
  vec2 uv = vUv ;
  vec2 imguv = uv;
  float scale = 1.;
  olduv *= 0.5 + time;
  olduv.y = olduv.y ;
  vec2 p = olduv*scale;
  vec4 txt = texture2D(perlinnoise, olduv);
  float gradient = dot(normalize( -camPos ), normalize( vNormal ));
  float pct = distance(vUv,vec2(0.5));

  vec3 rgbcolor0 = rgbcol(color0);
  vec3 rgbcolor1 = rgbcol(color1);
  vec3 rgbcolor2 = rgbcol(color2);
  vec3 rgbcolor5 = rgbcol(color5);

  // set solid background
  float y = smoothstep(0.16,0.525,pct);
  vec3 backcolor = mix(rgbcolor0, rgbcolor5, y);

  gl_FragColor = vec4(backcolor,1.);

  // set polar coords
  vec2 center = vec2(0.5);
  vec2 cor = UnityPolarCoordinates(vec2(vUv.x,vUv.y), center, 1., 1.);

  // set textures
  vec2 newUv = vec2(cor.x + time,cor.x*0.2+cor.y);
  vec3 noisetex = texture2D(perlinnoise,mod(newUv,1.)).rgb;
  vec3 noisetex2 = texture2D(sparknoise,mod(newUv,1.)).rgb;


  // set textures tones
  float tone0 =  1. - smoothstep(0.3,0.6,noisetex.r);
  float tone1 =  smoothstep(0.3,0.6,noisetex2.r);


  // set opacity for each tone
  float opacity0 = setOpacity(tone0,tone0,tone0,.29);
  float opacity1 = setOpacity(tone1,tone1,tone1,.49);

  //set final render
  if(opacity1>0.0){
    gl_FragColor = vec4(rgbcolor2,0.)*vec4(opacity1);
  } else if(opacity0>0.0){
    gl_FragColor = vec4(rgbcolor1,0.)*vec4(opacity0);
  }
}
`;

  const vertcylinder = `
    varying vec2 vUv;

    void main() {
        vUv = uv;
        vec3 pos = vec3(position.x/1.,position.y,position.z/1.);
        if(pos.y >= 1.87){
            pos = vec3(position.x*(sin((position.y - 0.6)*1.27)-0.16),position.y,position.z*(sin((position.y - 0.6)*1.27)-0.16));
        } else{
            pos = vec3(position.x*(sin((position.y/2. -  .01)*.11)+0.75),position.y,position.z*(sin((position.y/2. -  .01)*.11)+0.75));
        }
        gl_Position = projectionMatrix * modelViewMatrix * vec4( pos, 1.0 );
    }
`;

  const fragcylinder = `
    varying vec2 vUv;
    uniform sampler2D perlinnoise;
    uniform vec3 color4;
    uniform float time;
    varying vec3 vNormal;

    vec3 rgbcol(vec3 col) {
        return vec3(col.r/255.0,col.g/255.0,col.b/255.0);
    }

    void main() {
        vec3 noisetex = texture2D(perlinnoise,mod(1.*vec2(vUv.y-time*2.,vUv.x + time*1.),1.)).rgb;
        gl_FragColor = vec4(noisetex.r);

        if(gl_FragColor.r >= 0.5){
            gl_FragColor = vec4(rgbcol(color4),gl_FragColor.r);
        }else{
            gl_FragColor = vec4(0.);
        }
        gl_FragColor *= vec4(sin(vUv.y) - 0.1);
        gl_FragColor *= vec4(smoothstep(0.3,0.628,vUv.y));

    }

`;

  const vertflame = `
    varying vec2 vUv;
    varying vec3 camPos;
    varying vec3 vNormal;
    varying vec3 nois;
    uniform sampler2D noise;
    uniform float time;

    void main() {
        vUv = uv;
        camPos = cameraPosition;
        vNormal = normal;
        vec3 pos = vec3(position.x/1.,position.y,position.z/1.);
        vec3 noisetex = texture2D(noise,mod(1.*vec2(vUv.y-time*2.,vUv.x + time*1.),1.)).rgb;
        if(pos.y >= 1.87){
            pos = vec3(position.x*(sin((position.y - 0.64)*1.27)-0.12),position.y,position.z*(sin((position.y - 0.64)*1.27)-0.12));
        } else{
            pos = vec3(position.x*(sin((position.y/2. -  .01)*.11)+0.79),position.y,position.z*(sin((position.y/2. -  .01)*.11)+0.79));
        }
        pos.xz *= noisetex.r;
        gl_Position = projectionMatrix * modelViewMatrix * vec4( pos, 1.0 );
    }
`;

  const fragflame = `
    varying vec2 vUv;
    uniform sampler2D perlinnoise;
    uniform sampler2D noise;
    uniform vec3 color4;
    uniform float time;
    varying vec3 camPos;
    varying vec3 vNormal;
    varying vec3 nois;

    vec3 rgbcol(vec3 col) {
        return vec3(col.r/255.0,col.g/255.0,col.b/255.0);
    }


    void main() {
        vec3 noisetex = texture2D(noise,mod(1.*vec2(vUv.y-time*2.,vUv.x + time*1.),1.)).rgb;
        gl_FragColor = vec4(noisetex.r);
        if(gl_FragColor.r >= 0.44){
            gl_FragColor = vec4(rgbcol(color4),gl_FragColor.r);
        }

        else{
            gl_FragColor = vec4(0.);
        }
        gl_FragColor *= vec4(smoothstep(0.2,0.628,vUv.y));

    }

`;

  let options = {
      
      
    exposure: 2.8,
    bloomStrength: 3.5,
    bloomRadius: 0.39,
    color0: [0, 0, 0],
    color1: [81, 14, 5],
    color2: [181, 156, 24],
    color3: [66, 66, 66],
    color4: [79, 79, 79],
    color5: [64, 27, 0] };

  let gui = new dat.GUI();
  let bloom = gui.addFolder("Bloom");
  bloom.add(options, "bloomStrength", 0.0, 5.0).name("bloomStrength").listen();
  bloom.add(options, "bloomRadius", 0.1, 2.0).name("bloomRadius").listen();
  bloom.open();

  let color = gui.addFolder("Colors");
  color.addColor(options, "color0").name("ball0");
  color.addColor(options, "color1").name("ball1");
  color.addColor(options, "color2").name("ball2");
  color.addColor(options, "color4").name("steam");
  color.addColor(options, "color5").name("trail");
  color.open();
  gui.close();

  let scene,
          camera,
          renderer,
          controls,
          material,
          material2,
          material3,
          bloomPass,
          bloomComposer,
          composer,
          finalPass,
          finalComposer;
  const width = window.innerWidth,
          height = window.innerHeight;

  function init() {
      
      
    createScene();
    postProc();
    mesh();
    flame();
    cylinder();
    animatBloom();
  }

  function createScene() {
      
      
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(
            75,
            window.innerWidth / window.innerHeight,
            0.1,
            1000);

    camera.position.set(3.4369982203815655, 3.5239085092722098, 2.994862383531814);
    renderer = new THREE.WebGLRenderer();
    renderer.antialias = true;
    renderer.setClearColor(new THREE.Color('#000'));
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(width, height);
    controls = new OrbitControls(camera, renderer.domElement);
    document.getElementById("world").appendChild(renderer.domElement);
  }

  function postProc() {
      
      
    const renderScene = new RenderPass(scene, camera);
    bloomPass = new UnrealBloomPass(
            new THREE.Vector2(window.innerWidth, window.innerHeight),
            1.5,
            0.4,
            0.85);

    bloomPass.threshold = options.bloomThreshold;
    bloomPass.strength = options.bloomStrength;
    bloomPass.radius = options.bloomRadius;

    bloomComposer = new EffectComposer(renderer);
    bloomComposer.addPass(renderScene);
    bloomComposer.addPass(bloomPass);
  }

  function mesh() {
      
      
    const geometry = new THREE.SphereBufferGeometry(1, 30, 30);
    material = new THREE.ShaderMaterial({
      
      
      uniforms: {
      
      
        time: {
      
      
          type: "f",
          value: 0.0 },

        perlinnoise: {
      
      
          type: "t",
          value: new THREE.TextureLoader().load(
                  "https://raw.githubusercontent.com/pizza3/asset/master/noise9.jpg") },


        sparknoise: {
      
      
          type: "t",
          value: new THREE.TextureLoader().load(
                  "https://raw.githubusercontent.com/pizza3/asset/master/sparklenoise.jpg") },


        color5: {
      
      
          value: new THREE.Vector3(...options.color5) },

        color4: {
      
      
          value: new THREE.Vector3(...options.color4) },

        color3: {
      
      
          value: new THREE.Vector3(...options.color3) },

        color2: {
      
      
          value: new THREE.Vector3(...options.color2) },

        color1: {
      
      
          value: new THREE.Vector3(...options.color1) },

        color0: {
      
      
          value: new THREE.Vector3(...options.color0) },

        resolution: {
      
       value: new THREE.Vector2(width, height) } },

      vertexShader: vert,
      fragmentShader: frag });


    const mesh = new THREE.Mesh(geometry, material);
    mesh.scale.set(0.78, 0.78, 0.78);
    mesh.position.set(1 + 0, 0, 0);
    scene.add(mesh);
  }

  function cylinder() {
      
      
    const geometry = new THREE.CylinderBufferGeometry(1.11, 0, 5.3, 50, 50, true);
    material2 = new THREE.ShaderMaterial({
      
      
      uniforms: {
      
      
        perlinnoise: {
      
      
          type: "t",
          value: new THREE.TextureLoader().load(
                  "https://raw.githubusercontent.com/pizza3/asset/master/water-min.jpg") },
        color4: {
      
      
          value: new THREE.Vector3(...options.color4) },

        time: {
      
      
          type: "f",
          value: 0.0 },

        noise: {
      
      
          type: "t",
          value: new THREE.TextureLoader().load(
                  "https://raw.githubusercontent.com/pizza3/asset/master/noise9.jpg") } },



      // wireframe:true,
      vertexShader: vertcylinder,
      fragmentShader: fragcylinder,
      transparent: true,
      depthWrite: false,
      side: THREE.DoubleSide });


    const mesh = new THREE.Mesh(geometry, material2);
    mesh.rotation.set(0, 0, -Math.PI / 2);
    mesh.position.set(1 + -4.05, 0, 0);
    mesh.scale.set(1.5, 1.7, 1.5);
    scene.add(mesh);
  }

  function flame() {
      
      
    const geometry = new THREE.CylinderBufferGeometry(1, 0, 5.3, 50, 50, true);
    material3 = new THREE.ShaderMaterial({
      
      
      uniforms: {
      
      
        perlinnoise: {
      
      
          type: "t",
          value: new THREE.TextureLoader().load(
                  "https://raw.githubusercontent.com/pizza3/asset/master/water-min.jpg") },

        color4: {
      
      
          value: new THREE.Vector3(...options.color5) },

        time: {
      
      
          type: "f",
          value: 0.0 },

        noise: {
      
      
          type: "t",
          value: new THREE.TextureLoader().load(
                  "https://raw.githubusercontent.com/pizza3/asset/master/noise9.jpg") } },

      // wireframe:true,
      vertexShader: vertflame,
      fragmentShader: fragflame,
      transparent: true,
      depthWrite: false,
      side: THREE.DoubleSide });


    const mesh = new THREE.Mesh(geometry, material3);
    mesh.rotation.set(0, 0, -Math.PI / 2);
    mesh.position.set(1 + -4.78, 0, 0);
    mesh.scale.set(2, 2, 2);
    scene.add(mesh);
  }

  function updateDraw(deltaTime) {
      
      
    material.uniforms.time.value = -deltaTime / (1000 * 2);
    material2.uniforms.time.value = -deltaTime / (3000 * 2);
    material3.uniforms.time.value = -deltaTime / (3000 * 2);
    material.uniforms.color5.value = new THREE.Vector3(...options.color5);
    material2.uniforms.color4.value = new THREE.Vector3(...options.color4);
    material3.uniforms.color4.value = new THREE.Vector3(...options.color5);
    material.uniforms.color3.value = new THREE.Vector3(...options.color3);
    material.uniforms.color2.value = new THREE.Vector3(...options.color2);
    material.uniforms.color1.value = new THREE.Vector3(...options.color1);
    material.uniforms.color0.value = new THREE.Vector3(...options.color0);
  }

  function animatBloom(deltaTime) {
      
      
    requestAnimationFrame(animatBloom);
    updateDraw(deltaTime);
    controls.update();
    bloomPass.strength = options.bloomStrength;
    bloomPass.radius = options.bloomRadius;
    bloomComposer.render();
  }

  function handleResize() {
      
      
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
  }

  window.addEventListener("load", init);
  window.addEventListener("resize", handleResize, false);
</script>
</html>

猜你喜欢

转载自blog.csdn.net/qq_35241329/article/details/130778769