15

How do you pass by reference in a GLSL shader?

bobobobo
  • 64,917
  • 62
  • 258
  • 363
  • 1
    What does "by reference" mean here? Is the goal to pass "without making a copy so that future changes - to the shared object - will affect the shader"? –  Nov 29 '12 at 19:55
  • Great comment. What I mean is exactly the meaning in C++ or any other programming language -- __a local copy of the passed parameter is not made__. – bobobobo Nov 29 '12 at 21:15

2 Answers2

14

You can mark an attribute as inout in the function signature, and that will make the attribute effectively "pass by reference"

For example,

void doSomething( vec3 trans, inout mat4 mat )

Here mat is "passed by reference", trans is passed by value.

mat must be writeable (ie not a uniform attribute)

bobobobo
  • 64,917
  • 62
  • 258
  • 363
  • 1
    Is it possible to use `inout` on elements/swizzles of compound types? e.g. `void swap(inout float a, inout float b); vec3 foo, bar; swap(foo.x, bar.x)` – AkiRoss Jul 29 '14 at 09:10
  • 10
    It's a lie. "inout" function parameter qualifier will result in two "deep copies" of your data. Read documentation. https://www.opengl.org/wiki/Core_Language_(GLSL)#Functions As I can see there is only one way to get true "references" in glsl, and this is allowed by this extension: https://www.opengl.org/registry/specs/NV/shader_buffer_load.txt – Crabonog Aug 05 '16 at 15:02
  • 11
    For anyone coming across this answer in the future, **IT IS COMPLETELY WRONG**. GLSL does not give you control over how function parameters are passed "under the hood". Instead, the compiler decides **everything**, and will (hopefully) not actually copy things usually. See [this answer](https://stackoverflow.com/a/28577878) for more detail. – AnOccasionalCashew Feb 10 '18 at 05:24
  • I believe for a struct you have to pass as `inout` – Aditya Singh Rathore Nov 20 '20 at 18:32
2

All parameters are “pass by value” by default. You can change this behavior using these “parameter qualifiers”:

in: “pass by value”; if the parameter’s value is changed in the function, the actual parameter from the calling statement is unchanged.

out: “pass by reference”; the parameter is not initialized when the function is called; any changes in the parameter’s value changes the actual parameter from the calling statement.

inout: the parameter’s value is initialized by the calling statement and any changes made by the function change the actual parameter from the calling statement.

So if you don't want to make a copy, you should use out