1
\$\begingroup\$

I don't think I fully understand how rendering shaders work. I get that you give a shader to an object/sprite when drawing it, and it applies the shader to it. But I don't think I'm doing it right.

For example, I wrote a shader for when the player is underwater. It makes the player sway side to side, but the problem is I'm not sure how to tell when I can use it. Do I loop through all the water blocks, and If the player intersects, run the shader on the player? This brings up the problem where all of the player would wave instead of just the part of him below the water.

I'm not sure what else I could do, and I apologize if this sounds confusing, I'm very confused myself and am not sure how to explain it. Do I run the shader on the water and somehow get it to run on all the pixels intersecting the water? What do I do? Also, just to make sure, I am using 2D.

\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

You generally don't use a special shader for the player to create an underwater effect, nor do you do any sort of crazy collision detection between the player and the water.

Underwater effects generally activate when the camera is under the water. And underwater effects are often accomplished by way of full-screen post-process passes rather than swapping everything to a special underwater shader.

In other words you render your player and everything else normally all the time. If the camera happens to be underwater, you render a fullscreen quad when a special shader that samples the regular frame and applies the underwater "wave" effect, along with whatever other fancy effects you may want to add (maybe a color shift, for example).

The other side of the coin is when the camera is above the water, but looking down into it. In this case, the responsibility of doing any refractive waving and whatever would normally be the job of the water geometry's shader; it will generally also sample the regular frame and apply a similar kind of distortion (as well as a reflection and refraction effect).

In both case, the player doesn't get a special underwater shader. A post-process effect is used when the camera's below the water plane, and a special effect is used for the water plane itself for when the camera sees it from above.


Since you've edited the question to specify that you're using 2D, I'll note that that doesn't change a whole lot. You no longer have to worry about a water shader for when you're above the water, looking down into it. That makes things easier.

You also don't have a camera that can ever really be under the water. Instead, you know which regions of your world are underwater via some other mechanism (maybe the world is tile based, maybe you can identify the water with a rectangle or spline region, et cetera). You can use that mechanism to build a mask for the fullscreen underwater effect, using a texture containing alpha values as I describe in my answer to this other question. That mask can be used as a blend factor to ensure the wavy postprocess effect is only applied to the regions of the scene that are under water.

\$\endgroup\$
6
  • \$\begingroup\$ ah crap, I probably should've mentioned I'm using 2D. Whoops, I was really confused for a minute. Sorry! \$\endgroup\$
    – Merle
    Commented Mar 3, 2017 at 2:52
  • \$\begingroup\$ @Merle 2D changes very little, I'll address that. \$\endgroup\$
    – user1430
    Commented Mar 3, 2017 at 3:14
  • \$\begingroup\$ I still don't understand fully, is it possible to run a shader on a transparent image, and have everything behind the image have the same shader ran? I've been experimenting with hours, and I can't get this to work. \$\endgroup\$
    – Merle
    Commented Mar 4, 2017 at 21:44
  • \$\begingroup\$ No, shaders run on geometry you submit. The basic idea behind a post processing pipeline is to render you scene as normal, except with your render target output set to a texture, rather than the backbuffer (as is the default). Then you can bind your regular scene as a texture and render a full-screen quad using that texture; in the shader for the full-screen quad you sample your normal scene texture and apply whatever effects you want. \$\endgroup\$
    – user1430
    Commented Mar 4, 2017 at 22:12
  • \$\begingroup\$ I apologize if this is pushing it but I've been staring at your words for an hour and they still don't make much sense to me. I got some of it, I set my render target output to a texture rather than the backbuffer, I rendered it which worked fine, but how do I 'sample the normal scene texture'? The water takes up only a small part of the screen, I can't apply the shader to the entire image. And If I had a separate layer for the water, the size would be weird. Could you try explaining it like I didn't know what OpenGL was? \$\endgroup\$
    – Merle
    Commented Mar 5, 2017 at 0:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .