2016-05-23 175 views
-1

目前我正在学习的OpenGL和整个本教程中偶然发现: http://patriciogonzalezvivo.com/2015/thebookofshaders/03/动画自定义着色器/ three.js所

我试图使用的WebGL的剪断,以便进一步了解机制,但不知何故,它不工作,我老实说不知道为什么。我相信肯定会有一些语法错误,但它会是什么?如果没有,那我该如何做这项工作?

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

// 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);
<div id="container"></div> 
 

 
<script type="x-shader/x-vertex" id="vertexshader"> 
 
// switch on high precision floats 
 
#ifdef GL_ES 
 
precision highp float; 
 
#endif 
 

 
void main() 
 
{ 
 
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0); 
 
} 
 
</script> 
 

 
<script type="x-shader/x-fragment" id="fragmentshader"> 
 

 
uniform float u_time; 
 

 
void main() { 
 
    gl_FragColor = vec4(sin(u_time),0.0,0.0,1.0); 
 
} 
 

 
</script> 
 
<script src="https://aerotwist.com/static/tutorials/an-introduction-to-shaders-part-1/demo/js/Three.js"></script> 
 
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>

+0

你在哪里声明了projectionMatrix,modelViewMatrix和position?投影矩阵和modelViewMatrix应声明为制服;位置作为属性,加上你应该将它们发送到GPU。 如果这不是你的问题,那么你应该澄清什么是不工作,我猜。 – Zouch

+0

顺便说一句,我不知道THREE.js,但我没有看到你发送u_time制服的位置。 – Zouch

+0

@Zouch我在学习本教程。我想我必须以某种方式绑定JavaScript代码中的u_time。创建某种计时器。 – Asperger

回答

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()调用自身一旦浏览器是准备渲染另一帧渲染循环的一个基本的例子:您更新uniforms.u_time.valueuniforms.u_time

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

    注意。这是因为制服持有type和现在的value

Working jsFiddle with changes

也知道你在你的提琴使用非常古老的版本three.js所的。 r40版本是从2011年开始的,目前我们已经达到r76。最近版本中有一些细节使得这个更简单。

相关问题