unity-game-engine - 顶点相对于法线的位置

标签 unity-game-engine transform hlsl cg geometry-surface

在表面着色器中,给定世界的上轴(以及其他轴)、世界空间位置和世界空间中的法线,我们如何将世界空间位置旋转到世界空间的空间中正常吗?

也就是说,给定一个向上向量和一个非正交的目标向上向量,我们如何通过旋转其向上向量来变换位置?

我需要这个,以便我可以获得仅受对象旋转矩阵影响的顶点位置,而我无法访问

这是我想要做的事情的图形可视化:

  • Up 是世界向上向量
  • 目标是世界空间法线
  • Pos 是任意的

该图是二维的,但我需要在 3D 空间中解决这个问题。

vector diagram

最佳答案

看起来您正在尝试以将 up 转换为 new_up 的相同旋转方式来旋转 pos

使用旋转矩阵发现here ,我们可以使用以下代码旋转pos。这将在曲面函数或补充顶点函数中起作用,具体取决于您的应用程序:

// Our 3 vectors
float3 pos;
float3 new_up;
float3 up = float3(0,1,0);

// Build the rotation matrix using notation from the link above
float3 v = cross(up, new_up);
float s = length(v);  // Sine of the angle
float c = dot(up, new_up); // Cosine of the angle
float3x3 VX = float3x3(
    0, -1 * v.z, v.y,
    v.z, 0, -1 * v.x,
    -1 * v.y, v.x, 0
); // This is the skew-symmetric cross-product matrix of v
float3x3 I = float3x3(
    1, 0, 0,
    0, 1, 0,
    0, 0, 1
); // The identity matrix
float3x3 R = I + VX + mul(VX, VX) * (1 - c)/pow(s,2) // The rotation matrix! YAY!

// Finally we rotate
float3 new_pos = mul(R, pos);

这是假设 new_up 已标准化。

如果“目标正常”是一个常数,则R的计算可能(并且应该)每帧只发生一次。我建议在 CPU 端执行此操作并将其作为变量传递到着色器中。计算每个顶点/片段的成本很高,请考虑您实际需要的是什么。

如果你的pos是一个向量4,只需对前三个元素执行上述操作,第四个元素就可以保持不变(无论如何,在这种情况下它实际上没有任何意义)。

我没有可以运行着色器代码的机器,所以如果我在上面犯了任何语法错误,请原谅我。

关于unity-game-engine - 顶点相对于法线的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32257338/

相关文章:

unity-game-engine - Blender 2.8 模型 Material 在导入到 unity 时显示为半透明

unity-game-engine - 如何使对象在统一首次启动时仅可见一次

Firefox 中的 CSS Transform Perspective 坏像素化

c# - 我应该如何将经过训练的 CNN 模型部署到 C# 项目?

css - 转换 - 当我将 html 内容转换为 pdf 时,旋转和缩放不起作用

java - 将java域模型从域A转换为域B

opengl - 如何强制 GLSL 分支?

linear-algebra - hlsl 点函数

c++ - HLSL 常量缓冲区中数组的意外大小

unity-game-engine - 防止物体侧翻;确保它始终面朝上或面朝下落地