1 Star 0 Fork 0

ing10010/verge3d-code-examples

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
webgl_materials_curvature.html 10.11 KB
一键复制 编辑 原始数据 按行查看 历史
<!DOCTYPE html>
<html lang="en">
<head>
<title>Verge3D webgl - shader - curvature [ninja]</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link type="text/css" rel="stylesheet" href="main.css">
</head>
<body>
<div id="container"></div>
<div id="info">
<a href="https://www.soft8soft.com/verge3d" target="_blank" rel="noopener">Verge3D</a> - curvature estimation of a geometry<br/>
by <a href="http://codercat.club" target="_blank" rel="noopener">CoderCat</a>
</div>
<script id="vertexShaderRaw" type="x-shader/x-vertex">
attribute float curvature;
varying float vCurvature;
void main() {
vec3 p = position;
vec4 modelViewPosition = modelViewMatrix * vec4(p , 1.0);
gl_Position = projectionMatrix * modelViewPosition;
vCurvature = curvature;
}
</script>
<script id="fragmentShaderRaw" type="x-shader/x-fragment">
varying vec3 vViewPosition;
varying float vCurvature;
void main() {
gl_FragColor = vec4(vCurvature * 2.0, 0.0, 0.0, 0.0);
}
</script>
<script type="module">
import * as v3d from '../build/v3d.module.js';
import { GUI } from './jsm/libs/dat.gui.module.js';
import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { OBJLoader } from './jsm/loaders/OBJLoader.js';
let camera, scene, renderer;
let ninjaMeshRaw, curvatureAttribute, bufferGeo;
init();
animate();
//returns average of elements in a dictionary
function average(dict) {
let sum = 0;
let length = 0;
Object.keys(dict).forEach(function(key) {
sum += dict[key];
length ++;
});
return sum / length;
}
//clamp a number between min and max
function clamp(number, min, max) {
return Math.max(min, Math.min(number, max));
}
//filter the curvature array to only show concave values
function filterConcave(curvature) {
for (let i = 0; i < curvature.length; i++) {
curvature[i] = Math.abs(clamp(curvature[i], - 1, 0));
}
}
//filter the curvature array to only show convex values
function filterConvex(curvature) {
for (let i = 0; i < curvature.length; i++) {
curvature[i] = clamp(curvature[i], 0, 1);
}
}
//filter the curvature array to show both the concave and convex values
function filterBoth(curvature) {
for (let i = 0; i < curvature.length; i++) {
curvature[i] = Math.abs(curvature[i]);
}
}
//initialize the scene
function init() {
scene = new v3d.Scene();
camera = new v3d.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.x = - 23;
camera.position.y = 2;
camera.position.z = 24;
renderer = new v3d.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.autoClear = false;
document.body.appendChild(renderer.domElement);
const controls = new OrbitControls(camera, renderer.domElement);
controls.minDistance = 20;
controls.maxDistance = 100;
const loader = new OBJLoader();
//load the obj
loader.load('models/obj/ninja/ninjaHead_Low.obj', function(object) {
object.traverse(function(child) {
if (child.isMesh) {
bufferGeo = child.geometry;
bufferGeo.center();
const dict = {};
for (let i = 0; i < bufferGeo.attributes.position.count; i += 3) {
//create a dictionary of every position, and its neighboring positions
const array = bufferGeo.attributes.position.array;
const normArray = bufferGeo.attributes.normal.array;
const posA = new v3d.Vector3(array[3 * i], array[3 * i + 1], array[3 * i + 2]);
const posB = new v3d.Vector3(array[3 * (i + 1)], array[3 * (i + 1) + 1], array[3 * (i + 1) + 2]);
const posC = new v3d.Vector3(array[3 * (i + 2)], array[3 * (i + 2) + 1], array[3 * (i + 2) + 2]);
const normA = new v3d.Vector3(normArray[3 * i], normArray[3 * i + 1], normArray[3 * i + 2]).normalize();
const normB = new v3d.Vector3(normArray[3 * (i + 1)], normArray[3 * (i + 1) + 1], normArray[3 * (i + 1) + 2]).normalize();
const normC = new v3d.Vector3(normArray[3 * (i + 2)], normArray[3 * (i + 2) + 1], normArray[3 * (i + 2) + 2]).normalize();
const strA = posA.toArray().toString();
const strB = posB.toArray().toString();
const strC = posC.toArray().toString();
const posB_A = new v3d.Vector3().subVectors(posB, posA);
const posB_C = new v3d.Vector3().subVectors(posB, posC);
const posC_A = new v3d.Vector3().subVectors(posC, posA);
const b2a = normB.dot(posB_A.normalize());
const b2c = normB.dot(posB_C.normalize());
const c2a = normC.dot(posC_A.normalize());
const a2b = - normA.dot(posB_A.normalize());
const c2b = - normC.dot(posB_C.normalize());
const a2c = - normA.dot(posC_A.normalize());
if (dict[strA] === undefined) {
dict[strA] = {};
}
if (dict[strB] === undefined) {
dict[strB] = {};
}
if (dict[strC] === undefined) {
dict[strC] = {};
}
dict[strA][strB] = a2b;
dict[strA][strC] = a2c;
dict[strB][strA] = b2a;
dict[strB][strC] = b2c;
dict[strC][strA] = c2a;
dict[strC][strB] = c2b;
}
let curvatureDict = {};
let min = 10, max = 0;
Object.keys(dict).forEach(function(key) {
curvatureDict[key] = average(dict[key]);
});
//smoothing
const smoothCurvatureDict = Object.create(curvatureDict);
Object.keys(dict).forEach(function(key) {
let count = 0;
let sum = 0;
Object.keys(dict[key]).forEach(function(key2) {
sum += smoothCurvatureDict[key2];
count ++;
});
smoothCurvatureDict[key] = sum / count;
});
curvatureDict = smoothCurvatureDict;
// fit values to 0 and 1
Object.keys(curvatureDict).forEach(function(key) {
const val = Math.abs(curvatureDict[key]);
if (val < min) min = val;
if (val > max) max = val;
});
const range = (max - min);
Object.keys(curvatureDict).forEach(function(key) {
const val = Math.abs(curvatureDict[key]);
if (curvatureDict[key] < 0) {
curvatureDict[key] = (min - val) / range;
} else {
curvatureDict[key] = (val - min) / range;
}
});
curvatureAttribute = new Float32Array(bufferGeo.attributes.position.count);
for (let i = 0; i < bufferGeo.attributes.position.count; i++) {
const array = bufferGeo.attributes.position.array;
const pos = new v3d.Vector3(array[3 * i], array[3 * i + 1], array[3 * i + 2]);
const str = pos.toArray().toString();
curvatureAttribute[i] = curvatureDict[str];
}
bufferGeo.setAttribute('curvature', new v3d.BufferAttribute(curvatureAttribute, 1));
//starting filter is to show both concave and convex
const curvatureFiltered = new Float32Array(curvatureAttribute);
filterBoth(curvatureFiltered);
const materialRaw = new v3d.ShaderMaterial({
vertexShader: document.getElementById('vertexShaderRaw').textContent,
fragmentShader: document.getElementById('fragmentShaderRaw').textContent
});
ninjaMeshRaw = new v3d.Mesh(bufferGeo, materialRaw);
}
});
scene.add(ninjaMeshRaw);
});
//init GUI
const params = {
filterConvex: function() {
const curvatureFiltered = new Float32Array(curvatureAttribute);
filterConvex(curvatureFiltered);
bufferGeo.attributes.curvature.array = curvatureFiltered;
bufferGeo.attributes.curvature.needsUpdate = true;
},
filterConcave: function() {
const curvatureFiltered = new Float32Array(curvatureAttribute);
filterConcave(curvatureFiltered);
bufferGeo.attributes.curvature.array = curvatureFiltered;
bufferGeo.attributes.curvature.needsUpdate = true;
},
filterBoth: function() {
const curvatureFiltered = new Float32Array(curvatureAttribute);
filterBoth(curvatureFiltered);
bufferGeo.attributes.curvature.array = curvatureFiltered;
bufferGeo.attributes.curvature.needsUpdate = true;
}
};
const gui = new GUI();
const topologyFolder = gui.addFolder('Topology');
topologyFolder.add(params, 'filterConvex');
topologyFolder.add(params, 'filterConcave');
topologyFolder.add(params, 'filterBoth');
topologyFolder.open();
onWindowResize();
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
}
</script>
</body>
</html>
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
HTML
1
https://gitee.com/ing/verge3d-code-examples.git
git@gitee.com:ing/verge3d-code-examples.git
ing
verge3d-code-examples
verge3d-code-examples
master

搜索帮助