mee*_*tar 7 shader opengl-es glsl webgl three.js
简短版本:我正在操纵顶点着色器中顶点的位置,但是当我根据顶点计算法线时position,法线是根据原始顶点位置计算的.顶点着色器不应该知道新顶点的位置吗?
长版:我正在基于three.js normalmap着色器在three.js R.58中编写自定义着色器.我将平面纹理(0.5,0.5,1.0淡紫色)作为a传递给着色器tNormal,然后planeGeometry在顶点着色器中设置顶点的位置以将其弯曲成球体.
这是顶点着色器中计算法线的位:
vec3 newPosition = mix( position, goalPosition, mixAmount );
vec4 mvPosition = modelViewMatrix * vec4( newPosition, 1.0 );
vViewPosition = -mvPosition.xyz;
vNormal = normalize( normalMatrix * normal );
//tangent and binormal vectors
vTangent = normalize( normalMatrix * tangent.xyz );
vBinormal = cross( vNormal, vTangent ) * tangent.w;
vBinormal = normalize( vBinormal );
Run Code Online (Sandbox Code Playgroud)
此代码适用于默认的sphereGeometry和planeGeometry.然而,当我将一个平面变形为一个球体时,阴影不能按预期工作 - 片段着色器似乎认为球体仍然是一个平面 - 或者其他东西.
这是带有pointLight的球体,显示了扭曲的镜面高光:

演示:http://meetar.github.io/planebending/plane_bending.html
并且只有在原始平面面向点光源时才会显示 - 在其他旋转时,无论相机在哪里,球体都是黑色的,这表明平面法线仍然以某种方式被计算,就好像顶点没有被重新定位一样.
我设置geometry.dynamic = true以及geometry.normalsNeedUpdate和geometry.tangentsNeedUpdate,和我打电话geometry.computeTangents(),但似乎没有任何工作.
我的印象是在GLSL中,用于计算法线的场景组件(例如normalMatrix和tangent)考虑了顶点着色器的任何顶点操作.我错过了什么?这是针对three.js的特定内容吗?
编辑:
检查控制台,我看到变形平面中的每个面仍然具有(0,0,1)的世界空间法线,就像它处于未变形状态时一样,而不是sphereGeometry实例,其法线根据其方向而变化.
这是另一个演示:这两个对象具有相同的材料.左边是SphereGeometry,右边是变形的PlaneGeometry.当平面变形时,法线似乎不会更新以反映面部的新方向,并且镜面反射不会正确显示.

演示:http://meetar.github.io/planebending/plane_bending_06.html
简短版:你不能!
长版:即使顶点着色器正在移动顶点,它只知道当前顶点的更新位置- 要计算新的面法线,它必须知道所有邻居顶点的更新位置,到目前为止,WebGL没有不允许这样.
虽然顶点着色器确实计算法线,但它们都基于原始法线,它们与原始顶点位置一起传递到顶点着色器.这些计算大多只是片段着色器所需的标准正常相关事物,例如光的位置,变换等,并且它们都假设顶点将在对象空间中相对于彼此保持静止.
使用CPU更新法线并将它们传递给顶点着色器相对容易,但如果必须在顶点着色器中进行,则有一些偷偷摸摸的方法可以伪造它,例如使用凹凸贴图 ; 如果基于任何类型的参数计算移动顶点,您可以动态生成一些邻居并检查它们之间的正常,这肯定是作弊.
资料来源:
| 归档时间: |
|
| 查看次数: |
5250 次 |
| 最近记录: |