[英]THREE.js - Apply Gradient Colors to Imported GLTF Model
我一直在嘗試將漸變 colors 應用於此官方 THREE.js 教程中使用的 Flower model:
https://threejs.org/examples/webgl_instancing_scatter.html
花 model 長這樣:
它可以從這里下載: https://github.com/mrdoob/three.js/tree/master/examples/models/gltf/Flower )
到目前為止,我已經能夠成功地將 model 加載到我的項目中,並且我還能夠將不同的 colors 應用到其“開花”網格 - 但只有實心 Z62848E3CE5804AA985513A79222FF8。
我想應用漸變colors。
為了說明我的想法,我在 Photoshop 中制作了一張非常快速和骯臟的圖像,它可能看起來像:
我嘗試使用vertexColors
技術來做到這一點——這是我知道的唯一技術(我對 THREE.js 很陌生)——到目前為止還沒有運氣(代碼如下。)
在這一點上,我的一部分想知道這是否可能與進口的 GLTF model 相關 - 或者它是否是一個失敗的原因。
希望得到一些輸入/幫助。
這是我的代碼 - 分為兩部分:第一部分是固體 colors - 有效,第二部分是我嘗試應用漸變 colors - 這不起作用:
// NOTE: I stored the already imported GLTF model in a new Mesh called “blossomMesh”
// 1. Create a new Group to which I’ll add the Stem and Blossom:
var newFlower = new THREE.Group();
// 2. CLONE the MESH of the imported 3D model:
let newBlossomMesh = blossomMesh.clone();
// 3. CLONE it's GEOMETRY:
var newBlossomGeometry = blossomMesh.geometry.clone();
// 4. CLONE it's MATERIAL:
var newBlossomMaterial = blossomMesh.material.clone();
// 5. MAKE a NEW COLOR:
let newBlossomColor = new THREE.Color(generateRandomColor());
newBlossomMaterial.color = newBlossomColor;
newBlossomMesh.material = newBlossomMaterial;
newFlower.add(newBlossomMesh);
newFlower.add(newStemMesh);
scene.add(newFlower);
所以以上適用於 SOLID colors。
這是我試圖獲得漸變 colors 的內容:
// THE BLOSSOM:
// 1. CLONE the MESH of the imported 3D model:
let newBlossomMesh = blossomMesh.clone();
// 2. This time use a BufferGeometry to CLONE the GEOMETRY:
var newBlossomGeometry = new THREE.BufferGeometry();
newBlossomGeometry = blossomMesh.geometry.clone();
var blossomVertexPositionsArray = newBlossomGeometry.attributes.position;
newBlossomGeometry = newBlossomGeometry.toNonIndexed();
blossomVertexPositionsArray = newBlossomGeometry.attributes.position;
// Make a Colors Array:
var blossomColorsArray = [];
const newBlossomColor = new THREE.Color();
for(var i = 0, l = blossomVertexPositionsArray.count; i < l; i ++) {
newBlossomColor.setHSL(Math.random() * 0.2 + 0.05, 0.95, 0.799);
blossomColorsArray.push(newBlossomColor.r, newBlossomColor.g, newBlossomColor.b);
}
// Now “splash” the "blossomColorsArray" all over the Blossom:
newBlossomGeometry.setAttribute("color", new THREE.Float32BufferAttribute(blossomColorsArray, 3));
newBlossomMesh.material = newBlossomMaterial;
newFlower.add(newBlossomMesh);
newFlower.add(newStemMesh);
scene.add(newFlower);
我從中得到的是黑色的花朵。 它基本上看起來就像沒有任何顏色,所以我看到的黑色更像是沒有顏色,而不是實際的顏色“黑色”。
=================================================
更新:
好的,所以它正在工作 - 但只是“單一地”,而且只有“本地”。
這就是我的意思:我想做的不僅僅是一朵花 object,而是 100 朵。 而且我不想在 GLTFLoader 的回調GLTFLoader
中這樣做,因為我需要將各種其他邏輯應用於我的 100 個花對象(比如給它們(x,y,z)坐標,給它們userData
值,添加他們到 arrays 等。因此,我創建了一個單獨的 function 來處理所有這些工作,我的策略是:
GLTFLoader
加載Flower.glb
model,一旦加載成功…… 您的代碼運行良好,但我試圖使其在多個 Blossom 對象上工作,並在GLTFLoader
function 的回調之外進行。 正是這后半部分讓我抓狂。
這是我的代碼:
(目前的結果是,我的 500 朵花中的每一朵都得到完全相同的灰色——而且沒有漸變;它們只是不工作。)
var blossomMesh;
var stemMesh;
function load3DFlowerModel() {
loader.load("./Flower.glb", function(theFlower) {
flowerScene = theFlower.scene;
// Assign values to my global "blossomMesh" and "stemMesh" variables:
blossomMesh = flowerScene.children[0]; // Blossom
stemMesh = flowerScene.children[1]; // Stem
// Now call my external function:
makeFlowers();
});
}
function makeFlowers() {
for(var flowerCount = 0; flowerCount < TOTAL_FLOWERS; flowerCount ++) {
var newFlowerGroup = new THREE.Group();
// I. THE BLOSSOM:
// 1. First, make a new copy of the incoming global "blossomMesh" object:
var newBlossomMesh = blossomMesh.clone();
// 2. Next, make a new copy of the MATERIAL of the incoming global "blossomMesh" object:
var newBlossomMaterial = blossomMesh.material.clone();
// 3. Now make a new copy of the GEOMETRY of the incoming global "blossomMesh" object:
var newBlossomGeometry = blossomMesh.geometry.clone();
// 4. Get its vertices:
let blossomVertexPositionsArray = newBlossomGeometry.attributes.position;
// 5. Make Colors for it:
var blossomColorsArray = [];
var newBlossomColor = new THREE.Color();
for(var i = 0; i < blossomVertexPositionsArray.count; i ++) {
newBlossomColor.setHSL(Math.random() * 0.2 + 0.05, 0.95, 0.799);
blossomColorsArray.push(newBlossomColor.r, newBlossomColor.g, newBlossomColor.b);
}
// 6. Finally SPLASH the "blossomColorsArray" all over the Blossom's Geometry:
newBlossomGeometry.setAttribute("color", new THREE.Float32BufferAttribute(blossomColorsArray, 3));
// And set "vertexColors" to true:
newBlossomMaterial.vertexColors = true;
// II. THE STEM
let newStemMesh = stemMesh.clone();
newStemMesh.castShadow = true;
newTulipGroup.add(newStemMesh);
newTulipGroup.add(newBlossomMesh);
newTulipGroup.name = "Tulip#" + tulipCount;
// etc.
所以我得到了一整束花,但它們都有相同的灰色花朵。 總是灰色的...
按預期工作。 將燈光添加到場景中,為材質設置vertexColors: true
。
body{ overflow: hidden; margin: 0; }
<script type="module"> import * as THREE from "https://threejs.org/build/three.module.js"; import {OrbitControls} from "https://threejs.org/examples/jsm/controls/OrbitControls.js"; import {GLTFLoader} from "https://threejs.org/examples/jsm/loaders/GLTFLoader.js"; let scene = new THREE.Scene(); let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 0.1, 10); camera.position.set(0, 5, 5); let renderer = new THREE.WebGLRenderer(); renderer.setSize(innerWidth, innerHeight); document.body.appendChild(renderer.domElement); let controls = new OrbitControls(camera, renderer.domElement); let light = new THREE.DirectionalLight(0xffffff, 1); light.position.setScalar(10); scene.add(light); scene.add(new THREE.AmbientLight(0xffffff, 0.5)); scene.add(new THREE.GridHelper()); let loader = new GLTFLoader(); loader.load("https://threejs.org/examples/models/gltf/Flower/Flower.glb", gltf => { let model = gltf.scene; model.scale.setScalar(10); //console.log(model); let g = model.children[0].geometry; let m = model.children[0].material; let p = g.attributes.position; let c = new THREE.Color(); let colors = []; for(let i = 0; i < p.count; i++){ c.set(Math.random() < 0.5? 0xff00ff: 0xffff00); colors.push(c.r, c.g, c.b); } g.setAttribute("color", new THREE.Float32BufferAttribute(colors, 3)); m.vertexColors = true; scene.add(model); }); renderer.setAnimationLoop( _ => { renderer.render(scene, camera); }); </script>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.