3

I'm working with Brad Larson's GPUImage, which I've found to be really amazing. For flexibility and ease of writing, I've created a custom filter that has 3 uniform inputs. I based it on the GPUImageBrightnessFilter.h and .m. One uniform is simply a "parameter" float, one is a "center" CGPoint to feed in touch coordinates if I need them, and one will hopefully be a time float which is the amount of time that has elapsed since the shader was started. I'm using initWithFragmentShaderFromFile to use my own shader files.

My "parameter" and "center" uniforms work. It's the time uniform that doesn't work because I don't understand how to create a uniform that is constantly changing (as time does).

The goal of my time uniform seems to be similar to SpriteKit's u_time. It returns the number of seconds since the current shader has been running which you can feed into your custom shader to animate it. One very simple example use might be to cycle the hue of an image as time passes. I'm hoping to build upon that with more complexity as my knowledge of GLSL grows.

I'm not sure what code to post, as my misunderstanding could be in many places and it may be that I'm trying to do something that's not possible. This post about setting a start time and subtracting it from CACurrentMediaTime() seems like a good place to start:

Getting the time elapsed (Objective-c)

The problem is I'm not sure how to continually update a uniform to pass to my shader. Do I do it in my custom filter's setter for time? Don't custom setter's only get executed once? Do I do it in my init override? Doesn't that only get executed once? Do I write a loop in my controller that continually calls the setter? That seems like an expensive and messy solution.

I'm not asking for code, just suggestions to steer me in the right direction or un-steer me from whatever wrong direction I've gone in my thinking.

Community
  • 1
  • 1
rikitikitavi
  • 139
  • 13

1 Answers1

1

Asking the question helped me to get to a solution and learn about NSTimer. I incorporated a method that creates a repeating NSTimer into my customized GPUImageFilter subclass that passes a time uniform to the shader. It calls a selector that increments my 'time' variable and passes that into the uniform array.

rikitikitavi
  • 139
  • 13
  • I wish you'd been able to find a better answer than that. It seems to me to defeat the purpose of using a shader if you continuously need to feed it data like that. Doesn't that just slow the whole thing down? – PKCLsoft May 20 '19 at 12:54
  • It never slowed anything down for me. I'm just feeding the time in as a uniform, so it's not occupying any of the GPU time. I'd be open to other methods, but no drawbacks here as far as I can tell. – rikitikitavi Aug 27 '19 at 21:58
  • Forgive my ignorance, but if it's a uniform, doesn't that mean that every instance of your shader will use the same time? I was thinking of a per-instance attribute which I thought would be slower. There's a very good chance I have misunderstood things, but I though that if the CPU changes the value, it then needs to be "sent" to the GPU and that slows down things. I'm a complete newby to shaders, so I'm easily mistaken in these things. Thanks for responding though. – PKCLsoft Aug 28 '19 at 06:39