Hi @alex,
I would like to implement LineDashedMaterial in our custom web viewer for geometry:
Definition: three.js docs
Example : three.js examples
Also I need to set the line width “screen-defined”, so that it doesn’t resize when zooming.
That being said… my question is: what would be the most straightforward between:
-extending SpeckleMaterial
-working with pure three.js on top of your library
Do you have any examples of people creating their own material?
Depending on how you are going to use the dashed lines, you have several options:
The viewer already has a custom line material SpeckleLineMaterial which is built upon this three line implementation. It supports, scree space size and dashing with customizable dash scale, offset and gap. This is what all lines in the viewer use. It’s currently not exported by the viewer, but we can add it to the export list in the next release
You can do your own three.js thing alongside the viewer. This is one concept we’ve insisted on sticking with. So you can create your own objects and materials using stock three.js and they will work alongside the speckle custom ones. Just remember to set the objects to an ObjectLayer otherwise it will not get rendered by the speckle cameras. The only caveat here is that by doing this, you will not benefit from automatic draw call batching, relative to eye rendering (if required), and it might be difficult to pull off complex rendering pipeline related features.
As you suggested, make your own material extension. While this is possible, it would make the most sense for cases where you also need to alter the underlying shader. Otherwise, it won’t be worth the hassle. Besides the speckle customized materials I don’t know of other material extensions.
Thank you very much for the answer @alex
I didn’t know you were using this example as a basis, the options are very interesting indeed! But I am afraid the way width is working may be a problem for our use case.
So let me first test option 2. Can I affect a three.js custom material to a speckle object (my lines) directly, or should I hide the speckle object and rebuilt a similar one as a three object, from the display-mesh data?
I would recommend we take a step back. Without any details about your use case it’s hard to tell for sure, but I think you can easily avoid complications.
I’ve made this example for your that shows how you can customize an existing speckle line object material. I’ve changed it’s color, it’s width (in pixels) and made it dashed.
For line width you have two options: world units or screen units (pixels). The example above shows how to set the line width in pixels. If you want it in world units, just set worldUnits to true, however from your previous post I understand that you want it screen units.
For dashed lines, the example shows that it’s possible. There are also a bunch of options for dashes, and the example does not use all of them.
Going with option 2 seems like an unnecessary complication, but if you are keen on it, you can probably do it too. You can use your own materials with the speckle objects, however you need to make sure you are using the correct one, since three.js does not allow you to use any kind of material with any kind of geometry. Hiding the speckle line and then rebuilding it separately would work in theory, but that would beat the purpose in my opinion
Thanks @alex
Your help is always really useful!
The usecase is always the same: the viewer for historical geometric figures
I didn’t know about the world/screen unit property, that’s perfect I will use this.
I still have two questions/suggestions about these line sytles, but it’s not urgent:
The dash effect could also be set in world/screen (as is the case with TopSolid, the size of the dashes doesn’t scale with the zoom)
Axis line style would be very useful (i.e. a small dash alternating with a large dash).
How can I get the id of the parent object? I found a hack from _renderData, but it only works with colored lines. I guess there is a more conventional way?
Thanks!
I’ll need more information on what you are trying to do, as I’m not sure what you mean by parent object.
In you image, the arrow at the top points to a batch id. These ids we generate ourselves and are the unique ids of each batch. The arrow below that points to a render view id, which is the speckle id of a renderable object.
Batches hold a group of render views with the same material. And each render view knows which batch it’s part of via it’s batchId
So which id are you trying to get, based off which other id?
Ok thank you very much @alex
I was not understanding correctly how batch works, now it is ok.
My problem is :
We use a custom data to specify if a line is dotted (5 different dotted-style), this data is on the object.
If sent two lines with different dott-style, they will look the same and have the same batch in the default speckle viewer.
So I cannot modify directly the batch.material as in your example.
Is there a way to apply a new material directly to an object instead of :
You are right, this is how you normally set a material on a per-object basis. However, line batches and lines in general work a bit differently and I’m not sure you can make selective line objects dotted using this approach. We might need to find a workaround. I’ll get back you later today