【问题标题】:Angle between view vector and normal?视图矢量和法线之间的角度?
【发布时间】:2020-04-16 22:19:31
【问题描述】:

相当标准的 GLSL 问题。不幸的是,虽然我熟悉它背后的数学,但我对 webgl 级别的实现并不确定。而且着色器的调试相当棘手。

我试图在 glsl 着色器级别获取视图向量和对象法线之间的角度。我正在使用threejs,但通过它们创建自己的共享者。

这是顶点着色器的相关部分:

void main() {
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);

    vec3 nmalInWorld = normalize(normalMatrix * normal);
    vec3 camInWorld = cameraPosition;
    vec4 posInWorld = modelViewMatrix * vec4(position, 1.0);
    posInWorld /= posInWorld[3];
    angle = -dot(normalize(posInWorld - vec4(cameraPosition, 1.0)), normalize(vec4(nmalInWorld,1.0)));
    if(angle > 0.7){
      angle = 1.0;
    }else{
      angle = 0.0;
    }

我已经尝试了这种安排的几种排列方式,所以如果它不必要地复杂,我提前道歉。我确实得到了一些与我想要的非常相似的东西——它在相机视角方面肯定总是相同的,但由于某种我不明白的原因它没有居中。片段着色器只是直接将角度修补到色域。

如您所见,白点不在球体的中间,这是预期的结果。我真的不明白为什么。也许它缺少透视变换应用程序?试了一下没有成功。我不认为在这种情况下视图向量应该是相关的,无论相机的目标如何,球体都应该保持相同的颜色。

【问题讨论】:

  • 你可能会发现this article很有用
  • 是的。我真的很喜欢 webglfundamentals。

标签: three.js glsl webgl shader vertex-shader


【解决方案1】:

posInWorldvec4(cameraPosition, 1.0)vec4(nmalInWorld,1.0)Homogeneous coordinates

2 个Cartesian Unit vectorsDot product 等于向量之间夹角的Cosine

“视图”向量是从顶点位置到相机位置的归一化笛卡尔向量。当顶点位置被modelViewMatrix 转换时,结果是视图空间中的位置。相机的视空间位置是(0, 0, 0),因为视空间的原点就是相机的位置:

vec4 posInView = modelViewMatrix * vec4(position, 1.0);
posInView /= posInView[3];

vec3 VinView = normalize(-posInView.xyz); // (0, 0, 0) - posInView

normalMatrix 将向量从模型空间转换到视图空间:

vecr NinView = normalize(normalMatrix * normal);

VinViewNinView 都是视图空间中的向量。前者从顶点指向相机,后者是曲面在顶点坐标处的法向量。
两个向量夹角的余弦可以通过点积得到:

float NdotV = dot(NinView, VinView);

【讨论】:

  • 谢谢。我误解了 modelViewMatrix 背后的功能,我假设它转移到了世界坐标。一切都按预期工作。此解决方案效果很好。
猜你喜欢
  • 2014-05-10
  • 2018-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多