Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

glslify how to share a struct between modules

I am using https://github.com/glslify/glslify to share code between glsl shaders.

I have a vert shader that is trying to include a module at the top the vert has:

#pragma glslify: JointAndPalette = require('./JointAndPalette.glsl');
#pragma glslify: decodeJointAndPalette = require('./decodeJointAndPalette.glsl');

JointAndPalette jointAndPalette = decodeJointAndPalette(inputProps);

decodeJointAndPalette is also dependent on the JointAndPalette struct as its return definition

JointAndPalette looks like:

struct JointAndPalette
{
  int jointId;
  int paletteId;
};

#pragma glslify: export(JointAndPalette)

decodeJointAndPalette looks like:

JointAndPalette decodeJointAndPalette(float jointPaletteSplit) {
  // implementation

  JointAndPalette JandP;
  JandP.jointId = int(x);
  JandP.paletteId = int(y);

  return JandP;
}

#pragma glslify: export(decodeJointAndPalette)

Its not clear to me from the glslify docs how to structure this dependency

like image 405
kevzettler Avatar asked Apr 10 '19 21:04

kevzettler


1 Answers

Edit - TLDR;

glsify evaluates each file separately and if the same variable/function/struct name is encountered in multiple files, glslify assumes that the objects are local, and renames them to avoid name collisions.

This means that before an external variable/function/struct can be used in a file, the file containing that variable/function/struct must be imported by the require command.

In your particular case, this means adding the line

#pragma glslify: JointAndPalette = require('./JointAndPalette.glsl');

to the file decodeJointAndPalette.glsl, while also keeping the same require statement at the top of the vertex shader.

Original answer:

I installed and ran glslify in CLI mode as described on the github page.

npm install -g npm
glslify index.glsl

Where index.glsl is what you described as your 'vert shader'. The output is clearly confused, and glslify seems to think there are multiple definitions of JointAndPalette, and gives them a _0 and _1 suffix.

#define GLSLIFY 1
struct JointAndPalette_0
{
  int jointId;
  int paletteId;
};

JointAndPalette_1 decodeJointAndPalette(float jointPaletteSplit) {
  // implementation

  JointAndPalette_1 JandP;
  JandP.jointId = int(x);
  JandP.paletteId = int(y);

  return JandP;
}

JointAndPalette_0 jointAndPalette = decodeJointAndPalette(inputProps);

So tried to modify decodeJointAndPalette.glsl, so that it imports JointAndPalette.glsl as well.

#pragma glslify: JointAndPalette = require('./JointAndPalette.glsl');
JointAndPalette decodeJointAndPalette(float jointPaletteSplit) {
  // implementation

  JointAndPalette JandP;
  JandP.jointId = int(x);
  JandP.paletteId = int(y);

  return JandP;
}

#pragma glslify: export(decodeJointAndPalette)

Now the output from glslify index.glsl using the modified decodeJointAndPalette.glsl does no longer include the _0 and _1 suffixes.

#define GLSLIFY 1
struct JointAndPalette
{
  int jointId;
  int paletteId;
};

JointAndPalette decodeJointAndPalette(float jointPaletteSplit) {
  // implementation

  JointAndPalette JandP;
  JandP.jointId = int(x);
  JandP.paletteId = int(y);

  return JandP;
}

JointAndPalette jointAndPalette = decodeJointAndPalette(inputProps);

This looks correct to me. And the logic seems to be that glsilify assumes declarations of the same name in different compile units are supposed to be unique entities, and as such renames them in the combined output, not to cause a name clash.

like image 138
visibleman Avatar answered Oct 21 '22 02:10

visibleman