NickXitco Posted May 13, 2021 Share Posted May 13, 2021 Hello! I'm new to this forum but I had a burning question that I can't seem to solve and was hoping to get some sort of help. I'm trying to write a function to animate a bezier curve that changes styles (color and weight). I'm splitting up the curve into many straight line segments so that I can apply a style to each line segment to get an illusion of a gradient. I'm doing this by using two graphics objects (A and B), where A that animates the "head" or leading segment of the bezier curve (the one that's moving), and B renders the lasting tail segments that I want to persist after the animation is done. For reference, here is the drawing line segments code. lineStyle is not applied anywhere else in the codebase. static drawSegments(graphics, camera, segments, startIndex) { for (let i = startIndex; i < segments.length; i++) { const segment = segments[i]; //Prevents edges from appearing too thin. //Increasing threshold will make small lines larger, vice versa. const THRESHOLD = 0.5; const strokeWeight = Math.max(segment.u.weight, THRESHOLD / camera.getZoomFactor().x); const color = ColorUtilities.hsv2rgb(segment.u.hue, segment.u.sat, 100); const hexColor = ColorUtilities.rgb2hex(color.r, color.g, color.b); const randomColor = Math.random() * 0xFFFFFF; console.log(color); graphics.lineStyle({ width: strokeWeight, color: hexColor, cap: PIXI.LINE_CAP.ROUND, }); graphics.moveTo(segment.u.x, segment.u.y); graphics.lineTo(segment.v.x, segment.v.y); } } If I clear B every frame (B.clear();), the lineStyle behaves correctly, as you can see in the first photo below, the line smooths from a small indigo line to a larger pink-ish one. However, this isn't great for me performance wise, as I want to have many of these lines, and drawing them from scratch every frame is expensive. Therefore I'm trying to just draw the segments that B hasn't already drawn yet. So every frame B will draw more and more lines. However, if I do it this way I get a strange result. In the second case, the color of the line doesn't transition correctly, or at all really. The weight transitions fine, but the color stays either constant or varies very slightly (as shown in the third picture). Perhaps more bizarrely, if I set the color instead to be a random color, the lineStyle seems to adjust correctly (although the colors don't seem nearly random enough. Additionally, if I set the color to be some aspect of the index of the loop I'm drawing in (like setting the hue to be (i * 20 % 360)), I get these weird color bands that seem to want to jump back to previous colors. I stepped through the batching code and could not figure out for the life of me where these colors were disappearing. I would love some help as to figuring out this problem because I am completely stumped. I'm using the development build of Pixi v6.0.1. ivan.popelyshev 1 Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted May 13, 2021 Share Posted May 13, 2021 Adding more features to Graphics, making it smooth and color transitions is one of hardest tasks related to PixiJS and WebGL 2d graphics. Even I am stuck with one of such tasks for 6 months already. The main problem is that when someone does that kind of improvement or solves particular tasks - he doesnt share it, and next person has to re-invent it. As a result, those tasks are real paid work, dont expect people to just help with it. Maybe someone will share his experience in the topic, but dont count on it. Quote Link to comment Share on other sites More sharing options...
NickXitco Posted May 13, 2021 Author Share Posted May 13, 2021 Okay, fair enough I guess I'm just confused because the behavior seems to be inconsistent. If I draw the entire line in one frame, then the color transition works fine. But when I draw it across multiple frames, it seems to reference previous line style colors rather than using the newly declared line style each time. I'll continue to look into it and post here if I get any findings. Thank you. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted May 13, 2021 Share Posted May 13, 2021 As for bizzare case - that requires a complete reproduction, minimal demo. Quote Link to comment Share on other sites More sharing options...
NickXitco Posted May 13, 2021 Author Share Posted May 13, 2021 Alright so I've found a solution and also may have found the root of the problem while digging through the graphics code. I'm unsure if this is due to some batching problem but here's the issue that I've found(I'd be happy to post more on GitHub if this is actually an issue). I've included the table below that showcases the problem. idx #Colors #Verts #Batches 0 0 0 0 1 0 8 1 2 0 24 2 3 0 32 3 4 0 48 4 5 0 64 5 6 0 80 6 7 0 96 7 8 0 112 8 9 0 128 9 10 0 144 9 11 0 160 10 12 0 168 11 13 0 184 11 14 0 192 12 15 104 208 14 16 212 216 14 17 328 232 15 18 448 240 16 19 572 248 16 Each of these columns (besides the index) represents the length of the GraphicsGeometry's colors, points, and batches arrays, respectively. Every time we add a new line segment we add 8-16 numbers (x, y) which should presumably come with 4-8 color values, one for each vertex. And this works fine the first time that buildDrawCalls() is called, which in this case happens after 12 batches have been added to the geometry, so we get the proper numbering (on idx 15) where the number of colors in the geometry is 104 = 208/2. Then when this is passed to packAttributes(), each vertex is assigned the correct color. However, on the next buildDrawCalls() at idx 16, this.addColors(...) is called again for every single one of the geometries batches, despite it only adding 4 vertices. Therefore, when packAttributes is called, the vertices that were added are now colored by the colors that are supposed to be associated with the first few vertices in the list. I've included a diagram of what I'm trying to describe in case my description is confusing. I'm not sure if this is a problem with the way I'm using my graphics objects, but this causes the colors array to quickly get out of hand and become far larger than the number of vertices. With 68 line segments the number of colors goes to around 28000, when we really only need around 300 of those, so most go completely wasted. As a patch for this, I simply clear the colors array of the geometry every time I add a line segment. Since buildDrawCalls() currently re-adds all the colors anyways, it seems like this shouldn't cause an issue, and would actually be more efficient. I'm curious to know if this is a real bug or caused by something that I'm doing wrong. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.