2017-08-28 161 views
0

我試圖用three.js創建一個配置器,但即時點我需要改變產品的顏色dinamycally,我雖然那我可以使用SVG作爲紋理,改變SVG的填充性能,輕鬆地更新紋理,但我不是有很好的效果動態更改svg的顏色並將其作爲紋理應用於three.js

此刻我有什麼是

-A 3D模型與應用爲SVG紋理與TextureLoader,但svg被放置在一個外部文件(「images/texture.svg」)(也three.js減少紋理的大小,但我認爲它的映射問題)

-The SVG是在層分離,這樣我就可以手動更改顏色,並將其應用於

但是我試圖使它的動態,你選擇一種顏色,它會自動更新應用紋理

任何SVG的想法?

謝謝!

回答

2

我指派別人的小提琴來展示解決方案。我添加了一個修改SVG並在模型上重繪材質的點擊功能。

參見例子http://jsfiddle.net/L4pepnj7/

點擊任意位置更改SVG圓的顏色。

將SVG轉換爲encodedURI的操作需要密集處理以保持常量循環,但您可以在渲染器自己做事情時將顏色更改置於點擊事件中。我在現有的小提琴中添加了一個名爲「clickBody」的函數,該函數改變了其中一個SVG元素的顏色。

var mesh; 
var scene = new THREE.Scene(); 

var camera = new THREE.PerspectiveCamera(50, 500/400, 0.1, 1000); 
camera.position.z = 10; 

var renderer = new THREE.WebGLRenderer({ 
    antialias: true 
}); 
renderer.setSize(500, 400); 
document.body.appendChild(renderer.domElement); 

var svg = document.getElementById("svgContainer").querySelector("svg"); 
var svgData = (new XMLSerializer()).serializeToString(svg); 

var canvas = document.createElement("canvas"); 
var svgSize = svg.getBoundingClientRect(); 
canvas.width = svgSize.width; 
canvas.height = svgSize.height; 
var ctx = canvas.getContext("2d"); 

var img = document.createElement("img"); 
var material; 
img.setAttribute("src", "data:image/svg+xml;base64," + window.btoa(unescape(encodeURIComponent(svgData)))); 

img.onload = function() { 
    ctx.drawImage(img, 0, 0); 
    var texture = new THREE.Texture(canvas); 
    texture.needsUpdate = true; 
    var geometry = new THREE.SphereGeometry(3, 50, 50, 0, Math.PI * 2, 0, Math.PI * 2); 
    material = new THREE.MeshBasicMaterial({ 
     map: texture 
    }); 
    material.map.minFilter = THREE.LinearFilter; 
    mesh = new THREE.Mesh(geometry, material); 
    scene.add(mesh); 
}; 



var colors = ["red", "orange", "yellow", "green", "blue"]; 


var c = 0; 

function clickBody() { 
    document.getElementById("test").setAttribute("fill", colors[c]); 
    var svgData = (new XMLSerializer()).serializeToString(svg); 
    img.setAttribute("src", "data:image/svg+xml;base64," + window.btoa(unescape(encodeURIComponent(svgData)))); 
    img.onload = function() { 
     ctx.drawImage(img, 0, 0); 
     var texture = new THREE.Texture(canvas); 
     material.map = texture; 
     material.map.needsUpdate = true; 
     renderer.render(scene, camera); 
    } 
    c = c + 1; 
    if (c == colors.length) { 
     c = 0; 
    } 
} 
document.body.addEventListener("click", clickBody) 

var render = function() { 
    requestAnimationFrame(render); 
    mesh.rotation.y += 0.01; 
    renderer.render(scene, camera); 
}; 


render(); 
+0

所以基本上這是什麼代碼正在做的是使更新後的紋理只在clickevent?請問SVG的大小會影響到UV貼圖或比例?我的意思是,一個爲800x800 SVG質地會在相同的UV紋理空間比300x300? –

+0

@robertgarcia是的。所以在你的情況下,你有一個產品配置器來改變3D模型的圖形。在這種情況下,如果SVG通過單獨的UI更新,例如通過[svg-edit](https://github.com/SVG-Edit/svgedit)啓用,則可以觸發代碼將svg重新繪製爲編碼uri,並將其設置爲材質的新紋理。 – Radio

+0

好吧,關鍵並不是要改變圖形,只需加載一個3D模型,並且您可以選擇不同的設計(SVG中的紋理),一旦您擁有了您想要的圖形,就可以使用您的圖形更改紋理的SVG屬性例如,使用顏色選擇器界面,所以你的技巧,謝謝! –