processing / processing/p5.js

On Latest Version of Safari SetUniform Doesn't Update in Draw Function

Open
#7,070 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Area:Core Area:WebGL Bug
Dominant language
JavaScript
Stars
24k
Forks
3.8k
Avg merge
3d 16h
Merged PRs (30d)
25

Description

Most appropriate sub-area of p5.js?
  • Accessibility
  • Color
  • Core/Environment/Rendering
  • Data
  • DOM
  • Events
  • Image
  • IO
  • Math
  • Typography
  • Utilities
  • WebGL
  • Build process
  • Unit testing
  • Internationalization
  • Friendly errors
  • Other (specify if possible)
p5.js version

v1.9.3

Web browser and version

Safari 17.4.1

Operating system

MacOSX

Steps to reproduce this
Steps:
  1. Below I have copy and pasted the code for 6 files of the test project.
  2. You just have to copy and paste them into new files with the correct extensions
  3. Put them all in the same folder and add the latest version of p5.js
  4. Run the project using a local server
  5. On windows you should see a flashing white on the screen but on the latest version of Safari on MacOSX it wont work
  6. That is due to the setUniform not updating the shader beyond the first call.
  7. Imporant, the test code works on the latest version of safari if we use version 1.5 of p5js so something must have changed between that version and the current p5js version related to setUniform. So far I haven't been able to find it in the code though.
Snippet:

// Paste your code here :)

//////////////////////////////////////////////////////////////////////////
vs.vert
///////////////////////////////////////////////////////////////////////////////

#ifdef GL_ES
precision mediump float;
#endif

attribute vec3 aPosition;
attribute vec2 aTexCoord;
varying vec2 vTexCoord;

void main() {
	vTexCoord = aTexCoord;
  vec4 positionVec4 = vec4(aPosition, 1.0);

  // scale the rect by two, and move it to the center of the screen
  positionVec4.xy = positionVec4.xy * 2.0 - 1.0;

  gl_Position = positionVec4;

}


//////////////////////////////////////////////////////////////////////////
fs.frag
////////////////////////////////////////////////////////////////////////////

precision mediump float;

uniform vec3 myColor;
varying vec2 vTexCoord;

uniform vec2 iResolution;
uniform float iTime;
uniform sampler2D iChannel0;
uniform sampler2D iChannel1;

uniform vec3 iMouse;
uniform vec2 prevMouse;
uniform vec4 paintColor;
//helpful function to match shadertoy
#define texture texture2D 
#define fragColor gl_FragColor

#define fragCoord (vec2(vTexCoord.x,1.-vTexCoord.y)*iResolution)

vec2 mouse;

const float speed = .01;
const float scale = 0.8;
const float falloff = 2.;
//END OF NOISE STUFF
void main() {
  // coordinates
  fragColor = vec4(0.0);
    vec2 uv = (fragCoord.xy - iResolution.xy / 2.)/iResolution.y;
    mouse = (iMouse.xy - iResolution.xy*0.5)/iResolution.y;
    //You have to do the same thing to previous mouse
    //as you do to mouse!
   float x = fract(iTime*0.01);
  fragColor = vec4(vec3(x), 1);
}


//////////////////////////////////////////////////////////////////////////////////////////
vs2.vert
//////////////////////////////////////////////////////////////////////////////////////////

#ifdef GL_ES
precision mediump float;
#endif

attribute vec3 aPosition;
attribute vec2 aTexCoord;
varying vec2 vTexCoord;

void main() {
	vTexCoord = aTexCoord;
  vec4 positionVec4 = vec4(aPosition, 1.0);

  // scale the rect by two, and move it to the center of the screen
  positionVec4.xy = positionVec4.xy * 2.0 - 1.0;

  gl_Position = positionVec4;

}


//////////////////////////////////////////////////////////////////////////////////////////
fs2.frag
//////////////////////////////////////////////////////////////////////////////////////////

precision mediump float;

uniform vec3 myColor;
varying vec2 vTexCoord;

uniform vec2 iResolution;
uniform float iTime;
uniform sampler2D iChannel0;

#define texture texture2D
#define fragColor gl_FragColor
#define fragCoord (vTexCoord*iResolution)
#define T(uv) texture(iChannel0, uv).a//needs to be a now

void main() {

   vec3 color = vec3(.0);
    // coordinates
    vec2 uv = fragCoord.xy / iResolution.xy;
   // vec3 dither = texture(iChannel1, fragCoord.xy / 1024.).rgb;
    

   // fragColor = vec4(color, 1);
   fragColor = vec4(texture(iChannel0,vTexCoord).rgb, 1);

}


///////////////////////////////////////////////////////////////////////////////////////////
sketch.js
/////////////////////////////////////////////////////////////////////////////////////////

//this variable will hold our shader object
let shader1;
let shader2;
let buffer;
let feedbackBuffer;
let imgBuffer;
let img;
let picker; 
let mousePressed;
function preload(){
  // a shader is composed of two parts, a vertex shader, and a fragment shader
  // the vertex shader prepares the vertices and geometry to be drawn
  // the fragment shader renders the actual pixel colors
  // loadShader() is asynchronous so it needs to be in preload
  // loadShader() first takes the filename of a vertex shader, and then a frag shader
  // these file types are usually .vert and .frag, but you can actually use anything. .glsl is another common one
  shader1 = loadShader('vs.vert', 'fs.frag');
  shader2 = loadShader('vs2.vert', 'fs2.frag');
 // img = loadImage('assets/noiseTextureColor.png');
}

function setup() {
  // shaders require WEBGL mode to work
  createCanvas(windowWidth, windowHeight, WEBGL);
  buffer = createGraphics(windowWidth, windowHeight, WEBGL);
  imgBuffer = createGraphics(windowWidth, windowHeight, WEBGL);
  feedbackBuffer = createGraphics(windowWidth, windowHeight);
  picker = createColorPicker('deeppink');
  picker.position(width-220,height-120);
   picker.size( 200, 100);
   picker.mouseOver(disablePaint);
   picker.draggable();
  noStroke();
}

function draw() {  
  //"shader"without any prefix is the main image's shader
  width = windowWidth;
  height = windowHeight;

  
  if (mouseIsPressed == true ) {
    mousePressed = 1.;
   }
   else{
	mousePressed = 0.;
   }   

  
  let c  = picker.color().levels;
  buffer.clear();
  buffer.shader(shader1);
  
  shader1.setUniform('iResolution', [width, height]);
  shader1.setUniform('iTime', frameCount);
  shader1.setUniform('iChannel0', feedbackBuffer);
  shader1.setUniform('paintColor', c);


  shader1.setUniform('iMouse', [mouseX,height-mouseY,mousePressed]);
  shader1.setUniform('prevMouse', [pmouseX,height-pmouseY]);
  buffer.rect(0,0,width, height);
  
 feedbackBuffer.clear();
 feedbackBuffer.image(buffer, 0,0,width, height);

  shader(shader2);
  shader2.setUniform('iResolution', [width, height]);
  shader2.setUniform('iTime', frameCount * 0.05);
  shader2.setUniform('iChannel0', buffer); 

  rect(0,0,width, height);
  
}

function windowResized(){
  resizeCanvas(windowWidth, windowHeight);
}

function disablePaint(){
  mousePressed = 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////
index.html
/////////////////////////////////////////////////////////////////////////////////////////////////////////
<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- Include p5.js library -->
    <script src="p5.js"></script>
	<script src="sketch.js"></script>
    <meta charset="utf-8" />
  </head>
  <body>
    
  </body>
</html>

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue with index.html and sketch.js using vs.vert, fs.frag, vs2.vert, and fs2.frag in Safari 17.4.1, then compare p5.js 1.5 with v1.9.3. Start by tracing the shader1.setUniform calls in sketch.js and identify why updates stop after the first call. Done means the provided example updates uniformly in the current version on Safari.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
computer-graphics, web-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.