I am trying to implement a metal-backed drawing application where brushstrokes are drawn on an MTKView by textured square repeatedly along a finger position.
I am drawing this with alpha 0.2. When the squares are overlapped the color is added. How can I draw with alpha 0.2.
I think you need to draw the brush squares to a separate texture, initially cleared to transparent, without blending. Then draw that whole texture to your view with blending.
If you draw the brush squares directly to the view, then they will accumulate. After you draw square 1, it's part of the image. Metal can no longer distinguish it from anything else that was already there. So, when you draw square 2 overlapping it, it will blend with what's already there, including square 1.
Related
Is it possible to do texturing inside 3 Vertex(Triangle). I drawing a triangle. I want to read the previous pixel inside fragment shader inside triangular area using sampler and I want to color. If there is previous color available i need to clear color. If color is available I need to add color to the pixel.
Inside quad we can do it sampling the texture.
How to draw a texture line using SKShapenode in SpriteKit?
For example, how to draw chalk-like textured line on touch move?
Is the following method correct?
[lineNode setStrokeTexture:[SKTexture textureWithImageNamed:#"texture.png"]];
But it shows nothing and the line is empty.
A possible solution for your task is to use SKCropNode with the line node set as the mask node of the crop node and a texture node added as a child to the crop node. Keep in mind however, that SKCropNode does not use alpha value of the mask image pixels to "smoothly" mask out the target image. It just checks if the alpha of the mask image is greater than 0.05 and if so, displays the corresponding target image pixel and if not, it completely masks out the pixel. So the result may be somewhat pixelated.
I'm building a thick line from triangles. The problem i'm having is that when the curve is semi transparent and some triangles overlap i get the effect in the picture. I would like for the triangles alphas to not get added.
I'm using this blend function:
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_CONSTANT_ALPHA);
You may render the curve to separate render target with full opacity and then draw that target with custom alpha. Otherwise you should avoid overlapping.
you can use stencil test for blocking the drawing of already drawn fragments (which prevent blending from the first place)
I am rendering point sprites (using OpenGL ES 2.0 on iOS) as a user's drawing strokes. I am storing these points in vertex buffer objects such that I need to perform depth testing in order for the sprites to appear in the correct order when they're submitted for drawing.
I'm seeing an odd effect when rendering these drawing strokes, as shown by the following screenshot:
Note the background-coloured 'border' around the edge of the blue stroke, where it is drawn over the green. The user drew the blue stroke after the green stroke, but when the VBOs are redrawn the blue stroke gets drawn first. When it comes to draw the green stroke, depth testing kicks in and sees that it should be behind the blue stroke, and so does this, with some success. It appears to me to be some kind of blending issue, or to do with incorrectly calculating the colour in the fragment shader? The edges of all strokes should be transparent, however it appears that the fragment shader combines it with the background texture when processing those fragments.
In my app I have created a depth renderbuffer and called glEnable(GL_DEPTH_TEST) using glDepthFunc(GL_LEQUAL). I have experimented with glDepthMask() to no avail. Blending is set to glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA), and the point sprite colour uses premultiplied alpha values. The drawing routine is very simple:
Bind render-to-texture FBO.
Draw background texture.
Draw point sprites (from a number of VBOs).
Draw this FBO's texture to the main framebuffer.
Present the main framebuffer.
EDIT
Here is some code from the drawing routine.
Setup state prior to drawing:
glDisable(GL_DITHER);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
Drawing routine:
[drawingView setFramebuffer:drawingView.scratchFramebuffer andClear:YES];
glUseProgram(programs[PROGRAM_TEXTURE]);
[self drawTexture:[self textureForBackgroundType:self.backgroundType]];
glUseProgram(programs[PROGRAM_POINT_SPRITE]);
// ...
// Draw all VBOs containing point sprite data
// ...
[drawingView setFramebuffer:drawingView.defaultFramebuffer andClear:YES];
glUseProgram(programs[PROGRAM_TEXTURE]);
[self drawTexture:drawingView.scratchTexture];
[drawingView presentFramebuffer:drawingView.defaultFramebuffer];
Thanks for any help.
If you want to draw non opaque geometries you have to z-sort them from back to front. This has been the only way to get a proper blending for many years. These days there are some algorithms for order independent transparency like Dual Depth Peeling but they are not applicable to iOS.
What is the purpose of the source rectangle parameter in the SpriteBatch.Draw() method?
MSDN says: A rectangle that specifies (in texels) the source texels from a texture. Use null to draw the entire texture.
What does that mean?
The idea of the sourceRectangle is to allow you to implement what is both a performance optimisation and an artist convenience by arranging multiple sprites into a single texture. This is known as a "Texture Atlas" or a "Sprite Sheet".
(source: andrewrussell.net)
I explain why it is a performance optimisation in this answer. Basically it lets you reduce the number of texture-swaps. (So in the case of my illustration, if you're only drawing an animated character once, using a sprite-sheet will not improve performance.)
It also lets you implement tacky 2D special effects, like having a sprite "wipe" in:
(source: andrewrussell.net)
A texel is more-or-less the same thing as a pixel in the texture (a "texture pixel", if you will). So, when you draw your sprite, you specify the top-left corner of your sprite within the texture, along with its width and height. (The same as if you selected it in an image editor.)
If you pass in null for your source rectangle, XNA will assume a source rectangle that covers the entire texture.
The origin you specify to Draw is also measured in texels from the upper-left corner of the source rectangle.
In a situation where you have a single texture that contains different frames (animated textures), you will want to specify the source rectangle, so that you can draw a single frame from a texture.
i.e.
Look at this spritesheet here
The source rectangle defines the area of the texture that will be displayed. So if you have a 40x40 texture, and your rectangle is (0, 0, 20, 20), only the top left corner of the texture will be displayed. If you specify null for the rectangle, you will draw the entire texture.
This can be helpful when drawing from a spritesheet (a collection of textures that are all put into one bigger texture), and also in image manipulation programs.