【问题标题】:Shadertoy in THREE.jsTHREE.js 中的 Shadertoy
【发布时间】:2020-08-28 06:38:31
【问题描述】:

我目前正在尝试使用 THREE.js 将此着色器转换到画布上:https://www.shadertoy.com/view/4sjXRG。这是我正在使用的功能,它适用于更简单的着色器。我想我可能需要将花车保存为制服,但我有点迷失了这个。有没有人按照这些思路做了一些事情并且知道问题可能是什么?我一直在使用这个指南:https://threejsfundamentals.org/threejs/lessons/threejs-shadertoy.html

  const canvas = document.querySelector('#background');
  const renderer = new THREE.WebGLRenderer({canvas});
  renderer.autoClearColor = false;

  const camera = new THREE.OrthographicCamera(
    -1, // left
     1, // right
     1, // top
    -1, // bottom
    -1, // near,
     1, // far
  );
  const scene = new THREE.Scene();
  const plane = new THREE.PlaneBufferGeometry(2, 2);

  const fragmentShader = `
    #include <common>

    uniform vec3 iResolution;
    uniform float iTime;


float ltime;

float noise(vec2 p)
{
  return sin(p.x*10.) * sin(p.y*(3. + sin(ltime/11.))) + .2; 
}

mat2 rotate(float angle)
{
  return mat2(cos(angle), -sin(angle), sin(angle), cos(angle));
}


float fbm(vec2 p)
{
  p *= 1.1;
  float f = 0.;
  float amp = .5;
  for( int i = 0; i < 3; i++) {
    mat2 modify = rotate(ltime/50. * float(i*i));
    f += amp*noise(p);
    p = modify * p;
    p *= 2.;
    amp /= 2.2;
  }
  return f;
}

float pattern(vec2 p, out vec2 q, out vec2 r) {
  q = vec2( fbm(p + vec2(1.)),
        fbm(rotate(.1*ltime)*p + vec2(3.)));
  r = vec2( fbm(rotate(.2)*q + vec2(0.)),
        fbm(q + vec2(0.)));
  return fbm(p + 1.*r);

}

vec3 hsv2rgb(vec3 c)
{
    vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
    vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
    return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}

void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
  vec2 p = fragCoord.xy / iResolution.xy;
  ltime = iTime;
  float ctime = iTime + fbm(p/8.)*40.;
  float ftime = fract(ctime/6.);
  ltime = floor(ctime/6.) + (1.-cos(ftime*3.1415)/2.);
  ltime = ltime*6.;
  vec2 q;
  vec2 r;
  float f = pattern(p, q, r);
  vec3 col = hsv2rgb(vec3(q.x/10. + ltime/100. + .4, abs(r.y)*3. + .1, r.x + f));
  float vig = 1. - pow(4.*(p.x - .5)*(p.x - .5), 10.);
  vig *= 1. - pow(4.*(p.y - .5)*(p.y - .5), 10.);
  fragColor = vec4(col*vig,1.);
}


    void main() {
      mainImage(gl_FragColor, gl_FragCoord.xy);
      }
    `;

    const uniforms = {
      iTime: { value: 0 },
      iResolution:  { value: new THREE.Vector3() },
    };

  const material = new THREE.ShaderMaterial({
      fragmentShader,
      uniforms,
  });
  scene.add(new THREE.Mesh(plane, material));

  function resizeRendererToDisplaySize(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(time) {

    time *= 0.001; //convert to seconds

    resizeRendererToDisplaySize(renderer);

    const canvas = renderer.domElement;
    uniforms.iResolution.value.set(canvas.width, canvas.heigth, 1);
    uniforms.iTime.value = time;

    renderer.render(scene, camera);

    requestAnimationFrame(render);
  }

  requestAnimationFrame(render);
}

main();```


【问题讨论】:

    标签: javascript three.js glsl shader fragment-shader


    【解决方案1】:

    制服iResolution 设置不正确。这是一个简单的错字。 canvas.height 而不是canvas.heigth

    uniforms.iResolution.value.set(canvas.width, canvas.heigth, 1);

    uniforms.iResolution.value.set(canvas.width, canvas.height, 1);
    

    const fragmentShader = `
    #include <common>
    
    uniform vec3 iResolution;
    uniform float iTime;
    
    float ltime;
    
    float noise(vec2 p)
    {
      return sin(p.x*10.) * sin(p.y*(3. + sin(ltime/11.))) + .2; 
    }
    
    mat2 rotate(float angle)
    {
      return mat2(cos(angle), -sin(angle), sin(angle), cos(angle));
    }
    
    
    float fbm(vec2 p)
    {
      p *= 1.1;
      float f = 0.;
      float amp = .5;
      for( int i = 0; i < 3; i++) {
        mat2 modify = rotate(iTime/50. * float(i*i));
        f += amp*noise(p);
        p = modify * p;
        p *= 2.;
        amp /= 2.2;
      }
      return f;
    }
    
    float pattern(vec2 p, out vec2 q, out vec2 r) {
      q = vec2( fbm(p + vec2(1.)),
    	    fbm(rotate(.1*iTime)*p + vec2(3.)));
      r = vec2( fbm(rotate(.2)*q + vec2(0.)),
    	    fbm(q + vec2(0.)));
      return fbm(p + 1.*r);
    
    }
    
    vec3 hsv2rgb(vec3 c)
    {
        vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
        vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
        return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
    }
    
    void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
      vec2 p = fragCoord.xy / iResolution.xy;
      ltime = iTime;
      float ctime = iTime + fbm(p/8.)*40.;
      float ftime = fract(ctime/6.);
      ltime = floor(ctime/6.) + (1.-cos(ftime*3.1415)/2.);
      ltime = ltime*6.;
      vec2 q;
      vec2 r;
      float f = pattern(p, q, r);
      vec3 col = hsv2rgb(vec3(q.x/10. + ltime/100. + .4, abs(r.y)*3. + .1, r.x + f));
      float vig = 1. - pow(4.*(p.x - .5)*(p.x - .5), 10.);
      vig *= 1. - pow(4.*(p.y - .5)*(p.y - .5), 10.);
      fragColor = vec4(col*vig,1.);
    }
    
    void main() {
        mainImage(gl_FragColor, gl_FragCoord.xy);
    }
    `;
    
    function main() {
        const canvas = document.querySelector('#background');
        const renderer = new THREE.WebGLRenderer({canvas});
        renderer.autoClearColor = false;
    
        let camera = new THREE.OrthographicCamera(
           -1, // left
            1, // right
            1, // top
           -1, // bottom
           -1, // near,
            1, // far
        );
        camera.position.z = 1;
    
        const scene = new THREE.Scene();
        const plane = new THREE.PlaneBufferGeometry(2, 2);
    
        const uniforms = {
            iTime: { value: 0 },
            iResolution:  { value: new THREE.Vector3() },
        };
    
        const material = new THREE.ShaderMaterial({
            fragmentShader,
            uniforms,
        });
         scene.add(new THREE.Mesh(plane, material));
    
        function resizeRendererToDisplaySize(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(time) {
    
            time *= 0.001; //convert to seconds
    
            resizeRendererToDisplaySize(renderer);
    
            const canvas = renderer.domElement;
            uniforms.iResolution.value.set(canvas.width, canvas.height, 1);
            uniforms.iTime.value = time;
    
            renderer.render(scene, camera);
    
            requestAnimationFrame(render);
        }
    
        requestAnimationFrame(render);
    }
    
    main();
    #background{
    	background : black;
    	color : white;
      	margin: auto;
    	width : 500px;
    	height : 500px;
    }
    <script src="https://cdn.jsdelivr.net/npm/three@0.115/build/three.js"></script>
    <div><canvas id="background"></canvas></div>

    【讨论】:

      猜你喜欢
      • 2017-12-21
      • 1970-01-01
      • 2014-09-09
      • 1970-01-01
      • 1970-01-01
      • 2019-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多