着色器在Three.js应用程序中不起作用

时间:2014-07-25 14:11:31

标签: javascript three.js

我用Three.js写了一个程序。我尝试使用着色器,但不幸的是,该应用程序无法正常工作。我试图从threejs.org定制一个应用程序。这是代码:

 <html>
<head>
    <title>Test</title>
    <script type="text/javascript" src="ecma/three.js"></script>
    <script type="text/javascript" src="ecma/jquery-1.9.0.js"></script>
    <script type="text/javascript" src="ecma/OrbitControls.js"></script>        
    <style>
        body{ margin: 0; overflow: hidden; }
    </style>
</head>
<body>
    <div id="WebGL-output">
    </div>
    <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 id="fragment_shader1" type="x-shader/x-fragment">
        uniform vec2 resolution;
        uniform float time;
        varying vec2 vUv;

        void main(void)
        {
            vec2 p = -1.0 + 2.0 * vUv;
            float a = time*100.0;
            float d,e,f,g=1.0/40.0,h,i,r,q;

            e=400.0*(p.x*0.5+0.5);
            f=400.0*(p.y*0.5+0.5);
            i=200.0+sin(e*g+a/150.0)*20.0;
            d=200.0+cos(f*g/2.0)*18.0+cos(e*g)*7.0;
            r=sqrt(pow(i-e,2.0)+pow(d-f,2.0));
            q=f/r;
            e=(r*cos(q))-a/2.0;f=(r*sin(q))-cos(a/2.0);
            d=sin(e*g)*176.0+sin(e*g)*164.0+r;
            h=((f+d)+a/2.0)*g;
            i=cos(h+r*p.x/1.3)*(e+e+a)+cos(q*g*6.0)*(r+h/3.0);
            h=sin(f*g)*144.0-sin(e*g)*212.0*p.x;
            h=(h+(f-e)*q+sin(r-(a+h)/7.0)*10.0+i/4.0)*g;
            i+=cos(h*2.3*sin(a/350.0-q))*184.0*sin(q-(r*4.3+a/12.0)*g)+tan(r*g+h)*184.0*cos(r*g+h);
            i=mod(i/5.6,256.0)/64.0;
            if(i<0.0) i+=4.0;
            if(i>=2.0) i=4.0-i;
            d=r/350.0;
            d+=sin(d*d*8.0)*0.52;
            f=(sin(a*g)+1.0)/2.0;
            gl_FragColor=vec4(vec3(f*i/1.6,i/2.0+d/13.0,i)*d*p.x+vec3(i/1.3+d/8.0,i/2.0+d/18.0,i)*d*(1.0-p.x),0.0);
        }
    </script>       

    <script type="text/javascript">
        $(function () {
            var W = window.innerWidth, H = window.innerHeight;
            var plane, planeGeom, planeMat;
            var sphere, sphereGeom, shadedMat;
            var scene, camera, renderer;
            var clock;
            var orbitControls;
            var uniforms1;

            init();     
            makeLights();
            makeFloor();
            makeSphere();
            render();

            function init(){
                scene = new THREE.Scene();
                camera = new THREE.PerspectiveCamera(45, W / H, 0.1, 1000);
                camera.position.set(-40, 30, 0);
                camera.lookAt(new THREE.Vector3(0,0,0));
                renderer = new THREE.WebGLRenderer();
                renderer.setClearColorHex(0xEEEEEE);
                renderer.setSize(W, H);
                renderer.shadowMapEnabled = true;
                orbitControls = new THREE.OrbitControls(camera);
                orbitControls.autoRotate = false;
                clock = new THREE.Clock();                  
            }

            function makeLights(){
                makeAmbientLight();
                makeSpotLight();
            }

            function makeAmbientLight(){
                ambiColor = 0x141414;
                ambientLight = new THREE.AmbientLight(ambiColor);
                scene.add(ambientLight);
            }

            function makeSpotLight(){
                var spotLight = new THREE.SpotLight( 0xffffff );
                spotLight.position.set( -40, 60, -10 );
                spotLight.castShadow = true;
                scene.add( spotLight );
            }

            function makeFloor(){
                planeGeom = new THREE.PlaneGeometry(100,100);
                planeMat = new THREE.MeshLambertMaterial();
                var planeTex = THREE.ImageUtils.loadTexture("picim/checkerboard.jpg");
                planeTex.wrapS = planeTex.wrapT = THREE.RepeatWrapping;
                planeTex.repeat.set(50, 50);
                planeMat.map = planeTex;
                planeMat.side = THREE.DoubleSide;
                plane = new THREE.Mesh(planeGeom, planeMat);
                plane.rotation.x=-0.5*Math.PI;
                plane.position.set(15, 0, 0);
                plane.receiveShadow = true;
                scene.add(plane);
            }

            function makeSphere(){
                sphereGeom = new THREE.SphereGeometry(5,20,20);

                uniforms1 = {
                    time: { type: "f", value: 1.0 },
                    resolution: { type: "v2", value: new THREE.Vector2() }
                };
                shadedMat = new THREE.ShaderMaterial({uniforms: uniforms1, 
                                                      vertexShader: document.getElementById('vertexShader').textContent,
                                                      fragmentShader: document.getElementById('fragment_shader1').textContent,
                                                     });
                sphere = new THREE.Mesh(sphereGeom, shadedMat);
                sphere.position.set(0, 10, 0);
                sphere.castShadow = true;
                scene.add(sphere);
            }

            function render(){
                var delta = clock.getDelta();
                orbitControls.update(delta);                    
                sphere.rotation.y += 0.02;
                requestAnimationFrame(render);
                renderer.render(scene, camera);
            }

            $("#WebGL-output").append(renderer.domElement);
        });
    </script>
</body>
</html>

应用必须显示使用着色器的地板和球体。但该应用程序显示一个明亮的白色球体。你能帮我找到错误吗?

谢谢,

的Ee

1 个答案:

答案 0 :(得分:0)

如果您看到带有这些疯狂着色器的白色球体,那么这意味着着色器不起作用?

如果你问为什么那个...着色器(并且它是一个非常着色器)渲染白色,而不是所有的数学,那么任何人都可以帮助你使用所提供的代码是值得怀疑的。

你可以添加像gl_FragColor.xyz = cos(gl_FragColor.xyz)*。5 + .5;你会看到那个白色是否真的有更大的意义。