通过ShaderMaterial访问变形目标

时间:2017-11-06 11:55:47

标签: javascript three.js morphing

我在example中使用此threejs并将带有变形目标的人体对象加载到其中。

但我在使用ShaderMaterial时遇到通过网络应用程序访问该问题的问题。虽然ShaderMaterial具有morphTarget属性,但morphTarget: true;无效。

这是我的代码。

<body>
    <div id="info">

    </div>

    <script src="js/three.js"></script>
    <script src="js/ShaderSkin.js"></script>
    <script src="js/CopyShader.js"></script>
    <script src="js/EffectComposer.js"></script>
    <script src="js/RenderPass.js"></script>
    <script src="js/ShaderPass.js"></script>
    <script src="js/MaskPass.js"></script>
    <script src="js/Detector.js"></script>
    <script src="js/stats.min.js"></script>
    <script src="js/AssimpJSONLoader.js"></script>
    <script src="js/dat.gui.min.js"></script>
    <script src="js/OrbitControls.js"></script>

    <script>

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

        var statsEnabled = true;
        var container, stats, loader;
        var camera, scene, renderer;
        var mesh, mesh2, gui;
        var directionalLight;
        var mouseX = 0;
        var mouseY = 0;
        var targetX = 0, targetY = 0;
        var character,object;
        var windowHalfX = window.innerWidth / 2;
        var windowHalfY = window.innerHeight / 2;
        var mapColor, mapHeight, mapSpecular;
        var firstPass = true;
        var composer, composerBeckmann;
        var controls;

        init();
        animate();

        function init() {

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

            //
            camera = new THREE.PerspectiveCamera( 27, window.innerWidth / window.innerHeight, 1, 10000 );
            camera.position.z = 600;
            camera.position.y = -20;

            scene = new THREE.Scene();
            scene.background = new THREE.Color( 0xffffff );

            // LIGHTS
            scene.add( new THREE.AmbientLight( 0x333344 ) );

            directionalLight = new THREE.DirectionalLight( 0xffffff, 1 );
            directionalLight.position.set( 500, 0, 500 );

            directionalLight.castShadow = true;

            directionalLight.shadow.mapSize.width = 2048;
            directionalLight.shadow.mapSize.height = 2048;

            directionalLight.shadow.camera.near = 200;
            directionalLight.shadow.camera.far = 1500;

            directionalLight.shadow.camera.left = -500;
            directionalLight.shadow.camera.right = 500;
            directionalLight.shadow.camera.top = 500;
            directionalLight.shadow.camera.bottom = -500;

            directionalLight.shadow.bias = -0.005;

            scene.add( directionalLight );

            //access morph targets
            gui = new dat.GUI();

            var params = {  
                Height: 0       
            };

            var folder = gui.addFolder( 'Morph Targets' );
            folder.add( params, 'Height', 0.0, 1.0 ).step( 0.01 ).onChange( function( value ) { object.morphTargetInfluences[ 1 ] = value; } );
            folder.open();

            // load the object
            loader = new THREE.JSONLoader();
            loader.load( 'leeperrysmith/MorphMan1.json', function ( geometry ) {
            object = new THREE.Mesh( geometry );
            createScene( geometry , 120)

            } );

            //
            renderer = new THREE.WebGLRenderer( { antialias: true } );
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( window.innerWidth, window.innerHeight );
            container.appendChild( renderer.domElement );

            renderer.shadowMap.enabled = true;
            renderer.shadowMap.renderReverseSided = false;

            renderer.autoClear = false;

            //
            renderer.gammaInput = true;
            renderer.gammaOutput = true;

            //
            if ( statsEnabled ) {
                stats = new Stats();
                container.appendChild( stats.dom );
            }

            // COMPOSER
            renderer.autoClear = false;

            // BECKMANN
            var effectBeckmann = new THREE.ShaderPass( THREE.ShaderSkin[ "beckmann" ] );
            var effectCopy = new THREE.ShaderPass( THREE.CopyShader );

            effectCopy.renderToScreen = true;

            var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };
            var rtwidth = 512, rtheight = 512;

            composerBeckmann = new THREE.EffectComposer( renderer, new THREE.WebGLRenderTarget( rtwidth, rtheight, pars ) );
            composerBeckmann.addPass( effectBeckmann );
            composerBeckmann.addPass( effectCopy );

            // EVENTS
            //document.addEventListener( 'mousemove', onDocumentMouseMove, true);
            window.addEventListener( 'resize', onWindowResize, true );


            controls = new THREE.OrbitControls( camera, renderer.domElement );
            controls.addEventListener( 'change', render ); // remove when using animation loop
            controls.enableZoom = true;
        }

        function createScene( geometry, scale ) {

            var textureLoader = new THREE.TextureLoader();

            // bump Map
            var mapHeight = textureLoader.load( "leeperrysmith/3d_skin_texture_bump_map_by_degrahuma_stock.jpg" );

            mapHeight.anisotropy = 4;
            mapHeight.wrapS = mapHeight.wrapT = THREE.RepeatWrapping;
            mapHeight.format = THREE.RGBFormat;


            var mapSpecular = textureLoader.load( "leeperrysmith/3d_skin_texture_bump_map_by_degrahuma_stock.jpg" );

            mapSpecular.anisotropy = 4;
            mapSpecular.wrapS = mapSpecular.wrapT = THREE.RepeatWrapping;
            mapSpecular.format = THREE.RGBFormat;

            // skin texture
            var mapColor = textureLoader.load( "leeperrysmith/middleage_lightskinned_male_diffuse2.png" );

            mapColor.anisotropy = 4;
            mapColor.wrapS = mapColor.wrapT = THREE.RepeatWrapping;
            mapColor.format = THREE.RGBFormat;

            var shader = THREE.ShaderSkin[ "skinSimple" ];

            var fragmentShader = shader.fragmentShader;
            var vertexShader = shader.vertexShader;

            var uniforms = THREE.UniformsUtils.clone( shader.uniforms );

            uniforms[ "enableBump" ].value = true;
            uniforms[ "enableSpecular" ].value = true;

            uniforms[ "tBeckmann" ].value = composerBeckmann.renderTarget1.texture;
            uniforms[ "tDiffuse" ].value = mapColor;

            uniforms[ "bumpMap" ].value = mapHeight;
            uniforms[ "specularMap" ].value = mapSpecular;

            uniforms[ "diffuse" ].value.setHex( 0xffffff );
            uniforms[ "specular" ].value.setHex( 0xffffff );
            //uniforms[ "specular" ].value.setHex( 0xa0a0a0 );

            uniforms[ "uRoughness" ].value = 0.2;
            uniforms[ "uSpecularBrightness" ].value = 1;

            // change the bump scale 
            uniforms[ "bumpScale" ].value = 0.5;

            var material = new THREE.ShaderMaterial( { 

            fragmentShader: fragmentShader, 
            vertexShader: vertexShader, 
            uniforms: uniforms, 
            lights: true,  
            morphTargets: true,
            //morphNormals: true,
            } );

            material.extensions.derivatives = true;

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

            mesh.position.y = - 50;
            mesh.scale.set( scale, scale, scale );

            mesh.castShadow = true;
            mesh.receiveShadow = true;

            scene.add( mesh);//, mesh2 );
        }

        //
        function onWindowResize( event ) {

            windowHalfX = window.innerWidth / 2;
            windowHalfY = window.innerHeight / 2;

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

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

        }

        function onDocumentMouseMove( event ) {

            mouseX = ( event.clientX - windowHalfX ) * 1;
            mouseY = ( event.clientY - windowHalfY ) * 1;

        }

        //
        function animate() {

            requestAnimationFrame( animate );
            controls.update(); 
            render();
            if ( statsEnabled ) stats.update();

        }

        function render() {

            targetX = mouseX * .001;
            targetY = mouseY * .001;

            if ( mesh ) {

                mesh.rotation.y += 0.05 * ( targetX - mesh.rotation.y );
                mesh.rotation.x += 0.05 * ( targetY - mesh.rotation.x );

            }

            if ( firstPass ) {

                composerBeckmann.render();
                firstPass = false;

            }

            renderer.clear();
            renderer.render( scene, camera );

        }

    </script>

</body>

有人可以告诉我如何解决这个问题,或者让我知道在使用ShaderMaterial时是否还有其他方法可以访问morphTargets?

0 个答案:

没有答案