簡體   English   中英

THREE.js - 將漸變 Colors 應用到導入的 GLTF Model

[英]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 來處理所有這些工作,我的策略是:

  1. 像我們一直在做的那樣,使用GLTFLoader加載Flower.glb model,一旦加載成功……
  2. 調用我的另一個 function 循環創建 500 個此 Flower 的新實例,每個實例都有自己獨特的花朵漸變顏色、x、y、z、坐標等。

您的代碼運行良好,但我試圖使其在多個 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM