首页 > 解决方案 > 视图矢量和法线之间的角度?

问题描述

而是标准的 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;
    }

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

在此处输入图像描述

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

标签: three.jsglslwebglshadervertex-shader

解决方案


posInWorld,vec4(cameraPosition, 1.0)vec4(nmalInWorld,1.0)齐次坐标

2 个笛卡尔单位向量点积等于向量之间夹角的余弦值。

“视图”向量是从顶点位置到相机位置的归一化笛卡尔向量。当顶点位置由 变换时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);

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

float NdotV = dot(NinView, VinView);

推荐阅读