I hope this does not get interpreted the wrong way since i’ve been a bit critical of the TSL.
I understand that there is an example with TSL that you are trying to follow. However, TSL is very new, and specific to three.js, while shaders like GLSL are generic. This means that in order to get help about this, someone has to be familiar with both shaders in general, and the syntax/system for TSL which is quite prone to change. Sure, a lot of people seem to be experimenting with it, but GLSL has been around for more than a decade.
Would it make sense for you to try to do this with ShaderMaterial
and WebGLRenderer
first and then move to the more modern approach? There should be examples on how to do that. I looked at your code, but i don’t understand anything unfortunately, while in theory, i know how this can be done 
For starters, i wouldn’t touch buffers and neighbors on the mesh itself. I would process the height texture to create a normal map. At least thats where my mind is at, as this could also be done less frequently than your render rate. Ie, rather than looking up neighbors every frame, you would look them up once you receive the texture. I imagine that there is a texture involved since i dont see any other way to do this:
edit
I’ve been able to assign vNormal
to your output, and i got green, so it looks like all your normals are 0,1,0. But yikes, i don’t understand anything else in the code.
edit2
position.y.addAssign( heightNode2);
neighbourA.y.addAssign( heightNode2);
neighbourB.y.addAssign( heightNode2);
You do most likely want to change this. I’m not sure what the expectation here is, but it’s probably not doing what you want, since it’s the same value being assigned to the neighbors as is to your point of interest. But again this is all very confusing. You probably dont want heightNode2
to be assigned to the both neighbors. If using buffers you proba bly want to create a new buffer that has the neighbor information for the point. But this seems awkward and inefficient unless there is something with WebGPU which im unfamiliar with. If you do read these from a texture though, then it becomes easier - for the point itself, you would read the texture at that point. For the neighbors you would read the texture at neighboring points.