last one for the road : https://playground.babylonjs.com/#LQVB2Y#14
Cool stuff buddy I am creating showcases for
GreasedLine
. Can I add your creations to the demo? Credits will be given of course. If you have any other ideas theyāre very welcome!
Thanks
Hey @Deltakosh!
I was working on optimalizations of the whole stuff and it got a full rewrite of the CPU part. Now the code is cleaner, faster and you can draw multiple lines with different widths in one draw call. Iād like to add support for different colors for the lines ofcourse in 1 draw call and it is missing positioning/rotation/scaling. Some GPU fragments needs to be added, depth buffer(?), fog(?)⦠I hope I can do the multicolor part and the pos/rot/scl part today. Maybe you can guys have a look at the code after I finish these tasks and review it.
I also added some SVG drawing capabilities to a separate utility class. I also created helper functions for drawing circles (ovals), arcs, grids, stuff to make the line more hires or lowres⦠However still tweaking them. I think full SVG support would be absolutely cool
I hope (I have a shitload of regular work) I can manage all of this (wo full SVG support) this week, so please stand by
Thanks!
r.
Multicoloring ready, at insane speedsā¦
Playing with widths and different z-offset for each country and the camera is rotatedā¦
EDIT:
Translation - Rotation - Scaling added as well.
Thanks! Yes, itās starting to be a really cool and powerful tool! There are so many use cases for it. I am preparing some demos and debugging the line routine at once. Just wait for it
some āinspirationā
.GitHub - rreusser/regl-gpu-lines: Pure GPU, instanced, screen-projected lines for regl
.GitHub - gl-vis/regl-line2d: Draw 2d polyline with regl
Iām so looking forward to this! I keep refreshing the page
Guys, Iāve added PBR support (95% ready) and I am playing with the stuff. Iāve realized there is quite much left to do. The separate line coloring requires the color tables and the color pointers at creation time and it should be quite challenging for beginners to create them correctly so I decided to create a builder classs which will allow to draw lines using a syntax like this:
const line = GreasedLineBuilder.createLine(params: GreasedLineParameters)
GreasedLineBuilder.addPoints(line: GreasedLine, points: Vector3[], colorStart: Color3, sizeStart: number, colorEnd?: Color3, sizeEnd?: number)
line.draw()
Different colors, different widths along the lines, 1 draw call.
Line thickness can be set for the upper part and the lower part of the line separatelly:
Supports glowing:
@inteja Thanks for your interest buddy! You can already play with it if you want, however a lot will change (and need to tide up code), so really just play with it and donāt use in your project yet. (I will rename the repo to babylonjs-greasedline soon)
There is a demos folder:
In main.ts
you need to call which demo you want to display:
@sebavan I need your help
const colorPointersBuffer = new Buffer(engine, this.colorPointers, true, 1)
this.setVerticesBuffer(colorPointersBuffer.createVertexBuffer('colorPointers', 0, 1))
colorPointersBuffer.update(array) // this is not updating the buffer
Do I need some additional steps to get the new buffer in the shader?
Looks superb @roland! Actually itās way more feature rich than I need for my use case! But no doubt all the extras youāre putting in will be great to have.
@roland I think your code should work. You should try to make a minimal repro with the code above.
Just to be sure: you add ācolorPointersā in the list of attributes when creating the shader?
@Evgeni_Popov Hello!
Yes, it works for the first time, but I canāt update it afterwards, no error, but nothing changes.
Are you sure array
has updated data? If yes, a repro will probably be needed to help further.
As expected Itās working. The amount of changes was so small that I couldnāt catch the changes with my eyesā¦
Thank you!
Hi @roland in the other thread you say:
I wrote some support functions to properly stretch the UVs through the line
Iāve been playing around with these a bit and they have the capacity to generate a lot of extra geometry. I realise the draw calls remain the same so maybe not such a big problem, but for optimal performance I was thinking it should be possible instead just to set or pass in UVs (based on segment length) while keeping vertex count the same, then using texture u and v scale to achieve desired repetition?
Hello, you can draw the whole stuff in one draw call. Iāll make it clear how to use when itās done
Hello!
Iām tweaking the LINE everyday and Iāve recently added offsets
so you can offset your points without recalculating and redrawing the whole line.
Here is a small demo using variable widths
and offset
and using dashArray
for the red line:
https://demos.babylonjs.xyz/greased-line/sound-analyzer/
Donāt forget to enable the audio.
I have more ideas to add but Iāll release the current version and will implement those ideas later.
Click on the canvas and press shift + ctrl + I
to open the Inspector.
R.
import {
Analyser,
ArcRotateCamera,
Color3,
Color4,
Engine,
RawTexture,
Scene,
Sound,
Vector2,
Vector3,
} from '@babylonjs/core'
import { GreasedLineMaterial } from './../GreasedLineMaterial'
import { GreasedLine } from './../GreasedLine'
export function spectrumAnalyzer(scene: Scene, camera: ArcRotateCamera) {
const engine = scene.getEngine()
scene.clearColor = new Color4(0, 0, 0, 1)
const numOfBars = 256
const barWidth = 3
const analyzerPoints = []
const offsets = []
for (let i = 0; i < numOfBars; i++) {
analyzerPoints.push(new Vector3(i * barWidth, 0, 0))
offsets.push(0, 0, 0, 0, 0, 0)
}
const wavePoints = [...analyzerPoints]
const analyzerLine = new GreasedLine(
'analyzer-line',
scene,
{
points: analyzerPoints,
},
true,
)
const waveLine = new GreasedLine(
'wave-line',
scene,
{
points: wavePoints,
offsets,
},
true,
)
waveLine.position = new Vector3(0, 30, 0)
const textureColors = new Uint8Array([255, 0, 0, 255, 255, 0, 0, 255, 0])
const texture = new RawTexture(
textureColors,
textureColors.length / 3,
1,
Engine.TEXTUREFORMAT_RGB,
scene,
false,
true,
Engine.TEXTURE_LINEAR_NEAREST
)
texture.wrapU = RawTexture.WRAP_ADDRESSMODE
texture.name = "analyzer-texture"
const analyzerMaterial = new GreasedLineMaterial('analyzerMaterial', scene, {
useMap: true,
map: texture,
opacity: 1,
sizeAttenuation: false,
lineWidth: 14,
})
const waveMaterial = new GreasedLineMaterial('waveMaterial', scene, {
color: Color3.Red(),
sizeAttenuation: true,
lineWidth: 14,
dashArray: 1 / numOfBars,
dashOffset: 0,
dashRatio: 0.4,
useDash: true,
alphaTest: 1,
})
analyzerLine.material = analyzerMaterial
waveLine.material = waveMaterial
camera.zoomOn([analyzerLine])
camera.radius = 530
camera.detachControl()
_drawGrid()
_startAudio()
_createAnalyzer()
function _startAudio() {
const music = new Sound('Music', 'mp3/glitch-flight-track.mp3', scene, null, {
loop: true,
autoplay: true,
})
}
function _drawGrid() {
const points:Vector3[][] = []
for(let i=0;i<numOfBars;i+=4) {
points.push([new Vector3(i*barWidth,-200,0), new Vector3(i*barWidth,200,0)])
}
for(let i=0;i<numOfBars;i+=2) {
points.push([new Vector3(0,i*barWidth-200,0), new Vector3(barWidth * numOfBars,i*barWidth-200,0)])
}
const grid = new GreasedLine("grid", scene, {
points
})
const gridMaterial = new GreasedLineMaterial("gridMaterail", scene, {
color: new Color3(0, 0, 0.6)
})
grid.material = gridMaterial
}
function _createAnalyzer() {
if (Engine.audioEngine) {
const analyser = new Analyser(scene)
Engine.audioEngine.connectToAnalyser(analyser)
analyser.BARGRAPHAMPLITUDE = 256
analyser.FFT_SIZE = 512
analyser.SMOOTHING = 0.7
const uvOffset = new Vector2(0, 0)
scene.onBeforeRenderObservable.add(() => {
const frequencies = analyser.getByteFrequencyData()
const widths = []
const offsets = []
for (let i = 0; i < numOfBars; i++) {
const normalizedFrequency = frequencies[i]
widths.push(normalizedFrequency, normalizedFrequency / 2)
offsets.push(0, normalizedFrequency, 0, 0, normalizedFrequency, 0)
}
analyzerLine.setWidth(widths)
waveLine.setOffsets(offsets)
analyzerMaterial.setParameters({
uvOffset,
})
uvOffset.x += 0.01 * scene.getAnimationRatio()
})
} else {
console.error('No audio engine.')
}
}
}