Opengl 按给定方向缩放网格的一部分

Opengl 按给定方向缩放网格的一部分,opengl,math,glsl,Opengl,Math,Glsl,我有很多立方体(ex 100),它们都是同一个网格的一部分,在顶点着色器中,我想沿给定轴缩放每个立方体,因此它的顶部移动,立方体拉伸如下: 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]; unifor

我有很多立方体(ex 100),它们都是同一个网格的一部分,在顶点着色器中,我想沿给定轴缩放每个立方体,因此它的顶部移动,立方体拉伸如下:

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);
}
...

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);

...
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;

每个立方体都有一个
ID
,每个顶点都有一个相应的
ID
,因此每个顶点都知道它是哪个立方体的一部分。一个统一的vec3规格化立方体数组(立方体应扩展的方向)和一个统一的vec3立方体数组(每个立方体的底部)也传递给着色器。这些统一数组的索引与多维数据集的
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);
}
...

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);

...
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;
但是我的缩放计划没有成功。我认为我需要做的是:

  • 从顶点减去原点,以使用顶点的公共基 缩放
  • 以某种方式沿“cubeUp”向量进行缩放
  • 将原点添加到顶点以再次远离基准
  • 大概是这样的:

    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);
    }
    
    ...
    
    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);
    
    ...
    
    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;
    
    但这会将立方体移动到不需要的位置,并且无法正确缩放它们

    我是否需要在应用比例之前旋转顶点坐标,以便正确使用原点


    如何从给定的
    cubeUp
    向量获得用于缩放的正确值?

    cubeUp
    方向上取顶点的点积(减去原点后),然后缩放并添加到顶点位置。这将确保顶点仅沿
    cubeUp
    的方向移动。大概是这样的:

    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);
    }
    
    ...
    
    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);
    
    ...
    
    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再相加,效率更高。

    vec3 cubeUp=cubeUps[popupIndex];这应该是vec3 cubeUp=cubeUps[cubeIndex]?(和cubeOrigin一样)是的,你是对的,我现在就编辑它。感谢您的回答,我一到家就会查看解决方案:)