Skip to content

[p5.js 2.0+ Bug Report]: struct-returning strands hooks don't work if they aren't also an input parameter #8949

Description

@davepagurek

Most appropriate sub-area of p5.js?

  • Accessibility
  • Color
  • Core/Environment/Rendering
  • Data
  • DOM
  • Events
  • Image
  • IO
  • Math
  • Typography
  • Utilities
  • WebGL
  • WebGPU
  • p5.strands
  • Build process
  • Unit testing
  • Internationalization
  • Friendly errors
  • Other (specify if possible)

p5.js version

2.3.0

Web browser and version

All

Operating system

All

Steps to reproduce this

If a hook takes in an input object (e.g. the worldInputs hook) and also return the same object, then you can modify the properties directly on the hook. Other hooks have a .set(...) method where you can specify a return value. However, .set(...) does not work with objects. This means hooks that return a struct but do not have that same struct as an input will not work.

Snippet:

function setup() {
  createCanvas(400, 400, WEBGL);
  let sh = baseMaterialShader().modify(() => {
    worldInputs.begin()
    worldInputs.set({
      position: worldInputs.position + [50, 0, 0],
      normal: worldInputs.normal,
      texCoord: worldInputs.texCoord,
      color: [0, 0, 1, 1]
    })
    worldInputs.end()
  })

  clear()
  shader(sh)
  noStroke()
  fill('red')
  sphere(100)
}

Live: https://editor.p5js.org/davepagurek/sketches/cEAjoB8TT

We get nulls in the shader, and also it looks like the property IDs are being returned as values.

p5.js says: [sketch.js, line 15] An error with message "Whoops! Something went wrong initializing the shader:
Yikes! An error occurred compiling the vertex shader: ERROR: 0:84: 'null' : undeclared identifier
ERROR: 0:84: 'position' :  field selection requires structure, vector, or interface block on left hand side
ERROR: 0:84: 'assign' : l-value required (can't modify a const)
ERROR: 0:84: '=' : dimension mismatch
ERROR: 0:84: 'assign' : cannot convert from 'const 3-component vector of float' to 'const highp float'
ERROR: 0:85: 'null' : undeclared identifier
ERROR: 0:85: 'normal' :  field selection requires structure, vector, or interface block on left hand side
ERROR: 0:85: 'assign' : l-value required (can't modify a const)
ERROR: 0:85: '=' : dimension mismatch
ERROR: 0:85: 'assign' : cannot convert from 'const 3-component vector of float' to 'const highp float'
ERROR: 0:86: 'null' : undeclared identifier
ERROR: 0:86: 'texCoord' :  field selection requires structure, vector, or interface block on left hand side
ERROR: 0:86: 'assign' : l-value required (can't modify a const)
ERROR: 0:86: '=' : dimension mismatch
ERROR: 0:86: 'assign' : cannot convert from 'const 2-component vector of float' to 'const highp float'
ERROR: 0:87: 'null' : undeclared identifier
ERROR: 0:87: 'color' :  field selection requires structure, vector, or interface block on left hand side
ERROR: 0:87: 'assign' : l-value required (can't modify a const)
ERROR: 0:87: '=' : dimension mismatch
ERROR: 0:87: 'assign' : cannot convert from 'const 4-component vector of float' to 'const highp float'
 in:

#version 300 es
#define WEBGL2
#define VERTEX_SHADER
precision highp float;
#ifdef WEBGL2

#define IN in
#define OUT out

#ifdef FRAGMENT_SHADER
out vec4 outColor;
#define OUT_COLOR outColor
#endif
#define TEXTURE texture

#else

#ifdef FRAGMENT_SHADER
#define IN varying
#else
#define IN attribute
#endif
#define OUT varying
#define TEXTURE texture2D

#ifdef FRAGMENT_SHADER
#define OUT_COLOR gl_FragColor
#endif

#endif

vec4 getTexture(in sampler2D content, vec2 coord) {
  vec4 color = TEXTURE(content, coord);
  if (color.a > 0.) color.rgb /= color.a;
  return color;
}
precision highp int;


#define AUGMENTED_HOOK_getWorldInputs



IN vec3 aPosition;
IN vec3 aNormal;
IN vec2 aTexCoord;
IN vec4 aVertexColor;

#ifdef AUGMENTED_HOOK_getWorldInputs
uniform mat4 uModelMatrix;
uniform mat4 uViewMatrix;
uniform mat3 uModelNormalMatrix;
uniform mat3 uCameraNormalMatrix;
#else
uniform mat4 uModelViewMatrix;
uniform mat3 uNormalMatrix;
#endif
uniform mat4 uProjectionMatrix;

uniform bool uUseVertexColor;
uniform vec4 uMaterialColor;

OUT vec3 vNormal;
OUT vec2 vTexCoord;
OUT vec3 vViewPosition;
OUT vec3 vAmbientColor;
OUT vec4 vColor;

struct Vertex {
  vec3 position;
  vec3 normal;
  vec2 texCoord;
  vec4 color;
};

void HOOK_beforeVertex() {}
Vertex HOOK_getObjectInputs(Vertex inputs) { return inputs; }
Vertex HOOK_getWorldInputs(Vertex _p5_param_inputs) {
  null.position = vec3(9.0000);
  null.normal = vec3(1.0000);
  null.texCoord = vec2(2.0000);
  null.color = vec4(14.0000);
  return Vertex(vec3(9.0000), vec3(1.0000), vec2(2.0000), vec4(14.0000));
}
Vertex HOOK_getCameraInputs(Vertex inputs) { return inputs; }
void HOOK_afterVertex() {}
void main(void) {
  HOOK_beforeVertex();

  Vertex inputs;
  inputs.position = aPosition;
  inputs.normal = aNormal;
  inputs.texCoord = aTexCoord;
  inputs.color = (uUseVertexColor && aVertexColor.x >= 0.0) ? aVertexColor : uMaterialColor;
#ifdef AUGMENTED_HOOK_getObjectInputs
  inputs = HOOK_getObjectInputs(inputs);
#endif

#ifdef AUGMENTED_HOOK_getWorldInputs
  inputs.position = (uModelMatrix * vec4(inputs.position, 1.)).xyz;
  inputs.normal = uModelNormalMatrix * inputs.normal;
  inputs = HOOK_getWorldInputs(inputs);
#endif

#ifdef AUGMENTED_HOOK_getWorldInputs
  // Already multiplied by the model matrix, just apply view
  inputs.position = (uViewMatrix * vec4(inputs.position, 1.)).xyz;
  inputs.normal = uCameraNormalMatrix * inputs.normal;
#else
  // Apply both at once
  inputs.position = (uModelViewMatrix * vec4(inputs.position, 1.)).xyz;
  inputs.normal = uNormalMatrix * inputs.normal;
#endif
#ifdef AUGMENTED_HOOK_getCameraInputs
  inputs = HOOK_getCameraInputs(inputs);
#endif

  // Pass varyings to fragment shader
  vViewPosition = inputs.position;
  vTexCoord = inputs.texCoord;
  vNormal = inputs.normal;
  vColor = inputs.color;

  gl_Position = uProjectionMatrix * vec4(inputs.position, 1.);
  HOOK_afterVertex();
}

Metadata

Metadata

Assignees

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
Completed

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions