[Three.js] 본 애니메이션이나 모프 애니메이션을 하는 메쉬의 정점 좌표를 취득한다
덧붙여서 Stack Overflow 상의 코드는 특별한 기술이 없는 한, CC BY-SA 3.0에서 라이센스
gman씨는 한층 더 자신의 코드를 CC0로 라이센스한다고 명언하고 있으므로, 이 기사에 라이센스상의 문제는 특별히 없다.
문제
예를 들면 이 동작 샘플 에 있어서의 검사 메쉬를 구성하는 각 정점의 좌표를 취득하려면 어떻게 하면 좋을까?
본 애니메이션이나 모프 애니메이션을 하지 않는 메쉬의 정점 좌표
우선 전제 지식으로서.
이쪽은 간단하게 취득할 수 있다.
mesh의 vertexIndex 번째 정점의 로컬 좌표를 가져옵니다.const localPosition = mesh.geometry.vertices[vertexIndex];
mesh의 vertexIndex 번째 정점의 전역 좌표를 가져옵니다.mesh.updateMatrixWorld();
const globalPosition = mesh.geometry.vertices[vertexIndex].clone();
globalPosition.applyMatrix4(mesh.matrixWorld);
앞의 예의 검사 메쉬는 본 애니메이션, 모프 애니메이션을 실시하고 있으므로 이 방법에서는 정점 좌표를 취득할 수 없다.
본 애니메이션이나 모프 애니메이션의 효과가 미치기 전의 정점 좌표를 취득할 수 있을 뿐이다.
본 애니메이션이나 모프 애니메이션을 하는 메쉬의 정점 좌표
원래 제작으로 Three.js는 JavaScript 코드에서 GLSL 프로그램을 자동 생성하고 그리기 처리의 대부분을 자동 생성한 GLSL에 맡기고 있다.
본 애니메이션이나 모프 애니메이션을 하는 메쉬의 정점 좌표를 계산하는 처리도 GLSL 안에서 행해지고 있어 JavaScript측에서 계산 결과를 취득하는 것은 원칙할 수 없다.
그래서 gman씨는 GLSL중의 정점 좌표 계산 처리를 JavaScript로 번역했다.
덧붙여 모든 케이스에서 완벽하게 움직이는 보증까지는 하지 않기 때문에, 잘 움직이지 않는 케이스에 닿으면 노력할 수 있다고 하는 것이다.
mesh의 정점의 좌표를 취득한다// 各種パラメータを最新の状態にしておく
mesh.updateMatrixWorld();
mesh.skeleton.update();
// バッファ
const position = new THREE.Vector3();
const transformed = new THREE.Vector3();
const temp1 = new THREE.Vector3();
const tempBoneMatrix = new THREE.Matrix4();
const tempSkinnedVertex = new THREE.Vector3();
const tempSkinned = new THREE.Vector3();
// 頂点座標計算処理
for (let vndx = 0; vndx < mesh.geometry.vertices.length; ++vndx) {
position.copy(mesh.geometry.vertices[vndx]);
transformed.copy(position);
for (let i = 0; i < mesh.geometry.morphTargets.length; ++i) {
temp1.copy(mesh.geometry.morphTargets[i].vertices[vndx]);
transformed.add(temp1.sub(position).multiplyScalar(mesh.morphTargetInfluences[i]));
}
tempSkinnedVertex.copy(transformed).applyMatrix4(mesh.bindMatrix);
tempSkinned.set(0, 0, 0);
const skinIndices = mesh.geometry.skinIndices[vndx];
const skinWeights = mesh.geometry.skinWeights[vndx];
for (let i = 0; i < 4; ++i) {
const boneNdx = skinIndices.getComponent(i);
const weight = skinWeights.getComponent(i);
tempBoneMatrix.fromArray(mesh.skeleton.boneMatrices, boneNdx * 16);
temp1.copy(tempSkinnedVertex);
tempSkinned.add(temp1.applyMatrix4(tempBoneMatrix).multiplyScalar(weight));
}
transformed.copy(tempSkinned).applyMatrix4(mesh.bindMatrixInverse);
// この時点でのtransformedがmeshのvndx番目の頂点のローカル座標
transformed.applyMatrix4(mesh.matrixWorld);
// この時点でのtransformedがmeshのvndx番目の頂点のグローバル座標
}
동작 샘플
검사 메쉬를 구성하는 각 정점의 좌표에 빨간 상자를 설치하고 있다.
올바르게 정점 좌표를 취득할 수 있는 것을 알 수 있다.
다만, 본래 GPU로 하는 처리를 CPU로 하고 있기 때문에 북극이 되어 버린다.
덤: 드로잉에 사용되는 GLSL 코드를 얻는 방법
material
에서 그리기에 사용되고 있는 정점 쉐이더의 소스는 renderer.context.getShaderSource(material.program.vertexShader)
, 픽셀 셰이더의 소스는 renderer.context.getShaderSource(material.program.fragmentShader)
로 볼 수 있는 모양.
Reference
이 문제에 관하여([Three.js] 본 애니메이션이나 모프 애니메이션을 하는 메쉬의 정점 좌표를 취득한다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/anqooqie/items/bc8af195238d08bb3bfd
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
우선 전제 지식으로서.
이쪽은 간단하게 취득할 수 있다.
mesh의 vertexIndex 번째 정점의 로컬 좌표를 가져옵니다.
const localPosition = mesh.geometry.vertices[vertexIndex];
mesh의 vertexIndex 번째 정점의 전역 좌표를 가져옵니다.
mesh.updateMatrixWorld();
const globalPosition = mesh.geometry.vertices[vertexIndex].clone();
globalPosition.applyMatrix4(mesh.matrixWorld);
앞의 예의 검사 메쉬는 본 애니메이션, 모프 애니메이션을 실시하고 있으므로 이 방법에서는 정점 좌표를 취득할 수 없다.
본 애니메이션이나 모프 애니메이션의 효과가 미치기 전의 정점 좌표를 취득할 수 있을 뿐이다.
본 애니메이션이나 모프 애니메이션을 하는 메쉬의 정점 좌표
원래 제작으로 Three.js는 JavaScript 코드에서 GLSL 프로그램을 자동 생성하고 그리기 처리의 대부분을 자동 생성한 GLSL에 맡기고 있다.
본 애니메이션이나 모프 애니메이션을 하는 메쉬의 정점 좌표를 계산하는 처리도 GLSL 안에서 행해지고 있어 JavaScript측에서 계산 결과를 취득하는 것은 원칙할 수 없다.
그래서 gman씨는 GLSL중의 정점 좌표 계산 처리를 JavaScript로 번역했다.
덧붙여 모든 케이스에서 완벽하게 움직이는 보증까지는 하지 않기 때문에, 잘 움직이지 않는 케이스에 닿으면 노력할 수 있다고 하는 것이다.
mesh의 정점의 좌표를 취득한다// 各種パラメータを最新の状態にしておく
mesh.updateMatrixWorld();
mesh.skeleton.update();
// バッファ
const position = new THREE.Vector3();
const transformed = new THREE.Vector3();
const temp1 = new THREE.Vector3();
const tempBoneMatrix = new THREE.Matrix4();
const tempSkinnedVertex = new THREE.Vector3();
const tempSkinned = new THREE.Vector3();
// 頂点座標計算処理
for (let vndx = 0; vndx < mesh.geometry.vertices.length; ++vndx) {
position.copy(mesh.geometry.vertices[vndx]);
transformed.copy(position);
for (let i = 0; i < mesh.geometry.morphTargets.length; ++i) {
temp1.copy(mesh.geometry.morphTargets[i].vertices[vndx]);
transformed.add(temp1.sub(position).multiplyScalar(mesh.morphTargetInfluences[i]));
}
tempSkinnedVertex.copy(transformed).applyMatrix4(mesh.bindMatrix);
tempSkinned.set(0, 0, 0);
const skinIndices = mesh.geometry.skinIndices[vndx];
const skinWeights = mesh.geometry.skinWeights[vndx];
for (let i = 0; i < 4; ++i) {
const boneNdx = skinIndices.getComponent(i);
const weight = skinWeights.getComponent(i);
tempBoneMatrix.fromArray(mesh.skeleton.boneMatrices, boneNdx * 16);
temp1.copy(tempSkinnedVertex);
tempSkinned.add(temp1.applyMatrix4(tempBoneMatrix).multiplyScalar(weight));
}
transformed.copy(tempSkinned).applyMatrix4(mesh.bindMatrixInverse);
// この時点でのtransformedがmeshのvndx番目の頂点のローカル座標
transformed.applyMatrix4(mesh.matrixWorld);
// この時点でのtransformedがmeshのvndx番目の頂点のグローバル座標
}
동작 샘플
검사 메쉬를 구성하는 각 정점의 좌표에 빨간 상자를 설치하고 있다.
올바르게 정점 좌표를 취득할 수 있는 것을 알 수 있다.
다만, 본래 GPU로 하는 처리를 CPU로 하고 있기 때문에 북극이 되어 버린다.
덤: 드로잉에 사용되는 GLSL 코드를 얻는 방법
material
에서 그리기에 사용되고 있는 정점 쉐이더의 소스는 renderer.context.getShaderSource(material.program.vertexShader)
, 픽셀 셰이더의 소스는 renderer.context.getShaderSource(material.program.fragmentShader)
로 볼 수 있는 모양.
Reference
이 문제에 관하여([Three.js] 본 애니메이션이나 모프 애니메이션을 하는 메쉬의 정점 좌표를 취득한다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/anqooqie/items/bc8af195238d08bb3bfd
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
// 各種パラメータを最新の状態にしておく
mesh.updateMatrixWorld();
mesh.skeleton.update();
// バッファ
const position = new THREE.Vector3();
const transformed = new THREE.Vector3();
const temp1 = new THREE.Vector3();
const tempBoneMatrix = new THREE.Matrix4();
const tempSkinnedVertex = new THREE.Vector3();
const tempSkinned = new THREE.Vector3();
// 頂点座標計算処理
for (let vndx = 0; vndx < mesh.geometry.vertices.length; ++vndx) {
position.copy(mesh.geometry.vertices[vndx]);
transformed.copy(position);
for (let i = 0; i < mesh.geometry.morphTargets.length; ++i) {
temp1.copy(mesh.geometry.morphTargets[i].vertices[vndx]);
transformed.add(temp1.sub(position).multiplyScalar(mesh.morphTargetInfluences[i]));
}
tempSkinnedVertex.copy(transformed).applyMatrix4(mesh.bindMatrix);
tempSkinned.set(0, 0, 0);
const skinIndices = mesh.geometry.skinIndices[vndx];
const skinWeights = mesh.geometry.skinWeights[vndx];
for (let i = 0; i < 4; ++i) {
const boneNdx = skinIndices.getComponent(i);
const weight = skinWeights.getComponent(i);
tempBoneMatrix.fromArray(mesh.skeleton.boneMatrices, boneNdx * 16);
temp1.copy(tempSkinnedVertex);
tempSkinned.add(temp1.applyMatrix4(tempBoneMatrix).multiplyScalar(weight));
}
transformed.copy(tempSkinned).applyMatrix4(mesh.bindMatrixInverse);
// この時点でのtransformedがmeshのvndx番目の頂点のローカル座標
transformed.applyMatrix4(mesh.matrixWorld);
// この時点でのtransformedがmeshのvndx番目の頂点のグローバル座標
}
검사 메쉬를 구성하는 각 정점의 좌표에 빨간 상자를 설치하고 있다.
올바르게 정점 좌표를 취득할 수 있는 것을 알 수 있다.
다만, 본래 GPU로 하는 처리를 CPU로 하고 있기 때문에 북극이 되어 버린다.
덤: 드로잉에 사용되는 GLSL 코드를 얻는 방법
material
에서 그리기에 사용되고 있는 정점 쉐이더의 소스는 renderer.context.getShaderSource(material.program.vertexShader)
, 픽셀 셰이더의 소스는 renderer.context.getShaderSource(material.program.fragmentShader)
로 볼 수 있는 모양.
Reference
이 문제에 관하여([Three.js] 본 애니메이션이나 모프 애니메이션을 하는 메쉬의 정점 좌표를 취득한다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/anqooqie/items/bc8af195238d08bb3bfd
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여([Three.js] 본 애니메이션이나 모프 애니메이션을 하는 메쉬의 정점 좌표를 취득한다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/anqooqie/items/bc8af195238d08bb3bfd텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)