Shader vs. RenderTexture: Two Ways to Build a Magnifying Glass in Cocos
Introduction
Hello everyone, I am Yiyuan Programmer, a lead programmer with 8 years of experience in the game industry.
A few days ago, I saw a message in a group:
"Does anyone have a magnifying glass effect?"
The fewer the words, the bigger the demand.
Seeing this sentence, my first reaction was also:
Use a Shader.
Just as I was about to reply, a question suddenly occurred to me:
A magnifying glass can clearly be implemented using
RenderTexture, so why is the first reactionShader?
Actually, it's not just the magnifying glass.
- Water ripples, use
Shader. - Dissolve, use
Shader. - Streaming light, use
Shader. - Character hit flash, also use
Shader.
As if in game development, whenever an effect is slightly mysterious, it ends up with the same prescription:
Recommend Shader, once in the morning and once in the evening, observe on a real device after writing.
So in this article, I don't plan to just throw you a piece of magnifying glass code. (Throw two pieces haha)
We will implement the same effect in Cocos game development using both RenderTexture and Shader, and then answer the question in the title:
Why does everyone like using Shaders so much? Is it really that good, or does it just make you look like a pro?
The example project for this article is available at the end; friends, go get it yourselves.
| RenderTexture | Shader |
|---|---|
Don't rush to write code, what exactly is a Shader?
Many people, when they first hear Shader, picture green code rain, complex formulas, and a programmer still adjusting colors at 2 AM.
Actually, you can start by understanding it a bit crudely:
A Shader is a small program that runs on the GPU, responsible for telling the GPU where vertices are placed and what color a pixel ultimately becomes.
In normal business code, we often handle things by object: hide this button, move that character, open this popup.
Shader's way of thinking is a bit different. It's more like saying:
"All pixels passing through here, process them according to this set of rules."
This is also one of the reasons people like Shader.
Next, let's get into actual combat.
Practical Combat 1: RenderTexture, shooting with a camera
First, look at the solution without writing Shader.
Normally, the Camera renders the picture to the screen. But we can also have a second Camera render its result to a texture; this texture is the RenderTexture.
Then put the RenderTexture into a circular Mask, and the chain becomes:
1. Why prepare a hidden copy?
The capture camera should only see the content that needs to be magnified, and cannot see the magnifying glass itself.
Otherwise, the lens captures the lens, and the lens appears inside the lens again, ultimately resulting in an infinite nesting doll effect.
So in the example, we prepared:
Artwork: The image normally displayed by the main camera.CaptureArtwork: Placed on a separateLayer, only visible to the capture camera.Lens: CircularMask,RenderTexturecontent, and frame.
2. Create RenderTexture
Three things were done here:
- 1. Create a
256 x 256texture. - 2. Have the capture camera draw its result into it.
- 3. Give the texture to the lens
Spritefor display.
3. How to control the magnification factor?
The smaller the orthoHeight, the less range the camera sees.
Suppose the lens diameter is 220, the magnification factor is 2, the camera only captures content about 110 in height, then spreads it across the 220 lens, achieving 2x magnification.
4. Make the camera follow the finger
First, convert the touch point to inside the image, then map it to the world coordinates of the hidden copy, and the capture camera can find the corresponding position.
After the finger is released, we simultaneously hide the lens and disable the capture camera.
Practical Combat 2: Shader, let the pixels come over themselves
RenderTexture is very versatile, but to magnify a static Sprite, we added a copy, Camera, Layer, RenderTexture, and Mask.
It's not that it can't be used, it's just a bit like seriously purchasing an excavator just to dig up a scallion.
However, the Shader version only needs:
- The original
Sprite. - One
Material. - A script that updates parameters following the touch point.
This is also another reason Shader is popular:
When an effect can be described by pixel rules, it often reduces extra operations.
1. What is UV?
UV can be understood as the coordinates inside an image, typically ranging from 0~1.
Urepresents the horizontal direction, usually from0on the left to1on the right.Vrepresents the vertical direction, also in the0~1range; the specific up/down direction might differ depending on the texture source.
Normally, whatever UV the current pixel is at, it fetches the color from the corresponding position in the texture.
What the magnifying glass needs to do is make the UV inside the lens move closer to the center of the circle:
Suppose zoom = 2, a sampling point originally 0.2 away from the center now only fetches color from a position 0.1 away from the center.
A smaller texture range is spread into the same size circle, visually creating magnification.
2. Determine if the current pixel is inside the lens
Calculate the distance from the current UV to the lens center:
- Less than radius: Display the magnified image.
- Greater than radius: Display the original image.
3. Mix the original and magnified images
Outside the circle, use baseColor; inside the circle, use magnifiedColor.
Then determine if the pixel is at the edge of the circle, and mix in a layer of gold to create the frame.
As for the handle, this example doesn't include it. The most important thing in practical combat is to explain the principle clearly, not to let the art girl give three more optimization suggestions after seeing it.
4. The script only passes parameters
Four numbers are the lens center x, center y, radius, and magnification factor.
When the touch moves, update the center, and the Shader will recalculate at the new position.
So is Shader definitely better than RenderTexture?
Of course not.
Actually, for the magnifying glass effect, Shader is less flexible than RenderTexture.
We need to choose which tech stack to use based on the specific game requirements:
Prioritize Shader
- Magnifying a single image, character portrait, or static map.
- The effect is mainly local color change, distortion, gradient, or texture sampling variation.
- Want to reduce extra nodes and cameras.
Prioritize RenderTexture
- The lens contains multiple nodes.
- Need to see dynamic content like character animations, particles, map units, etc.
- The magnified object is not a simple texture.
Finally, answer the article title
Why does everyone like using Shaders so much?
I think:
- Shader can better optimize effects in specific situations.
- Shader can better optimize performance in specific situations.
- Shader can better showcase your abilities in specific situations.
Using Shader is cool, but knowing when not to use it is even cooler.
Conclusion
Here's a question: Do you friends have different opinions on "Why does everyone like using Shaders so much?"
Feel free to discuss in the comments section.
The example project for this article can be obtained by sending a private message with "Magnifying Glass".
I am "Yiyuan Programmer", a lead programmer with 8 years of experience in the game industry. In game development, I hope to help you, and through you, help everyone.
To be honest, I'd like a like and a heart! Please share this article with other friends you think might need it. Thank you!
Recommended articles:
Yiyuan Cocos Mini-Game Practical Combat Collection 2.0
Yiyuan Cocos Mini-Game Practical Combat Collection 1.0
This game worth 6.8 billion, aren't you going to practice it? Arrange it!
A friend said my jigsaw puzzle game using Mask couldn't be batched...
Who can't make Tetris... Ah? A quicksand version?
A recently popular jigsaw puzzle game, the boss asked me to make one with Cocos 3.8...
Dare to challenge replicating the once popular Cut the Rope game with Cocos 3.8?