在给定方向上缩放部分网格
Scaling part of mesh in a given direction
我有很多立方体(例如 100 个),它们都是同一个网格的一部分,在顶点着色器中,我想沿给定的轴缩放每个立方体,所以它的顶部被移动并且立方体被拉伸像这样:
每个立方体都有一个ID
,每个顶点都有一个对应的ID
,所以每个顶点都知道它是哪个立方体的一部分。统一的 vec3 数组标准化 cubeUps
(立方体应该扩展的方向)和统一的 vec3 数组 cubeOrigins
(每个立方体的底部)也被传递给着色器。这些统一数组的索引与立方体的 ID
相匹配。
正确知道 cubeOrigins
个立方体被放置在每个立方体底部的中心,就像这里的白点,因为我认为这是需要的,但不确定:
我可以像这样很容易地沿着给定的 normal
平移立方体:
layout (location = 0) in vec3 vertexPos;
layout (location = 1) in vec3 vertexNor;
layout (location = 2) in float vertexCubeId;
uniform mat4 mvp;
uniform vec3 cubeUps[100];
uniform vec3 cubeOrigins[100];
void main()
{
int cubeIndex = int(vertexCubeId);
vec3 cubeUp = cubeUps[cubeIndex];
vec3 cubeOrigin = cubeOrigins[cubeIndex];
vec3 transformedPos = vertexPos;
transformedPos.x += cubeUp.x;
transformedPos.y += cubeUp.y;
transformedPos.z += cubeUp.z;
gl_Position = mvp * vec4(transformedPos, 1.0);
}
但我的缩放计划没有奏效。我认为我需要做的是:
- 从顶点中减去原点,为
缩放。
- 以某种方式沿 'cubeUp' 矢量进行缩放。
- 将原点添加到顶点以再次远离底边。
像这样:
...
float scaleFactor = 1.5f;
vec3 scale = cubeUp * scaleFactor;
transformedPos.x -= cubeOrigin.x;
transformedPos.y -= cubeOrigin.y;
transformedPos.z -= cubeOrigin.z;
transformedPos.x *= scale.x;
transformedPos.y *= scale.y;
transformedPos.z *= scale.z;
transformedPos.x += cubeOrigin.x;
transformedPos.y += cubeOrigin.y;
transformedPos.z += cubeOrigin.z;
gl_Position = mvp * vec4(transformedPos, 1.0);
...
但这既会将立方体移动到不需要的位置,也不会正确缩放它们。
我是否需要在应用比例之前旋转顶点坐标,以便正确使用原点?
如何从给定的 cubeUp
向量获得用于缩放的正确值?
在cubeUp
方向取顶点(减去原点后)的点积,然后缩放,加到顶点位置。这将确保顶点仅在 cubeUp
方向移动。像这样:
float scaleFactor = 1.5f;
transformedPos.x -= cubeOrigin.x;
transformedPos.y -= cubeOrigin.y;
transformedPos.z -= cubeOrigin.z;
float dotProduct = dot(cubeUp, transformedPos);
dotProduct *= (scaleFactor - 1.0f); // or just set scaleFactor
// to 0.5f in the first place
vec3 offset = cubeUp * dotProduct;
transformedPos.x += offset.x;
transformedPos.y += offset.y;
transformedPos.z += offset.z;
transformedPos.x += cubeOrigin.x;
transformedPos.y += cubeOrigin.y;
transformedPos.z += cubeOrigin.z;
为了形象化为什么简单地乘以比例向量不起作用,想象一下由 cubeOrigin
和 cubeUp
定义的平面上的顶点(即立方体的底面)。根本不应该动。然而,每个角顶点都将有一个非零的 transformedPos
向量,这意味着乘以 scale
后的值将不相同,除了 cubeUp
的特殊情况] 正好沿着 X Y 或 Z 轴。
您需要专门乘以 transformedPos
向量中 cubeUp
方向的那部分,它等于 dot(cubeUp, transformedPos) * cubeUp
。与其减去该部分然后乘以 1.5 然后重新相加,不如乘以 0.5 并相加更有效。
我有很多立方体(例如 100 个),它们都是同一个网格的一部分,在顶点着色器中,我想沿给定的轴缩放每个立方体,所以它的顶部被移动并且立方体被拉伸像这样:
每个立方体都有一个ID
,每个顶点都有一个对应的ID
,所以每个顶点都知道它是哪个立方体的一部分。统一的 vec3 数组标准化 cubeUps
(立方体应该扩展的方向)和统一的 vec3 数组 cubeOrigins
(每个立方体的底部)也被传递给着色器。这些统一数组的索引与立方体的 ID
相匹配。
正确知道 cubeOrigins
个立方体被放置在每个立方体底部的中心,就像这里的白点,因为我认为这是需要的,但不确定:
我可以像这样很容易地沿着给定的 normal
平移立方体:
layout (location = 0) in vec3 vertexPos;
layout (location = 1) in vec3 vertexNor;
layout (location = 2) in float vertexCubeId;
uniform mat4 mvp;
uniform vec3 cubeUps[100];
uniform vec3 cubeOrigins[100];
void main()
{
int cubeIndex = int(vertexCubeId);
vec3 cubeUp = cubeUps[cubeIndex];
vec3 cubeOrigin = cubeOrigins[cubeIndex];
vec3 transformedPos = vertexPos;
transformedPos.x += cubeUp.x;
transformedPos.y += cubeUp.y;
transformedPos.z += cubeUp.z;
gl_Position = mvp * vec4(transformedPos, 1.0);
}
但我的缩放计划没有奏效。我认为我需要做的是:
- 从顶点中减去原点,为 缩放。
- 以某种方式沿 'cubeUp' 矢量进行缩放。
- 将原点添加到顶点以再次远离底边。
像这样:
...
float scaleFactor = 1.5f;
vec3 scale = cubeUp * scaleFactor;
transformedPos.x -= cubeOrigin.x;
transformedPos.y -= cubeOrigin.y;
transformedPos.z -= cubeOrigin.z;
transformedPos.x *= scale.x;
transformedPos.y *= scale.y;
transformedPos.z *= scale.z;
transformedPos.x += cubeOrigin.x;
transformedPos.y += cubeOrigin.y;
transformedPos.z += cubeOrigin.z;
gl_Position = mvp * vec4(transformedPos, 1.0);
...
但这既会将立方体移动到不需要的位置,也不会正确缩放它们。
我是否需要在应用比例之前旋转顶点坐标,以便正确使用原点?
如何从给定的 cubeUp
向量获得用于缩放的正确值?
在cubeUp
方向取顶点(减去原点后)的点积,然后缩放,加到顶点位置。这将确保顶点仅在 cubeUp
方向移动。像这样:
float scaleFactor = 1.5f;
transformedPos.x -= cubeOrigin.x;
transformedPos.y -= cubeOrigin.y;
transformedPos.z -= cubeOrigin.z;
float dotProduct = dot(cubeUp, transformedPos);
dotProduct *= (scaleFactor - 1.0f); // or just set scaleFactor
// to 0.5f in the first place
vec3 offset = cubeUp * dotProduct;
transformedPos.x += offset.x;
transformedPos.y += offset.y;
transformedPos.z += offset.z;
transformedPos.x += cubeOrigin.x;
transformedPos.y += cubeOrigin.y;
transformedPos.z += cubeOrigin.z;
为了形象化为什么简单地乘以比例向量不起作用,想象一下由 cubeOrigin
和 cubeUp
定义的平面上的顶点(即立方体的底面)。根本不应该动。然而,每个角顶点都将有一个非零的 transformedPos
向量,这意味着乘以 scale
后的值将不相同,除了 cubeUp
的特殊情况] 正好沿着 X Y 或 Z 轴。
您需要专门乘以 transformedPos
向量中 cubeUp
方向的那部分,它等于 dot(cubeUp, transformedPos) * cubeUp
。与其减去该部分然后乘以 1.5 然后重新相加,不如乘以 0.5 并相加更有效。