在webgl / three.js中设置自定义着色器的动画

时间:2016-05-23 18:27:13

标签: three.js webgl

我目前正在学习OpenGL,偶然发现了这个教程: http://patriciogonzalezvivo.com/2015/thebookofshaders/03/

我试图在webgl中使用snipped来进一步理解机制,但不知何故它不起作用,老实说我不确定为什么。我确信必定会有一些语法错误,但它可能是什么?如果没有,那么我该如何做到这一点?

说实话,我试图了解如何实现u_time。我认为GPU自动有一个内置的计时器,它会导致颜色过渡动画。

    Route::get('guest/shop/{product?}', 'GuestShopController@show')->name('guest.shop.show');

public function show($product = null)
{

}
// set the scene size
var WIDTH = 400,
    HEIGHT = 300;

// set some camera attributes
var VIEW_ANGLE = 45,
    ASPECT = WIDTH / HEIGHT,
    NEAR = 0.1,
    FAR = 10000;

// get the DOM element to attach to
// - assume we've got jQuery to hand
var $container = $('#container');

// create a WebGL renderer, camera
// and a scene
var renderer = new THREE.WebGLRenderer();
var camera = new THREE.Camera(  VIEW_ANGLE,
                              ASPECT,
                              NEAR,
                              FAR  );
var scene = new THREE.Scene();

// the camera starts at 0,0,0 so pull it back
camera.position.z = 300;

// start the renderer
renderer.setSize(WIDTH, HEIGHT);

// attach the render-supplied DOM element
$container.append(renderer.domElement);

// create the sphere's material
var shaderMaterial = new THREE.MeshShaderMaterial({
  vertexShader:   $('#vertexshader').text(),
  fragmentShader: $('#fragmentshader').text()
});

// set up the sphere vars
var radius = 50, segments = 16, rings = 16;

// create a new mesh with sphere geometry -
// we will cover the sphereMaterial next!
var sphere = new THREE.Mesh(
  new THREE.Sphere(radius, segments, rings),
  shaderMaterial);

// add the sphere to the scene
scene.addChild(sphere);

// draw!
renderer.render(scene, camera);

1 个答案:

答案 0 :(得分:3)

你是对的,你需要绑定/更新javascript中的值。要做到这一点,你需要做两件事:

  1. 在创建着色器材质时声明着色器中的u_time制服(包括type和初始value)。

    var shaderMaterial = new THREE.MeshShaderMaterial({
      uniforms: { // <- This is an object with your uniforms as keys
        u_time: { type: "f", value: 0 }
      },
      vertexShader:   $('#vertexshader').text(),
      fragmentShader: $('#fragmentshader').text()
    });
    
  2. 您需要有一个渲染循环,您可以不断更新制服的value。这是一个渲染循环的基本示例,一旦浏览器准备好渲染另一个帧,它就会使用requestAnimationFrame()来调用自身:

    function draw () {
      requestAnimationFrame(draw);
    
      // Update shader's time
      sphere.materials[0].uniforms.u_time.value += 0.01;
    
      // draw!
      renderer.render(scene, camera);
    }
    
    draw();
    

    请注意,您更新uniforms.u_time.value而不是uniforms.u_time。这是因为制服同时包含type和当前value

  3. Working jsFiddle with changes

    还知道你在小提琴中使用的是旧版本的three.js。版本r40是2011年,我们目前达到r76。最近的版本中有一些细节可以使这更简单。