three.js 地形法向量生成

three.js 地形法向量生成

three.js 地形法向量生成
• 发表于 3年前
• 阅读 44
• 收藏 0
• 评论 0

three.js 的PlaneGeometry 自带有法向量， 法向量分为两种 即 平面法向量 和 平面每个定点法向量。

材质编号_当前材质几何体组编号  作为几何体组的标识。

接着将相应的平面块 压入到对应的几何体组中。

控制每个几何体组的定点个数 小于 65535.

geometry.geometryGroups----->map形式访问几何体组

geometry.geometryGroupList-----> 数组形式访问几何体组

``````var pmat = new THREE.ShaderMaterial({
uniforms:{
light:{type:'v3', value:new THREE.Vector3()},
maxHeight:{type:'f', value:0},
minHeight:{type:'f', value:1},
},
attributes:{
displacement: {type:'f', value:[]},
vexNormal:{type:'v3', value:[]},
},

});``````

``````var v1 = new THREE.Vector3();
var v2 = new THREE.Vector3();

var distX = 2*3/(WIDTH-1);
var distY = 2*3/(HEIGHT-1);

var vexNormal = pmat.attributes.vexNormal.value;
var vertices = pmesh.geometry.vertices;

var lmat = new THREE.LineBasicMaterial({color:0xff0000});
for(var i = 0; i < vertices.length; i++)
{
var row = ~~(i/WIDTH);
var col = i%WIDTH;

var left = (col-1+WIDTH)%WIDTH;
var right = (col+1)%WIDTH;
var up = (row-1+HEIGHT)%HEIGHT;
var bottom = (row+1)%HEIGHT;

var l = value[row*WIDTH+left];
var r = value[row*WIDTH+right];
v1.set(distX, 0, r-l);

var u = value[up*WIDTH+col];
var b = value[bottom*WIDTH+col];
v2.set(0, distY, b-u);

v1.crossSelf(v2.clone()).normalize();

vexNormal.push(v1.clone());

var lgeo = new THREE.Geometry();
lgeo.vertices.push(new THREE.Vertex());
lgeo.vertices.push(new THREE.Vertex(v1.clone()));

var line = new THREE.Line(lgeo, lmat);
line.position.set(vertices[i].position.x, vertices[i].position.y, value[i]);

}``````

normalWorldMatrix 是 要的矩阵。

``````var pmat = new THREE.ShaderMaterial({
uniforms:{
light:{type:'v3', value:new THREE.Vector3()},
normalWorldMatrix:{type:'m4', value:new THREE.Matrix4()},
maxHeight:{type:'f', value:0},
minHeight:{type:'f', value:1},
},
attributes:{
displacement: {type:'f', value:[]},
vexNormal:{type:'v3', value:[]},
},
//wireframe:true,

});``````

normalWorldmatrix.value.getInverse(pmesh.matrixWorld).transpose();

nor = (normalWorldMatrix * vec4(vexNormal, 0)).xyz

lightDir = light-pos;

diffuse = max(dot(normalize(lightDir), nor), 0); 作为系数影响亮度。

×