What hint(ENABLE_OPTIMIZED_STROKE) does?

another simple quesiton. what Enable_Optimized_Stroke does?. im could not find any openGL reference. What is the openGl equivalent?
Thanks!

1 Like

Processing does some unique rendering optimizations which are not found in other environments (like openFrameworks, Godot, three.js, etc.) I suspect there’s no equivalent to be found in the openGL reference.

Here’s the source code where ENABLE_OPTIMIZED_STROKE and DISABLE_OPTIMIZED_STROKE is found. By default it is OPTIMIZED. I don’t know how it affects performance, but I do know that

attribute vec4 position;

has a different value depending on that hint. If you disable it, position contains the model coordinates. If you enable it, it contains something else.

I wish the default was reversed, otherwise you can go crazy while learning openGL and trying to understand why your rendering looks wrong. What I expected was that if I calculated color values based on position and I move the object, the colors would be attached to the shape as it was a sticker. That’s not what happens with ENABLE_OPTIMIZED_STROKE (the default).

Here you can see an image and some more info:

Update: in more detail, that hint sets how often to call the method flush() (continuously or when-full).

In OPTIMIZED mode, the modelview matrix seems to be applied in the CPU side (not GPU), and then the modelview matrix is set to the identity matrix to avoid it having any effect on the GPU side. I wonder if this was done before before Processing exposed shaders to us, so it was supposed to improve framerate without having a visible effect on our programs. But now that we can write shaders it feels confusing to not follow the same pattern as other environments.

2 Likes

Do you think that would be worth opening an issue request on Issues · processing/processing · GitHub to see if either the default could be changed?

At least I would be happy to know why is the current default what it is :slight_smile:
It could also be that with very slow GPUs it makes a big difference in performance…

I also wonder what could be a more intuitive name, because it affects things unrelated to STROKE (actually the vertex shader).

ps. Maybe a more generic solution would be to document hint(), which is not at all in the reference. And of course all the available hints with a short paragraph explaining what they do. What do you think?

1 Like

Hmm. I see a closed issue in processing-docs related to hint – perhaps look at that commit and reference in a new processing-docs issue?

Uhm according to the documentation

Forces the P3D renderer to draw each shape (including its strokes) separately, instead of batching them into larger groups for better performance. One consequence of this is that 2D items drawn with P3D are correctly stacked on the screen, depending on the order in which they were drawn. Otherwise, glitches such as the stroke lines being drawn on top of the interior of all the shapes will occur. However, this hint can make rendering substantially slower, so it is recommended to use it only when drawing a small amount of shapes. For drawing two-dimensional scenes, use the P2D renderer instead, which doesn’t need the hint to properly stack shapes and their strokes.

From the official documentation on hint()

So looks that if you call DISABLED_OPTIMIZED_STROKE the rendering takes care more about how the shapes are “layered”, while with the optimization (default, ENABLE_OPTIMIZED_STROKE) all the shapes are drawn as in the 3D space (if a line crosses a shape, you will see it actually crossing the shape). Enabling it results in better performances (as all the shapes are grouped together in the pipeline apparently).

Not sure if it applies also when you use Java OpenGL.

Nice that there is now a page in the reference :slight_smile:

More unexpected side effects I encountered: set uniform to 1.0, draw shape A, set uniform to 0.5, draw shape B, both are drawn with the uniform as 1.0, because they are batched together. Which makes the developer wonder… why is my uniform not working?

It shouldn’t do as far as I can tell - just been playing with it and looking through the code, and it’s all a layer above the direct OpenGL layer.

It does set flushing to continuous, so it’s not batching up calls - getting closer to immediate mode rendering. But also has some interest effects on perceived stroke weight - eg. testing with a sphere with stroke and fill and a larger stroke weight the different in the two seems quite pronounced.

Makes me wonder why you’re not calling flush()? :smiley_cat:

:slight_smile: I never heard about flush(). Where is it mentioned?

It probably isn’t! :rofl:

:slight_smile: So you mean that with

myshader.set('nonsense', 1.0);
shape(shapeA);
flush();
myshader.set('nonsense', 0.0);
shape(shapeB);

shapeB would use the value 0.0 even with ENABLE_OPTIMIZED_STROKE?

I think this is worth testing. With a dedicated graphics card (GTX 1060) and the kind of things I do, performance never seems to be an issue. Even when doing a ton of shader passes. And the deformations I’m doing require to use DISABLED_OPTIMIZED_STROKE.

I mention this because if you read that text you may think… oh, I should avoid changing this setting because everything will run slowly. It may be true if you’re on a slow computer.

I think if you want to twist shapes around their Z axis in real time, you need to disable it, otherwise the matrix you receive in the vertex shader is the identity matrix and all the vertices have already been displaced to their final positions, so you don’t know where the centers of the shapes are.