为什么空函数会改变结果?

问题描述 投票:0回答:1

我有这个 glsl 顶点着色器:

layout(location = 0) in vec4 a_position;
layout(location = 1) in vec4 a_color;

layout(location = 0) out vec4 v_color;

struct VertexMaterial
{
    vec4 color;
};

void InitMaterial(out VertexMaterial material)
{
    material.color = a_color;
}

void ExecuteVertexMaterial(out VertexMaterial material)
{
}

void main()
{
    VertexMaterial material;
    InitMaterial(material);

    {
        ExecuteVertexMaterial(material);
        v_color = material.color;
    }

    gl_Position = a_position;
}

ExecuteVertexMaterial
函数是空的,所以我希望
out VertexMaterial material
不会被改变。

但实际上,颜色开始闪烁

https://youtu.be/GqRE0B0Nw50

当这个函数被注释掉时:

void main()
{
    VertexMaterial material;
    InitMaterial(material);

    {
        //ExecuteVertexMaterial(material);
        v_color = material.color;
    }

    gl_Position = a_position;
}

或者执行

InitMaterial
函数:

void ExecuteVertexMaterial(out VertexMaterial material)
{
    InitMaterial(material);
}

它按预期工作:

这是为什么呢?有没有办法让

ExecuteVertexMaterial()
函数为空?

glsl
1个回答
0
投票

根据这篇文章

声明为

out
的参数不会由调用者初始化其值。函数会修改参数,函数执行完成后,会将参数的值复制到用户调用函数时指定的变量中。请注意,被调用函数开始时参数的初始值是未定义的,就像简单地创建了一个局部变量一样。

这意味着,如果将

material
传递给函数
ExecuteVertexMaterial(out VertexMaterial material)
,则
material
的初始值为
undefined
。该函数的作用是正确设置该输出参数。就你而言,它不会这样做。所以它会用
material
覆盖
undefined
的值。

本文还解释了

in
inout
关键字。

声明为

in
的参数意味着在调用函数时,赋予该参数的值将被复制到该参数中。然后,该函数可能会根据需要修改该参数,但这些更改不会影响调用代码。

inout
声明结合了两者。参数的值将由用户提供的值初始化,并输出其最终值

总之,您应该将参数声明为

inout
,以将已定义的值传递给函数并能够另外更改它。如果您不想通过引用更改它,则将这些参数声明为
in
就足够了。

© www.soinside.com 2019 - 2024. All rights reserved.