three.js毛皮 - 没有装任何东西

时间:2017-02-09 16:57:48

标签: javascript html three.js

我正在尝试理解并致力于在three.js中实现毛发,我在http://oos.moxiecode.com/js_webgl/fur/找到了示例。我试图这样做,作为一个例子来了解并理解代码。

模型加载,但现在问题是毛皮纹理没有加载,我添加了控制台上出现的错误,这些错误都链接到three.min.js。我已经加载了演示中使用的three.min.js r58版本和我当前的版本,错误/警告不会随着我使用的任何一个而改变。

这是模型,它加载但没有毛发纹理加载:

this is model, it loads but no fur texture loads on it

代码:

<!doctype html>
<html lang="en">
    <head>
        <title>three.js fur example 1</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <link rel="stylesheet" type="text/css" href="style_no_stats.css">
        <style type="text/css">
            body {
                background:#000000;
            }
        </style>
    </head>

    <body>

        <script src="three.min.js"></script>

        <script src="info.js"></script>

        <script type="x-shader/x-vertex" id="vertexshader">

            uniform float offset;
            uniform float globalTime;
            uniform vec3 gravity;

            varying vec2 vUv;
            varying vec3 vNormal;

            const float spacing = 12.0;

            void main()
            {
                vec3 displacement = vec3(0.0,0.0,0.0);
                vec3 forceDirection = vec3(0.0,0.0,0.0);

                // "wind"
                forceDirection.x = sin(globalTime+position.x*0.05) * 0.2;
                forceDirection.y = cos(globalTime*0.7+position.y*0.04) * 0.2;
                forceDirection.z = sin(globalTime*0.7+position.y*0.04) * 0.2;

                // "gravity"
                displacement = gravity + forceDirection;

                float displacementFactor = pow(offset, 3.0);

                vec3 aNormal = normal;
                aNormal.xyz += displacement*displacementFactor;

                // move outwards depending on offset(layer) and normal+force+gravity
                vec3 animated = vec3( position.x, position.y, position.z )+(normalize(aNormal)*offset*spacing);

                vNormal = normalize(normal*aNormal);

                vUv = uv*20.0;

                vec4 mvPosition = modelViewMatrix * vec4( animated, 1.0 );

                gl_Position = projectionMatrix * mvPosition;
            }

        </script>

        <script type="x-shader/x-fragment" id="fragmentshader">
            uniform sampler2D hairMap;
            uniform sampler2D colorMap;
            uniform vec3 color;
            uniform float offset;

            varying vec3 vNormal;

            varying vec2 vUv;

            void main() 
            {
                vec4 hairColor = texture2D(hairMap, vec2(vUv.s, vUv.t));
                vec4 col = texture2D(colorMap, vec2(vUv.s*0.2, vUv.t*0.2));

                // discard no hairs + above the max length
                if (hairColor.a <= 0.0 || hairColor.g < offset) {
                    discard;
                }

                // darker towards bottom of the hair
                float shadow = mix(0.0,hairColor.b*1.2,offset);

                // light
                vec3 light = vec3(0.1,1.0,0.3);
                float d = pow(max(0.25,dot(vNormal.xyz, light))*2.75, 1.4);

                gl_FragColor = vec4(color*col.xyz*d*shadow, 1.1-offset);    
            }

        </script>


        <script>

            var container;

            var camera, scene, renderer;

            var has_gl = false;

            var delta;
            var time;
            var oldTime;

            var shaderTime = 0;
            var meshes = [];

            var overlay;

            var texture;
            var color;
            var vignette;

            var mouse = new THREE.Vector2(-0.5,0.5);
            var gravity = new THREE.Vector3(0,-0.75,0);
            var mouseObj = {x:0, y: 0, vx: 0, vy:0};

            var touchDevice = ( ('ontouchstart' in document) || (navigator.userAgent.match(/ipad|iphone|android/i) != null) );
            var scaleRatio = 1;
            if (touchDevice) scaleRatio = 2;

            document.addEventListener( 'mousemove', onMouseMove, false );
            document.addEventListener( 'touchmove', onTouchMove, false );

            var loadedItems = 0;

            function checkLoading () {

                ++loadedItems;

                if (loadedItems < 3) return;

                animate();
            }

            init();

            function init() 
            {
                container = document.createElement( 'div' );
                document.body.appendChild( container );

                scene = new THREE.Scene();

                camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
                camera.position.z = 150;
                camera.lookAt(scene.position);
                scene.add( camera );

                // diffuse color
                color = THREE.ImageUtils.loadTexture( "11133-v4.jpg", undefined, checkLoading);
                color.wrapS = color.wrapT = THREE.RepeatWrapping;

                // hair texture
                texture = new THREE.Texture( generateTexture() );
                texture.needsUpdate = true;
                texture.wrapS = texture.wrapT = THREE.RepeatWrapping;

                vignette = THREE.ImageUtils.loadTexture( "VignetteWithDirt_alpha_sq.png", undefined, checkLoading);

                // model
                loader = new THREE.JSONLoader();
                loader.load( "suzanne.js", meshLoaded );

                var overlayMaterial = new THREE.SpriteMaterial( { map: vignette, useScreenCoordinates: true, opacity: 0.4 } );
                overlay = new THREE.Sprite( overlayMaterial );
                overlay.scale.set( window.innerWidth/scaleRatio, window.innerHeight/scaleRatio , 1 );
                overlay.position.set((window.innerWidth/scaleRatio)/2, (window.innerHeight/scaleRatio)/2 , 0);
                camera.add(overlay);

                try 
                {
                    // renderer
                    renderer = new THREE.WebGLRenderer({antialias: false});
                    renderer.setSize( window.innerWidth/scaleRatio, window.innerHeight/scaleRatio );
                    renderer.setClearColor(0x444444);

                    texture.anisotropy = renderer.getMaxAnisotropy();

                    if (scaleRatio > 1) 
                    {
                        renderer.domElement.style.position = "absolute";
                        renderer.domElement.style.top = "0px";
                        renderer.domElement.style.left = "0px";

                        renderer.domElement.style.webkitTransform = "scale3d("+scaleRatio+", "+scaleRatio+", 1)";
                        renderer.domElement.style.webkitTransformOrigin = "0 0 0";
                        renderer.domElement.style.transform = "scale3d("+scaleRatio+", "+scaleRatio+", 1)";
                        renderer.domElement.style.transformOrigin = "0 0 0";                
                    }

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

                    container.appendChild( renderer.domElement );
                    container.style.cursor = "url(cursor.png),pointer";

                    has_gl = true;
                }
                catch (e)
                {
                    // need webgl
                    document.getElementById('info').innerHTML = "<P><BR><B>Note.</B> You need a modern browser that supports WebGL for this to run the way it is intended.<BR>For example. <a href='http://www.google.com/landing/chrome/beta/' target='_blank'>Google Chrome 9+</a> or <a href='http://www.mozilla.com/firefox/beta/' target='_blank'>Firefox 4+</a>.<BR><BR>If you are already using one of those browsers and still see this message, it's possible that you<BR>have old blacklisted GPU drivers. Try updating the drivers for your graphic card.<BR>Or try to set a '--ignore-gpu-blacklist' switch for the browser.</P><CENTER><BR><img src='../general/WebGL_logo.png' border='0'></CENTER>";
                    document.getElementById('info').style.display = "block";
                    return;
                }
            }

            function onWindowResize ( event ) 
            {
                var w = window.innerWidth;
                var h = window.innerHeight;

                renderer.setSize( w/scaleRatio, h/scaleRatio );

                camera.aspect = w / h;
                camera.updateProjectionMatrix();

                if (overlay) 
                {
                    overlay.scale.set( w/scaleRatio, h/scaleRatio, 1 );
                    overlay.position.set((w/scaleRatio)/2, (h/scaleRatio)/2 , 0);
                }
            }

            function onMouseMove ( event ) 
            {
                event.preventDefault();

                mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
                mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
            }

            function onTouchMove ( event ) 
            {
                event.preventDefault();

                mouse.x = ( event.touches[0].clientX / window.innerWidth ) * 2 - 1;
                mouse.y = - ( event.touches[0].clientY / window.innerHeight ) * 2 + 1;
            }

            function meshLoaded( geometry ) 
            {
                // scale it up
                var size = 60;
                geometry.applyMatrix( new THREE.Matrix4().scale( new THREE.Vector3( size, size, size ) ) );

                // number of "shells" / layers
                var shells = 60;
                if (touchDevice) shells = 45;

                for (var i = 0; i < shells; i++) 
                {
                    var attributes = {};

                    var uniforms = 
                    {
                        color:      { type: "c", value: new THREE.Color( 0xffffff ) },
                        hairMap:    { type: "t", value: texture },
                        colorMap:    { type: "t", value: color },
                        offset: { type: "f", value: i/shells },
                        globalTime: { type: "f", value: shaderTime },
                        gravity:    { type: "v3", value: gravity },
                    };
                    var material = new THREE.ShaderMaterial( 
                    {
                        uniforms:       uniforms,
                        attributes:     attributes,
                        vertexShader:   document.getElementById( "vertexshader" ).textContent,
                        fragmentShader: document.getElementById( "fragmentshader" ).textContent,

                        transparent: true,
                    });

                    var mesh =  new THREE.Mesh(geometry, material);
                    mesh.matrixAutoUpdate = false;
                    mesh.frustumCulled = false;
                    scene.add(mesh);
                    meshes.push(mesh);
                }
                checkLoading();
            }

            function generateTexture()
            {
                var canvas = document.createElement( 'canvas' );
                canvas.width = 256;
                canvas.height = 256;

                var context = canvas.getContext( '2d' );

                for ( var i = 0; i < 20000; ++i ) {
                    // r = hair 1/0
                    // g = length
                    // b = darkness
                    context.fillStyle = "rgba(255," + Math.floor( Math.random() * 255 ) + ","+ Math.floor( Math.random() * 255 ) +",1)";

                    context.fillRect( ( Math.random() * canvas.width ), ( Math.random() * canvas.height ), 2, 2 );          
                }
                return canvas;
            }

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

            function render()
            {
                time = Date.now();
                delta = time - oldTime;
                oldTime = time;
                if (isNaN(delta) || delta > 1000 || delta == 0 )
                {
                    delta = 1000/60;
                }
                var optimalDivider = delta/16;
                var smoothing = Math.max(4, (20/optimalDivider) )

                // fake some gravity according to mouse movement
                var xf = (mouse.x - mouseObj.x)/(smoothing*5);
                var yf = (mouse.y - mouseObj.y)/(smoothing*5);
                mouseObj.vx += xf
                mouseObj.vy += yf;
                mouseObj.vx *= 0.96;
                mouseObj.vy *= 0.94;
                mouseObj.x += mouseObj.vx;
                mouseObj.y += mouseObj.vy;

                gravity.x = -(mouse.x-mouseObj.x)*2;

                var dif = Math.sin(mouse.x)*150 - camera.position.x;
                gravity.y = -0.75 + (Math.abs(dif)/150) - (mouse.y-mouseObj.y)*2;

                camera.position.x += (Math.sin(mouse.x)*150 - camera.position.x)/smoothing;
                camera.position.z += (Math.cos(mouse.x)*150 - camera.position.z)/smoothing;
                camera.position.y += (Math.sin(mouse.y)*150 - camera.position.y)/smoothing;

                camera.lookAt(scene.position);

                shaderTime += delta*0.005;

                for (var i = 0; i < meshes.length; i++) 
                {
                    meshes[i].material.uniforms.globalTime.value = shaderTime;
                }

                if (has_gl) {
                    renderer.render( scene, camera );
                }
            }
        </script>
    </body>
</html>

控制台中的错误是:

three.min.js:835 THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.

loadTexture @ three.min.js:835
three.min.js:419 THREE.SpriteMaterial: 'useScreenCoordinates' is not a property of this material.

setValues @ three.min.js:419
three.min.js:32 THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.

setValues @ three.min.js:419
three.min.js:32 THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.

由于我复制的代码不确定我做错了什么,我有所有.png和.jpg文件,我在本地服务器上有所有的javascript文件。

1 个答案:

答案 0 :(得分:1)

这听起来像你使用的是当前的three.js版本(r82),而这个例子使用的是版本r58(现在已经很老了)。你可能应该从较早的three.js版本开始(从herehere开始)并在你弄清楚究竟发生了什么后进行迁移。