有很多ActionScript Stage3D教程示例'在那里'。我感谢那些试图为我们的新手提供工作代码的人。这就是说我不相信我已经找到了一个我认为正确处理维基百科条目所概述的朗伯反射率的例子,但我不愿意补充一点,作为一个新手,也许我只是没有理解这些实现。
我认为这是任何实现的基本要求 - 它能够比较光源的方向[我故意将此讨论局限于模仿太阳的'定向光'的简单情况,而不是而不是“聚光灯”。]到要照亮的脸部法线的方向。
这就是我认为是我所看到的问题的核心 - 几乎在每种情况下,正在创建对象的几何体时执行面部法线的计算。因此,传递给着色器的法线值以本地对象空间表示。
现在我知道这个精彩论坛的工作方式,你宁愿我只提供一些示例代码,因此有人可以在CPU上使用的设置代码或GPU上使用的着色器代码中识别出特定的错误。因为我可以使用许多不同的框架找到这个问题的例子,我认为我[和我想象的许多其他人]需要的不是特定的编码解决方案,而是对实际需要什么来获得照片般逼真的渲染的一些具体说明。固定摄像机视点的简单基本情况下的物体,不移动的光源,忽略镜面反射等因素。
因此,当执行两个向量的点积时:
一个。是否应使用三个顶点的对象空间值或变换后的世界空间值计算表示要照亮的三角形面的法线的Vector3D值?
B中。如果需要世界空间值,我相信,应该在CPU或GPU上的每个渲染周期中执行动态计算的正常工作负载吗?
谢谢。
答案 0 :(得分:0)
特里我最近遇到了同样的问题,我怀疑你已经解决了它或继续前进。但我认为无论如何我都会回答这个问题。
我选择在顶点着色器中变换法线。
var vertexShader:Array = [
"m44 vt0, va0, vc0", // transform vertex positions (va0) by the world camera data (vc0)
// this result has the camera angle as part of the matrix, which is not good when calculating light
"mov op, vt0", // move the transformed vertex data (vt0) in output position (op)
"add v0, va1, vc12.xy", // add in the UV offset (va1) and the animated offset (vc12) (may be 0 for non animated), and put in v0 which holds the UV offset
"mov v1, va3", // pass texture color and brightness (va3) to the fragment shader via v1
"m44 v2, va2, vc4", // transform vertex normal, send to fragment shader
// the transformed vertices without the camera data
"m44 v3, va0, vc8", // the transformed vertices with out the camera data, works great for default AND for translated cube, rotated cube broken still
片段着色器中的
// normalize the light position
"sub ft1, v3, fc0", // subtract the light position from the transformed vertex postion
"nrm ft1.xyz, ft1", // normalize the light position (ft1)
// non flat shading
"dp3 ft2, ft1, v2", // dot the transformed normal with light direction
"sat ft2, ft2", // Clamp dot between 1 and 0, put result in ft2.
最后但并非最不重要的,您传递的数据!为了找到魔法,我做了不少尝试。
// mvp is the camera data mixed with each object world matrix
_context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, mvp, true); // aka vc0
// $model is the model to be drawn
var invmat:Matrix3D = $model.modelMatrix.clone();
invmat.transpose();
_context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 4, invmat, true); // aka vc4
var wsmat:Matrix3D = $model.worldSpaceMatrix.clone();
_context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 8, wsmat, true); // aka vc8
我希望将来可以帮助某人。