顶点相对于法线的位置 [英] Vertex position relative to normal
问题描述
在表面着色器中,给定世界的上轴(以及其他轴),世界空间位置和世界空间中的法线,我们如何将世界空间位置旋转到正常吗?
也就是说,给定一个向上矢量和一个非正交的目标向上矢量,我们如何通过旋转其向上矢量来变换位置?
我需要这个,所以我可以使顶点位置仅受对象旋转矩阵的影响,而我没有可以访问.
这是我想做什么的图形化可视化显示:
- Up是世界向上的载体
- 目标是世界空间法线
- Pos是任意的
该图是二维的,但我需要为3D空间解决此问题.
似乎您正尝试将 pos 旋转相同的旋转,从而将向上转换为 new_up .
使用找到的旋转矩阵 这是假设 new_up 已标准化. 如果正常目标向上"是一个常数,则 R 的计算只能(并且应该)每帧进行一次.我建议在CPU端执行此操作,并将其作为变量传递到着色器中.计算每个顶点/片段的成本很高,请考虑您的实际需求. 如果您的 pos 是一个vector-4,只需对前三个元素执行上述操作,则第四个元素可以保持不变(在此情况下,这实际上并不意味着任何东西)./p>
我不在可以运行着色器代码的机器上,因此,如果我在以上操作中遇到语法错误,请原谅我. In a surface shader, given the world's up axis (and the others too), a world space position and a normal in world space, how can we rotate the worldspace position into the space of the normal? That is, given a up vector and a non-orthogonal target-up vector, how can we transform the position by rotating its up vector? I need this so I can get the vertex position only affected by the object's rotation matrix, which I don't have access to. Here's a graphical visualization of what I want to do: The diagram is bidimensional, but I need to solve this for a 3D space. Looks like you're trying to rotate pos by the same rotation that would transform up to new_up. Using the rotation matrix found here, we can rotate pos using the following code. This will work either in the surface function or a supplementary vertex function, depending on your application: This is assuming that new_up is normalized. If the "target up normal" is a constant, the calculation of R could (and should) only happen once per frame. I'd recommend doing it on the CPU side and passing it into the shader as a variable. Calculating it for every vertex/fragment is costly, consider what it is you actually need. If your pos is a vector-4, just do the above with the first three elements, the fourth element can remain unchanged (it doesn't really mean anything in this context anyway). I'm away from a machine where I can run shader code, so if I made any syntactical mistakes in the above, please forgive me. 这篇关于顶点相对于法线的位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!// 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);
// 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);