GLSL Shaders on Android: Because Nerds Need Love Too

GLSL Shaders on Android: Because Nerds Need Love Too


Are you tired of waking up every morning, dreading the thought of implementing those pesky shaders in your Android app? Do you find yourself wondering why on earth anyone would voluntarily choose to sacrifice a few precious milliseconds of rendering time for a marginally-improved visual experience? Well, wonder no more! Today, we're going to dive headfirst into the wonderful world of GLSL Shaders in Android, where the lines between genius and madness are blissfully blurred.

We'll give you a high-level overview of what it takes to get started with GLSL Shaders in Android. You'll learn that it's not as daunting a task as it seems – all it requires is a dash of creativity, a pinch of patience, and a willingness to debug those pesky shader errors (which, let's be real, are the best kind of debugging experiences). By the end of this post, you'll have a basic understanding of how to incorporate GLSL Shaders into your Android app, and maybe – just maybe – a newfound appreciation for the art of shader programming.

What the heck is GLSL:

So, you're wondering what all the fuss is about with these 'GLSL shaders' everyone's talking about. Well, let me tell you, it's not like they're some sort of mystical, magical formula for making your graphics look slightly less terrible or anything (although, let's be real, that would be awesome). No, GLSL stands for Graphics Library Shading Language, which is just a fancy way of saying 'a bunch of complicated code that will make your brain hurt'. Essentially, shaders are little programs that run on your GPU to give you things like realistic lighting, reflections, and textures. But don't worry if it all sounds like gibberish - even the most seasoned graphics developers have no idea what's going on when they're writing shader code (just kidding, sort of). The point is, GLSL shaders are the secret sauce that makes 3D graphics look, well, not totally terrible, and that's all you really need to know.

How these shaders work:

Ah, the magic of GLSL shaders! So, you're thinking,

'Hey, I've written some code before, this will be easy!'

Wrong. Dead wrong. See, when you write a GLSL shader script, it's not like you're writing a normal program that executes line by line, like a human actually wrote the instructions (which, let's be real, would be way more efficient).

No, no, no. In this mystical realm of shaders, your code gets executed all at once... for each pixel. Yes, you read that right. For each individual pixel on your screen. It's like trying to write a program for every single grain of sand on the beach (and then having to debug it on-the-fly because one grain decided to get a little too close to another). But wait, it gets better! Because this is happening for every pixel simultaneously, you have to consider things like parallel processing, thread synchronization, and... oh yeah, making sure your code doesn't crash the entire GPU (which, let's face it, would be a real showstopper).

So, if you thought writing shaders was just a matter of slapping some math together and calling it a day, well... welcome to the wonderful world of GPU programming!

And now, if you're still wondering which brainiac wins the battle of the brushes (CPU or GPU), let our favourite myth-busting duo, Jamie and Adam, take it from here. Watch this fantastic 'Mythbusters Demo - GPU versus CPU' video and discover which method paints a more realistic picture (literally!). So, grab some popcorn, sit back, and enjoy the brush-wielding showdown!


GLSL Shaders in Android:

The thrill of writing GLSL Shaders in Android! Because, you know, what's more exciting than telling the GPU exactly how to render each individual pixel on your screen? I mean, who doesn't love a good dose of parallel processing and thread synchronization?

But seriously, folks, if you're new to the world of shaders in Android, here are some basics to keep in mind:

Why bother with shaders at all?

You want to add some serious eye-candy to your app, like fancy effects or realistic simulations. Or maybe you just love writing code that's 10x slower than the original rendering algorithm, but looks kinda cool.

The basic of GLSL Shaders: what is it and why do I care?

A shader is a tiny program that runs on the GPU (Graphics Processing Unit) to manipulate individual pixels. Think of it like a mini-program that says, "Hey, GPU, render this pixel as if it were a sparkly unicorn's mane!" And the GPU is all, "Sure thing, human! I'll make sure every single pixel looks like a sparkly unicorn's mane!"

What to keep in mind when writing shaders in Android:

  1. GLSL 100: That's the version of the GLSL language you'll be working with. Yeah, it's like learning a whole new programming language... again.
  2. Android's GPU limitations: Don't get too excited about your shader's performance. Remember that your phone's GPU might not be as powerful as a gaming console (but let's be real, neither is your phone).
  3. Shader storage: Store those shaders wisely! You don't want to run out of space on your device or have your app crash because it tried to load too many shaders.
  4. Performance considerations: Don't forget that every shader you write affects the performance of your app (for better or for worse). Test, test, test!
  5. GLSL Shaders are not a magic solution: If your app is slow or laggy, adding shaders won't magically fix it. You still need to optimize your rendering code and consider other factors that affect performance.
  6. Debugging shaders: Yeah, because there's nothing more fun than debugging tiny pieces of code running on the GPU...

So, there you have it – a quick rundown of what to keep in mind when writing GLSL Shaders in Android! It's not as scary as it seems (I promise), and with these tips, you'll be well on your way to creating some truly stunning graphics. Happy coding!

The moment of truth! You've reached the climax of our shader-filled adventure, and it's time to... well, not actually learn how to set up GLSL in Android just yet. Don't worry, we'll get to that later (maybe).

But for now, let's take a shortcut (because who doesn't love shortcuts?) and skip the setup process altogether! After all, setting up GLSL can be as thrilling as watching paint dry (but without the colorful visuals). So, instead of diving deeper into the world of GLSL setup, let's just send you to an amazing app that'll make your shader-filled dreams come true!

Introducing Shader Editor: The Ultimate Shading Experience!

Ready to unleash your inner shader master? Look no further than Shader Editor, available on Google Play Store! With this fantastic app, you can create, edit, and visualize your shaders in a snap (well, almost). No more tedious setup, no more frustrating debugging sessions. Just pure, unadulterated shader-making fun!

So, what are you waiting for? Head over to the Play Store and download Shader Editor today! Your shader-filled adventure awaits!

P.S. Don't worry about setting up GLSL in Android just yet. We'll get to that later (promises, promises).

You're thinking of downloading the Shader Editor app on your phone, are you? Ha! Good luck with that. You know what they say: "Nothing says 'fun' like trying to edit GLSL scripts on a tiny mobile screen while simultaneously avoiding autocorrect suggestions and squinting at the code." Yeah, because that's exactly what you wanted to do with your precious time.

But fear not, dear reader! We've got a much better idea. Why don't you just create an Android emulator on your computer? I mean, who needs human interaction or fresh air when you can stare at a screen for hours and hours, editing scripts in a tiny window? It's like being a real-life coding ninja – minus the stealth, agility, and cool ninja suit.

And the best part? You won't even have to worry about autocorrect ruining your perfectly crafted shader code! (Okay, maybe you will, but it'll be worth it, right?) So go ahead, download the Google Play Store-enabled Android emulator, and get ready to enter a world of coding bliss – or at least, a world where you can edit shaders without wanting to pull your hair out.

The moment of truth! You've finally opened the Shader Editor app in your emulator (because who doesn't love using an emulator to edit shaders on their computer?). Congratulations, you're now staring at a blank slate... or are you?

Don't worry if it looks like nothing's happening; that's just the anticipation building up for the most epic shader experience of your life! All you need to do is click that tantalizing "Eye" button, and voilà! You'll be treated to a dazzling display of rainbow-colored goodness. It's like a party in your eyes!

But wait, there's more! As you click and drag on the screen, the colors will change and swirl around like a kaleidoscope on steroids. It's mesmerizing, we know.

Now, before you get too carried away with the colorful fun (and trust us, it's hard to resist), let's take things down a notch and create a new shader. Why? Well, this example is just too advanced for you guys... yet. You need to warm up those coding muscles first! Think of it as a gentle exercise in shader creativity. Don't worry; we'll get to the really cool stuff later (much, much later).

So go ahead, click that "New Shader" button, and let's start this coding adventure on the right foot!

Let's dissect this script! The uniform vec2 resolution variable holds the secret to the canvas's dimensions. But here's the fascinating part: this script isn't just being executed once, it's running repeatedly for every single pixel on your screen at once! In GLSL lingo, each tiny pixel is called a fragment. As the script wraps up its calculations, it needs to assign a color to each individual fragment - and that's exactly what the final line does.

If you modify the final line to gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);, your entire canvas will transform into a fiery red hue. Why does this happen? It's because the vec4 function takes four arguments, which represent the RGBA color values. In this case, the red value is set to 1.0, while green and blue are both set to 0.0, resulting in a pure red color. The alpha value of 1.0 ensures the color is fully opaque.

Noticing the peculiar choice of red value as 1.0 instead of 255, which is typical in Android? This is because GLSL shaders operate on a different scale altogether. Instead of dealing with integers like 0-255, we work with floating-point values ranging from 0.0 to 1.0. This uniformity extends to the resolution as well, which is defined within this same range. By using this scale, our scripts become hardware-agnostic and seamlessly compatible across various devices and platforms, eliminating potential issues that might arise from differing hardware operations.

You're probably thinking, "Hammad, why did you go over such a simple example again? Where's the parallel processing magic we discussed earlier?" Fear not, let's move forward and enhance our code with the following modification just replace the main function part:

void main(void) {
	if(gl_FragCoord.x / resolution.x > 0.5) {
		gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
	}
	else {
		gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);
	}
}        

The above code will yield the following result.

Now you can see that we're actually utilizing the gl_FragCoord to determine the position of each fragment within the canvas. This value provides us with the coordinates of the pixel, allowing us to examine its location relative to the top-left corner. By doing so, we're essentially checking whether the current fragment is situated on the left side or not. If it is, we display a green color; otherwise, a red color will be shown.

Now when you modify the script with the following code

uniform vec2 resolution;
uniform float time;

void main(void) {
	if(gl_FragCoord.x / resolution.x > 0.5) {
		gl_FragColor = vec4(sin(time), 1.0, 0.0, 1.0);
	}
	else {
		gl_FragColor = vec4(1.0, sin(time), 0.0, 1.0);
	}
}        

You will be able to produce a vibrant canvas that transitions smoothly from red to green and eventually to parrot green. We've introduced a new uniform variable called time, which represents the elapsed time since the start of the canvas rendering process. By passing this time value to the sin function, we can create a wavy effect that'll make you wonder how something so simple can be so mesmerizing. And don't even get me started on what sin is - I mean, come on, you probably learned it in your 10th grade math class... or did you?

As you've seen in the previous examples, the GLSL shader script employs a syntax similar to that of C programming language - a familiar concept for many of us who learned it during our college days (or perhaps even university). Beyond the basics, there are additional data types that can be leveraged for various purposes. A huge shoutout to Patricio Gonzalez Vivo and Jen Lowe for curating "The Book of Shaders," an invaluable resource for grasping the intricacies of GLSL. Head over to this link to dive deeper into the world of shaders and uncover the magic within.

I'm glad you're curious! You might be wondering why I'm showing you an app developed by someone, but the purpose of this exercise is to demonstrate the capabilities of GLSL (Graphics Library Shading Language). With GLSL, you can have a lot of fun with camera images and effects!

By using this technology, you can play around with camera images, apply different filters, and even create some amazing effects - like making your face wobble! Who wouldn't want to try that out?

Before we dive into the fun stuff, let's get started by loading the current camera texture into our app. To do this, simply tap on the three dots at the top of the screen, navigate to "Load Sample," and then select "Back Camera." This will open your back camera stream on the canvas.

To unlock an amazing camera view on your canvas, simply follow these steps:

  1. Delete any existing script code in your editor.
  2. Paste the following GLSL script into your editor:

#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif

uniform vec2 resolution; // current resolution of the canvas
uniform vec2 cameraAddent;
uniform mat2 cameraOrientation;
uniform samplerExternalOES cameraFront; // texture for Front Camera
uniform int frame;

void main(void) {
	vec2 uv = gl_FragCoord.xy / resolution.xy; // get normalized camera coordinates
	vec2 st = cameraAddent + uv * cameraOrientation;
	float waitPixelCols = 150.0;
	int speed = 2;
	float width = 5.0;
	vec4 scanColor = vec4(0.4, 1.0, 0.85, 1.0);
	float scanPos = mod(float(frame) * float(speed), resolution.x + waitPixelCols);	
	vec4 color = vec4(
		texture2D(cameraFront, st).rgb, 1.0);
	if (st.x * resolution.x > resolution.x - scanPos) {
		discard;
	}
	else if (abs(st.x  * resolution.x + float(speed) *  width - (resolution.x - scanPos)) < width) {
		color = scanColor;
	}
	gl_FragColor=color;
}
        

As you paste the script, you'll see a TimeWarp effect emerge on your canvas. A line will start at the top and move downwards, giving you a mesmerizing time-warping experience!

Ready to dive deeper into the world of GLSL scripts? Well, buckle up, because there are some amazing resources out there just waiting to be devoured!

First off, check out these links - they're packed with tasty morsels of shader-y goodness. And if you're feeling extra adventurous (or just plain lazy), why not let AI do the heavy lifting for you? It's like having a personal tutor who never gets tired or complains about your lack of coding skills.

So go ahead, tap into that sweet, sweet knowledge and become the master of GLSL scripts!

References:

https://thebookofshaders.com/

https://seawisphunter.com/pdf/dan-buckstein-shaders.pdf

https://clauswilke.com/art/post/shaders


Shahid Iqbal

Android Engineer @smartech ?? | KMP/CMP | Debugging Wizard ??♂? | Relentless Problem Solver ??

8 个月

Insightful ??

回复

Sounds like an exciting read. Can't wait to level up my mobile development skills. ??

回复

要查看或添加评论,请登录

Hammad Farooq的更多文章

社区洞察

其他会员也浏览了