好吧,
所以我一直在网上尝试寻找使用法线和平行光(最初可以在learningwebgl.com教程中找到)进行正确渲染的方法。在learningwebgl教程中,法线都设置在一个数组中。在我的程序中,我需要能够加载wavefont OBJ文件,然后生成法线。我想知道这是否可能是我的正常生成代码,或者可能是我的着色器的问题。代码有点混乱(因为所有的顶点/法线/索引数据都在一个单独的数组中),但这里是我的普通生成代码:
for(var i=0;i<d["vertices"].length;i++)d["normals"][i] = 0;
for(var i=0;i<d["indices"].length/3;i++){
var a = [d["vertices"][d["indices"][(i*3)]], d["vertices"][d["indices"][(i*3)]+1], d["vertices"][d["indices"][(i*3)]+2]];
var b = [d["vertices"][d["indices"][(i*3)+1]], d["vertices"][d["indices"][(i*3)+1]+1], d["vertices"][d["indices"][(i*3)+1]+2]];
var c = [d["vertices"][d["indices"][(i*3)+2]], d["vertices"][d["indices"][(i*3)+2]+1], d["vertices"][d["indices"][(i*3)+2]+2]];
var e = vec3.cross(vec3.subtract(b, a), vec3.subtract(c, a));
d["normals"][d["indices"][(i*3)]] += -e[0];
d["normals"][d["indices"][(i*3)]+1] += -e[1];
d["normals"][d["indices"][(i*3)]+2] += -e[2];
d["normals"][d["indices"][(i*3)+1]] += -e[0];
d["normals"][d["indices"][(i*3)+1]+1] += -e[1];
d["normals"][d["indices"][(i*3)+1]+2] += -e[2];
d["normals"][d["indices"][(i*3)+2]] += -e[0];
d["normals"][d["indices"][(i*3)+2]+1] += -e[1];
d["normals"][d["indices"][(i*3)+2]+2] += -e[2];
}
for(var i=0;i<d["normals"].length/3;i++){
var old = vec3.normalize([d["normals"][(i*3)],d["normals"][(i*3)+1],d["normals"][(i*3)+2]]);
d["normals"][(i*3)] = old[0];
d["normals"][(i*3)+1] = old[1];
d["normals"][(i*3)+2] = old[2];
}(顶点)着色器的重要部分:
// where uNMatrix = inverse of model view matrix
vec3 transformedNormal = uNMatrix * aVertexNormal;
// vec3 - light pos
float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 1.0);
// vec3 = light color
vLightWeighting = uAmbientColor + uDirectionalColor * directionalLightWeighting; 我已经尝试了许多普通的算法,但都没有效果。我还发现,如果我不在最后标准化法线,颜色/阴影实际上会发生变化,这显然是不正确的阴影。
有关当前外观的示例(底部循环已注释),请单击此链接,从下拉列表中选择teddy,然后单击加载,然后单击“(重新)生成法线”,然后可以通过拖动鼠标围绕teddy旋转:
http://webdesignscript.net/assignment/graphics_a3/
有关着色器的详细信息,请参阅此处:
http://webdesignscript.net/assignment/graphics_a3/scripts/shaders.js
我已经坚持了好几个小时了,我开始怀疑它是否与着色器相关,但是我仍然是图形编程的新手,非常感谢大家的帮助。)
*使用的矩阵库是glMatrix
干杯,乔希
发布于 2011-09-14 10:41:51
我不能加载你的演示( model_engine.js第107行的分配大小溢出),但是我把你的着色器代码放到了我的引擎(shameless plug: check out Jax, it's really cool!)中,它工作得很好。
然后我仔细查看了你的JS代码,然后...好吧,我认为这是完全错误的。看起来您要做的第一件事就是取每个面的法线--这是一个很好的开始,但是我不明白为什么您要否定e的值。此时还应该规范化e,因为现在它只是一个任意长度的向量。不过,我不知道这是否真的重要。
你要做的下一件事是取给定顶点的所有e的和的法线。不完全正确:您需要标准化所有e的平均值,而不是总和。
最后,这是我想出来的。它在我自己的引擎上运行得很好,而且它的启动速度似乎比原来的版本快得多。(免责声明:可能仍有一些优化需要进行。我写这篇文章是为了清晰,而不是为了速度。)
var i, j, normals = {};
// calculate face normals. Note that each vertex will have a number of faces
// adjacent to it, so we accumulate their normals into an array. We'll take
// the average of them all when done.
var tmp1 = vec3.create(), tmp2 = vec3.create();
var a, b, c;
function pushNormal(index, normal) {
normals[index] = normals[index] || [];
normals[index].push(normal);
}
for (i = 0; i < d["indices"].length; i += 3) {
// get points a, b, c
var aIndex = d["indices"][i], bIndex = d["indices"][i+1], cIndex = d["indices"][i+2];
var aOffsetX = aIndex * 3, aOffsetY = aIndex * 3 + 1, aOffsetZ = aIndex * 3 + 2;
var bOffsetX = bIndex * 3, bOffsetY = bIndex * 3 + 1, bOffsetZ = bIndex * 3 + 2;
var cOffsetX = cIndex * 3, cOffsetY = cIndex * 3 + 1, cOffsetZ = cIndex * 3 + 2;
a = [d["vertices"][aOffsetX], d["vertices"][aOffsetY], d["vertices"][aOffsetZ]];
b = [d["vertices"][bOffsetX], d["vertices"][bOffsetY], d["vertices"][bOffsetZ]];
c = [d["vertices"][cOffsetX], d["vertices"][cOffsetY], d["vertices"][cOffsetZ]];
// calculate face normal
vec3.subtract(b, a, tmp1);
vec3.subtract(c, a, tmp2);
var e = vec3.normalize(vec3.cross(tmp1, tmp2, vec3.create()));
// accumulate face normal for each of a, b, c
pushNormal(a, vec3.create(e));
pushNormal(b, vec3.create(e));
pushNormal(c, vec3.create(e));
}
// now calculate normalized averages for each face normal, and store the result
for (i = 0; i < d["vertices"].length; i += 3) {
a = [d["vertices"][i], d["vertices"][i+1], d["vertices"][i+2]];
if (normals[a]) {
var avg = vec3.create();
for (j = 0; j < normals[a].length; j++) {
vec3.add(normals[a][j], avg, avg);
}
vec3.scale(avg, 1/normals[a].length);
vec3.normalize(avg);
d["normals"][i] = avg[0];
d["normals"][i+1] = avg[1];
d["normals"][i+2] = avg[2];
}
}
// sanity check
if (d["normals"].length != d["vertices"].length)
alert("ERROR "+d["normals"].length+" != "+d["vertices"].length);希望这能有所帮助!
https://stackoverflow.com/questions/6371154
复制相似问题