Best way to keep dash size constant

I keep the box size constant, no matter the camera distance from them.

I want to do the same with dashed line, but I noticed that dashNb can’t update.

So there is my method:

dash size attenuation | Babylon.js Playground (babylonjs.com)

red line is normal, I keep white line dash size constant

my method looks stupid, Is there a better way?

I think there’s no other way with the existing dash line builder.

Maybe @roland will have something for you in his
BabylonJS MeshLine - a port of THREE.MeshLine
?

Thanks!

constant dash size | Babylon.js Playground (babylonjs.com)

I try the ShaderMaterial, and done it.

but the color of line doesn’t work

You must set a value for the “color” uniform:

wow!

Now I get 4 forms to change color in my babylon app:

  1. shaderMaterial.setColor3('color', new BABYLON.Color3(0, 1, 0));

  2. normalLine.color = new BABYLON.Color3(0, 1, 0));

  3. material.diffuseColor = new BABYLON.Color3(0, 1, 0));

  4. sprite.color = new BABYLON.Color4(0, 1, 0);

I just want to change the color of picked thing, is there any way to simplify this?

Thank you! :smiley:

Not really. If the things you can pick are different (sprite, mesh, line, …), you have to change the color of the corresponding material.

Thanks!

and MeshLine much like THREE.Line2 I used in the three.js before, I just remember that the class had a serious memory issue, but it’s useful.

Maybe THREE.LineSegments2

Hello, there are too many warning, what should i do

There are two things:

  • the shader material used by the line mesh does not support the “store effect on sub-mesh” option, so you should pass false to the 4ith parameter of the ShaderMaterial constructor
  • the LineMesh class expects the color to be a Color4

Here’s the corrected PG:

1 Like

Thanks!

color doesn’t work again, i just let two line to use one material

Line.color = is terrible, It appears to modify the properties of the line, but actually it seems to affect the material

I guess I should do this

My app has thousands of lines, i just want to reduce the number of materials, because I found that every line automatically creates a material, regardless of whether they are the same color or not.

I guess that’s why line.dispose() will dipose my custom shader material.

I don’t know why LinesMesh extends Mesh,but too different usage and behavior

image

May be we need LineMaterial to replace the LineMesh.color and remove LineMesh.material.dispose() in LineMesh.dispose()

let material = new BABYLON.LineMaterial("line material", scene);
material.color = BABYLON.Color3.Red();
line.material = material;

That seems more reasonable, doesn’t it

Yes, GreasedLine has dash support.

const ls1 = GreasedLineBuilder.CreateGreasedLineSystem(
  'dashed-1',
  {
    points: line,
  },
  {
    dashArray: 1 / 10, // 1 / number of segments
    dashOffset: 0, // offset of the segment
    dashRatio: 0.1, // non-visible length of the segment
    useDash: true,
    color: Color3.Yellow(),
  },
  scene,
)

This piece of code geneates the first yellow line.
Changing dashRatio to 0.5 and you get the first green line.

Changing dashArray to to `1/20 and you get more segments (3rd and 4th lines)

Have a look at the example, the purple line is animated. Its dashOffset is incremented every frame:

https://demos.babylonjs.xyz/greased-line/dashes/

Full source:

import { GreasedLineBuilder } from './../GraesedLineBuilder'
import { GreasedLineMaterial } from '../GreasedLineMaterial'
import { ArcRotateCamera, Color3, Engine, RawTexture, Scene, Vector2, Vector3, VertexBuffer } from '@babylonjs/core'

export function dash(scene: Scene, camera: ArcRotateCamera) {
  let line = new Float32Array(600)
  for (var j = 0; j < 200 * 3; j += 3) {
    line[j] = -30 + 0.1 * j
    line[j + 1] = 5 * Math.sin(0.01 * j)
    line[j + 2] = -20
  }

  const ls1 = GreasedLineBuilder.CreateGreasedLineSystem(
    'dashed-1',
    {
      points: line,
    },
    {
      dashArray: 1 / 10, // 1 / number of segments
      dashOffset: 0, // offset of the segment
      dashRatio: 0.1, // non-visible length of the segment
      useDash: true,
      color: Color3.Yellow(),
    },
    scene,
  )

  //

  const ls2 = GreasedLineBuilder.CreateGreasedLineSystem(
    'dashed-2',
    {
      points: line,
    },
    {
      dashArray: 1 / 10, // 1 / number of segments
      dashOffset: 0, // offset of the segment
      dashRatio: 0.5, // non-visible length of the segment
      useDash: true,
      color: Color3.Green(),
    },
    scene,
  )
  ls2.position.y = 2

  //

  const ls3 = GreasedLineBuilder.CreateGreasedLineSystem(
    'dashed-3',
    {
      points: line,
    },
    {
      dashArray: 1 / 20, // 1 / number of segments
      dashOffset: 0, // offset of the segment
      dashRatio: 0.5, // non-visible length of the segment
      useDash: true,
      color: Color3.Yellow(),
    },
    scene,
  )
  ls3.position.y = 6

  //

  const ls4 = GreasedLineBuilder.CreateGreasedLineSystem(
    'dashed-3',
    {
      points: line,
    },
    {
      dashArray: 1 / 20, // 1 / number of segments
      dashOffset: 0, // offset of the segment
      dashRatio: 0.1, // non-visible length of the segment
      useDash: true,
      color: Color3.Green(),
    },
    scene,
  )
  ls4.position.y = 8

  //

  const ls5 = GreasedLineBuilder.CreateGreasedLineSystem(
    'dashed-animated-1',
    {
      points: line,
    },
    {
      dashArray: 1 / 20, // 1 / number of segments
      dashOffset: 0, // offset of the segment
      dashRatio: 0.3, // non-visible length of the segment
      useDash: true,
      width: 40,
      color: Color3.Purple(),
    },
    scene,
  )
  ls5.position.y = 12 

  //

  const ls5mat = ls5.material as GreasedLineMaterial
  let dashOffset = 0

  scene.onBeforeRenderObservable.add(() => {
    ls5mat.setDashOffset(dashOffset)

    dashOffset += 0.001 * scene.getAnimationRatio()
  })

  camera.radius = 86
}

r.

:vulcan_salute:

1 Like

There’s an optimization in the engine that won’t rebind an effect (material) if it was the last one to be bound. This is what happens for the two LineMesh that use the same material: the second LineMesh won’t rebind the material because it is already bound, and therefore the color won’t be updated.

You can overcome this problem by clearing the material cache of the scene after the material used by the LineMesh has been bound:

        shaderMaterial.onBindObservable.add(() => {
            scene.resetCachedMaterial();
        });

Here’s a corrected PG:

1 Like

You’re right that we should have the option to not dispose the material when disposing a LineMesh. This PR will allow it:

2 Likes

lot of interesting thing in babylon.js :smiley:

I noticed that the 2nd parameter of Node.dispose() is contrary to the definition of the 2nd parameter of LinesMesh.dispose() in your commit.

I’m afraid there will be wrong parameters when execute the LineMesh.parent.dispose() recursively

1 Like

You’re right, I should have kept the same signature than the base class.

Here’s the fix:

1 Like