【问题标题】:reload textures from a file从文件重新加载纹理
【发布时间】:2013-11-19 01:20:07
【问题描述】:

我正在开发一个“实时图像编辑器”以在三个 js 中应用纹理。

我的应用程序有两个部分,一个 2D 画布编辑器和一个显示在 2D 部分中完成的合成的 3D 模型。

您在 2d 部分中进行图像拼贴,将此构图保存在图像文件中,然后以 3d 模型进行充电。

我的问题是当用户进行更改时我无法重新加载图像文件。哟可以做第一个构图并在3d模型中正确充电,但如果你对构图进行另一次更改,请再次保存,并尝试应用于3d模型,不会重新加载文件中的数据,并显示旧图像.如果您加载另一个图像文件,它可以正常工作,但使用相同的图像文件名(数据更改,但名称相同)不会显示真实数据。

我的代码:

var cubeCamera, projector;
var texturas=[false,false,false];
var FAR = 1000;
var light, controls;
var SCREEN_WIDTH = _ANCHO3D = 380   ;
var SCREEN_HEIGHT = _ALTO3D = 340;
var container;
var camera, scene, projector, renderer;
var loader;
var composer;
var testParams, testPass;   
var tex, tex2, tex3;
var auxi=1;

$("#visor3D").append("<div id='conten3D' style='width:"+_ANCHO3D+"px; height:"+_ALTO3D+"px; border: 1px solid green;'></div>");

var clock = new THREE.Clock();
init();
animate();

function init() 
        {
    camera = new THREE.PerspectiveCamera( 40, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 900 );
    camera.position.set( -270, 45, 1 );

    // SCENE
    scene = new THREE.Scene();

    // LIGHTS                           
    var ambientLight = new THREE.AmbientLight(0xffffff,1.5);
        scene.add(ambientLight);                

    hemiLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, 1.5 );
    scene.add(hemiLight);

    renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer : true } );

    renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );

    container=$("#conten3D");
    container.append(renderer.domElement);

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

    // CONTROLS
    controls = new THREE.TrackballControls( camera, renderer.domElement );
            controls_set(); 

    loader = new THREE.OBJMTLLoader();
    loader.addEventListener('load', function ( event ) 
        {
        object = event.content;                 
        object.position.y = 44;                 
        object.scale.x =0.15;
        object.scale.y =0.15;
        object.scale.z =0.15;
        tex=new THREE.Texture();
        tex2=new THREE.Texture();
        tex3=new THREE.Texture();
                         object.children[11].material.map=THREE.ImageUtils.loadTexture( "obj/maps/blanco.jpg");
                object.children[10].material.map=THREE.ImageUtils.loadTexture( "obj/maps/blanco.jpg");
                object.children[6].material.map=THREE.ImageUtils.loadTexture( "obj/maps/blanco.jpg");
                object.children[8].material.map=THREE.ImageUtils.loadTexture( "obj/maps/blanco.jpg");       
                object.children[15].material.map=THREE.ImageUtils.loadTexture( "obj/maps/blanco.jpg");
                //aplicartexturas();
                scene.add( object );
                });

            loader.load( 'obj/demo.obj', 'obj/demo0.mtl' );

            }

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

        function render() 
            {
            tex.needsUpdate = true;
            tex2.needsUpdate = true;
            tex3.needsUpdate = true;
            var delta = clock.getDelta();
            controls.update( delta );
            renderer.render( scene, camera );
            }

function aplicartexturas()
{
tex=THREE.ImageUtils.loadTexture( "disenos/"+userid+"_LD.png" );
tex2=THREE.ImageUtils.loadTexture("disenos/"+userid+"_LI.png");
tex3=THREE.ImageUtils.loadTexture( "disenos/"+userid+"_BA.png" );
object.children[11].material.map=tex;
object.children[10].material.map=tex2;
object.children[6].material.map=tex3;
object.children[8].material.map=tex3;               
object.children[15].material.map=tex3;
}

当给物体充电时,我对所有物体都应用白色纹理 后来,当我在 2d 编辑器中进行更改时,我将这些更改应用到函数“aplicartexturas()”中。在这个函数中,“userid”是页面中的一个全局变量,供不同的多个用户访问。

谢谢。

【问题讨论】:

  • 试试这个: (1) 从渲染循环中删除 needsUpdate = true -- loadTexture 为您设置该标志。 (2) 加载是异步的。在加载后分配新加载的纹理——在loadTexture 回调中。 (3) 可以共享白色纹理。无需多次加载。
  • 是这个问题吗?如果是这样,我会发布一个答案。
  • 感谢您的回答。我删除了needsUpdate=true (1),现在我使用一个变量来加载白色纹理并将这个变量分配给所有贴图 (2)。但这很奇怪,我在回调tex2=THREE.ImageUtils.loadTexture("disenos/"+userid+"_LI.png", null, function(){ object.children[10].material.map=tex2; }); 中分配了新加载的纹理,但没有任何变化;也尝试将新加载的纹理直接分配给地图object.children[10].material.map=new THREE.ImageUtils.loadTexture("disenos/"+userid+"_LI.png");,但没有任何事情发生,但如果我同时做,那么它可以工作。再次感谢。
  • 好吧,如果你需要进一步的帮助,你将不得不发布一个简单的、活生生的例子来演示这个问题。

标签: 3d three.js


【解决方案1】:

这是工作代码:

        var cubeCamera, projector;
        var texturas=[false,false,false];
        var FAR = 1000;
        var light, controls;
        var SCREEN_WIDTH = _ANCHO3D = 380   ;
        var SCREEN_HEIGHT = _ALTO3D = 340;
        var container;
        var camera, scene, projector, renderer;
        var loader;
        var composer;
        var testParams, testPass;   
        var tex, tex2, tex3;
        var auxi=1;

        $("#visor3D").append("<div id='conten3D' style='width:"+_ANCHO3D+"px; height:"+_ALTO3D+"px; border: 1px solid green;'></div>");
        var clock = new THREE.Clock();
        init();
        animate();

        function init() 
            {
            camera = new THREE.PerspectiveCamera( 40, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 900 );
            camera.position.set( -270, 45, 1 );

            // SCENE
            scene = new THREE.Scene();

            // LIGHTS                           
            var ambientLight = new THREE.AmbientLight(0xffffff,1.5);
            scene.add(ambientLight);                

            hemiLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, 1.5 );
            scene.add(hemiLight);

            renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer : true } );

            renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );

            container=$("#conten3D");
            container.append(renderer.domElement);

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

            // CONTROLS
            controls = new THREE.TrackballControls( camera, renderer.domElement );
            controls_set(); 

            loader = new THREE.OBJMTLLoader();
            loader.addEventListener('load', function ( event ) 
                {
                object = event.content;                 
                object.position.y = 44;                 
                object.scale.x =0.15;
                object.scale.y =0.15;
                object.scale.z =0.15;

                tex=new THREE.Texture();
                tex2=new THREE.Texture();
                tex3=new THREE.Texture();

                var blanco=new THREE.ImageUtils.loadTexture( "obj/maps/blanco.jpg");
                object.children[11].material.map=blanco;
                object.children[10].material.map=blanco;
                object.children[6].material.map=blanco;
                object.children[8].material.map=blanco;
                object.children[15].material.map=blanco;                    

                scene.add( object );
                });

            loader.load( 'obj/demo.obj', 'obj/demo0.mtl' );

            }

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

        function render() 
            {
            var delta = clock.getDelta();
            controls.update( delta );
            renderer.render( scene, camera );
            }




function aplicartexturas()
{   
tex2=THREE.ImageUtils.loadTexture("disenos/"+userid+"_LI.png", null, function(){
    object.children[10].material.map=tex2;
    });
tex=THREE.ImageUtils.loadTexture("disenos/"+userid+"_LD.png", null, function(){
    object.children[11].material.map=tex;
    });
tex3=THREE.ImageUtils.loadTexture("disenos/"+userid+"_BA.png", null, function(){
    object.children[6].material.map=tex3;
    object.children[8].material.map=tex3;
    object.children[15].material.map=tex3;
    });

object.children[10].material.map=new THREE.ImageUtils.loadTexture("disenos/"+userid+"_LI.png");
object.children[11].material.map=new THREE.ImageUtils.loadTexture( "disenos/"+userid+"_LD.png");
object.children[6].material.map=new THREE.ImageUtils.loadTexture( "disenos/"+userid+"_BA.png");
object.children[8].material.map=new THREE.ImageUtils.loadTexture( "disenos/"+userid+"_BA.png");
object.children[15].material.map=new THREE.ImageUtils.loadTexture( "disenos/"+userid+"_BA.png");
render();
}

使用此代码,当我调用函数 aplicartexturas() 时,应用程序会从三个不同的图像文件重新加载数据并“实时”显示,而无需重新加载所有 3d 对象。

需要两种不同的负载和分配才能工作,这很奇怪:

tex2=THREE.ImageUtils.loadTexture("disenos/"+userid+"_LI.png", null, function(){
    object.children[10].material.map=tex2;
    });

object.children[10].material.map=new THREE.ImageUtils.loadTexture("disenos/"+userid+"_LI.png");

而且我认为这不是很理想。

如果您知道更好或最佳的正确方法,请发布。

谢谢大家的回答。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-27
    • 2018-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多