processing / p5.js

p5.js is a client-side JS platform that empowers artists, designers, students, and anyone to learn to code and express themselves creatively on the web. It is based on the core principles of Processing. http://twitter.com/p5xjs —
http://p5js.org/
GNU Lesser General Public License v2.1
21.08k stars 3.22k forks source link

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

Open JacobePhane opened 1 month ago

JacobePhane commented 1 month ago

Most appropriate sub-area of p5.js?

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>
welcome[bot] commented 1 month ago

Welcome! 👋 Thanks for opening your first issue here! And to ensure the community is able to respond to your issue, please make sure to fill out the inputs in the issue forms. Thank you!

davepagurek commented 1 month ago

I just checked on safari 17.2.1 (an earlier version, I haven't updated my OS in a few months) and it seems to work there. I'll try to update when I get some time, but in the mean time, do you see any WebGL errors or warnings in the developer console when you run this?

JacobePhane commented 1 month ago

I just checked on safari 17.2.1 (an earlier version, I haven't updated my OS in a few months) and it seems to work there. I'll try to update when I get some time, but in the mean time, do you see any WebGL errors or warnings in the developer console when you run this?

Hi thanks for looking into this and for more data. To answer your question no we didn't see any webGL errors.

JacobePhane commented 1 week ago

Just checking in, has there been any progress on this? Also if anyone else is interested feel free the jump in!

davepagurek commented 1 week ago

Not yet unfortunately! Things have been pretty busy for me with work so I haven't had the time to update my mac (and deal with the possible package issues that comes with that haha.)

In the mean time, some next steps could maybe be to try to find a minimal example that reproduces the behaviour? e.g. if you have a simple shader with just one custom uniform, does that also still not update in the draw function?

Faisal-imtiyaz123 commented 2 days ago

@JacobePhane let me take a look

davepagurek commented 1 day ago

@Faisal-imtiyaz123 sounds good, let me know if you can figure out what's happening in that Safari version that isn't happening in Chrome (or the other way around.)