2015-05-04 330 views
3

過去幾周我一直在用three.js庫&着色器進行實驗,並且在我的模型上實現了着色器。我在pixelsjders.com上發現了一個我想在threejs模型上實現的有趣例子。Threejs着色器的實現

http://pixelshaders.com/examples/noise.html

這是在頁面底部的最後一個例子,我試圖實現。

我試圖將它添加到可以在下面的鏈接中找到的3D模型:

http://martinr.nl/lab/Speeltuin/webgl_shader2.html

的辛苦的事情是,當我添加3D模型消失的例子的代碼。這使得調試和查找錯誤非常困難。

這是着色器代碼的作品,但不是用正確的着色器:

<script id="fragmentShader" type="x-shader/x-fragment"> 
 
    varying vec2 vUv; 
 

 
    uniform float time; 
 
    uniform vec2 resolution; 
 
    precision mediump float; 
 

 
    void main(void) { 
 

 
     vec2 position = 2.0 + 2.0 * vUv; 
 

 
     float red = abs(sin(position.x/position.y + time/5.0)); 
 
     float green = abs(sin(position.x/position.y + time/4.0)); 
 
     float blue = abs(sin(position.x/position.y + time/3.0)); 
 
     gl_FragColor = vec4(red, green, blue, 1.0); 
 
    } 
 

 
</script> 
 

 
<script id="vertexShader" type="x-shader/x-vertex"> 
 
varying vec2 vUv; 
 

 
    void main() 
 
    { 
 
     vUv = uv; 
 
     vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); 
 
     gl_Position = projectionMatrix * mvPosition; 
 
    } 
 

 
</script>

當我嘗試實施上述示例中的3D模型消失的着色器。

有沒有人知道如何在我的示例中將pixelshader.com示例的着色器實現到模型中?

還是沒有人有任何提示,我可以嘗試使其工作?

+0

添加[shaderMaterial](http://threejs.org/docs/#Reference /材料/ ShaderMaterial)在three.js中添加着色器代碼從這個材質的例子,它應該工作([例子](http://threejs.org/examples/webgl_shader2.html)) –

+0

oops剛剛看到你使用ShaderMaterial –

+0

的類似示例着色器接受'time'參數是否將此參數傳遞給着色器?也許這是問題,這些示例使用glsl.js而不是三個.js,但它應該可以正常工作,只需確保將所有必需的參數傳遞給着色器 –

回答

1

我用pixelshaders.com代碼替換了你的片段着色器。控制檯報告以下錯誤:

> THREE.WebGLProgram: shader error: 0 gl.VALIDATE_STATUS false 
> gl.getPRogramInfoLog Varyings with the same name but different type, 
> or statically used varyings in fragment shader are not declared in 
> vertex shader: position 

變量變量本質上是頂點着色器和片段着色器之間的接口。此錯誤告訴我們position在片段着色器中聲明,但不在頂點着色器中聲明。

實際上,您的頂點着色器中已經有了所需的變量,除了它被命名爲vUv。我所要做的就是使變量名一致。

noise shader

完整源(I在render()函數把縮放關閉time太):

<!DOCTYPE html> 
<html lang="en"> 
    <head> 
     <title>three.js webgl - materials - shaders [custom]</title> 
     <meta charset="utf-8"> 
     <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> 
     <style> 
      body { 
       color: #ffffff; 
       font-family:Monospace; 
       font-size:13px; 
       text-align:center; 
       font-weight: bold; 

       background-color: #050505; 
       margin: 0px; 
       overflow: hidden; 
      } 
      a { 
       color: #ffffff; 
      } 
      #oldie a { color:#da0 } 
     </style> 
    </head> 
    <body> 

     <div id="container"></div> 
     <div id="info"><a href="http://threejs.org" target="_blank">three.js</a> - shader material demo. featuring <a href="http://www.pouet.net/prod.php?which=52761" target="_blank">Monjori by Mic</a></div> 


    <link rel="stylesheet" href="css/skeleton.css"> 
    <link rel="stylesheet" href="css/normalize.css"> 
    <link rel="stylesheet" href="css/style.css"> 
    <link rel="stylesheet" href="css/codemirror.css"> 
    <script src="js/lib/three.min.js"></script> 
    <script src="js/lib/Detector.js"></script> 
    <script src="js/geo.js"></script> 

     <script id="fragmentShader" type="x-shader/x-fragment"> 
      precision mediump float; 

      varying vec2 vUv; 
      uniform float time; 

      float random(float p) { 
       return fract(sin(p)*10000.); 
      } 

      float noise(vec2 p) { 
       return random(p.x + p.y*10000.); 
      } 

      vec2 sw(vec2 p) {return vec2(floor(p.x) , floor(p.y));} 
      vec2 se(vec2 p) {return vec2(ceil(p.x) , floor(p.y));} 
      vec2 nw(vec2 p) {return vec2(floor(p.x) , ceil(p.y) );} 
      vec2 ne(vec2 p) {return vec2(ceil(p.x) , ceil(p.y) );} 

      float smoothNoise(vec2 p) { 
       vec2 inter = smoothstep(0., 1., fract(p)); 
       float s = mix(noise(sw(p)), noise(se(p)), inter.x); 
       float n = mix(noise(nw(p)), noise(ne(p)), inter.x); 
       return mix(s, n, inter.y); 
       return noise(nw(p)); 
      } 

      float movingNoise(vec2 p) { 
       float total = 0.0; 
       total += smoothNoise(p  - time); 
       total += smoothNoise(p*2. + time)/2.; 
       total += smoothNoise(p*4. - time)/4.; 
       total += smoothNoise(p*8. + time)/8.; 
       total += smoothNoise(p*16. - time)/16.; 
       total /= 1. + 1./2. + 1./4. + 1./8. + 1./16.; 
       return total; 
      } 

      float nestedNoise(vec2 p) { 
       float x = movingNoise(p); 
       float y = movingNoise(p + 100.); 
       return movingNoise(p + vec2(x, y)); 
      } 

      void main() { 
       vec2 p = vUv * 6.; 
       float brightness = nestedNoise(p); 
       gl_FragColor.rgb = vec3(brightness); 
       gl_FragColor.a = 1.; 
      } 

     </script> 



     <script id="vertexShader" type="x-shader/x-vertex"> 
     varying vec2 vUv; 

      void main() 
      { 
       vUv = uv; 
       vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); 
       gl_Position = projectionMatrix * mvPosition; 
      } 

     </script> 

     <script> 

      if (! Detector.webgl) Detector.addGetWebGLMessage(); 

      var container; 
      var camera, controls, scene, renderer; 
      var uniforms; 
      var clock = new THREE.Clock(); 

      init(); 
      animate(); 

      function init() { 

       container = document.getElementById('container'); 

       camera = new THREE.PerspectiveCamera(40, window.innerWidth/window.innerHeight, 1, 3000); 
       camera.position.z = 2; 

       scene = new THREE.Scene(); 

       var geometry = new THREE.BoxGeometry(0.5, 0.5, 0.5); 

       uniforms = { 
        time: { type: "f", value: 1.0 }, 
        resolution: { type: "v2", value: new THREE.Vector3() } 
       };    

       var material = new THREE.ShaderMaterial({ 
        uniforms: uniforms, 
        vertexShader: document.getElementById('vertexShader').textContent, 
        fragmentShader: document.getElementById('fragmentShader').textContent 
       }); 

       var mesh = new THREE.Mesh(geometry, material); 
       scene.add(mesh); 


       renderer = new THREE.WebGLRenderer(); 
       renderer.setPixelRatio(window.devicePixelRatio); 
       container.appendChild(renderer.domElement); 


       onWindowResize(); 

       window.addEventListener('resize', onWindowResize, false); 

      } 

      function onWindowResize(event) { 

       uniforms.resolution.value.x = window.innerWidth; 
       uniforms.resolution.value.y = window.innerHeight; 

       camera.aspect = window.innerWidth/window.innerHeight; 
       camera.updateProjectionMatrix(); 

       renderer.setSize(window.innerWidth, window.innerHeight); 

      } 

      // 

      function animate() { 
       requestAnimationFrame(animate); 
       render(); 
      } 

      function render() { 

       var delta = clock.getDelta(); 

       uniforms.time.value += delta; 

//    for (var i = 0; i < scene.children.length; i ++) { 
// 
//     var object = scene.children[ i ]; 
// 
//     object.rotation.y += delta * 0.5 * (i % 2 ? 1 : -1); 
//     object.rotation.x += delta * 0.5 * (i % 2 ? -1 : 1); 
// 
//    } 

       renderer.render(scene, camera); 

      } 

     </script> 

    </body> 
</html>