I am not familiar with three.js, but the properties of lights are often specified using uniforms. Uniforms are shader inputs, basically. You set them once before drawing, and their value stays the same for every vertex or fragment in that draw call. Hence the name "uniform". Typically, for a directional light you'll need a vec3 uniform for the light direction, and another vec3 uniform for the light color. Since many shaders support multiple directional lights, these uniforms might be declared as arrays like so:
uniform vec3 directionalLightColor[MAX_DIRECTIONAL_LIGHTS];
uniform vec3 directionalLightPosition[MAX_DIRECTIONAL_LIGHTS];
Chances are, three.js uses something like this. They will use the glUniform functions to set the directional light uniforms before each frame, and then all you have to do is declare the right uniforms in your shader, and then your shader can use those uniforms to access the light values.
This is just an educated guess, though. You'll need to find our what uniforms three.js is trying to set, and what their names and data types are. Unfortunately, the three.js documentation is completely unclear on this. So you might have to do some digging.
Concerning alpha blending, it's possible that you have blending disabled. In standard OpenGL, one would enable blending by calling glEnable with GL_BLEND passed in. You'll have to consult the three.js documentation to find out how to do this through their framework.
You'll also want to look into glBlendFunc to make sure you're using the right blend function (use GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA as the source and destination blend factors, respectively). Again, you may need to find the three.js equivalent of this.
Using alpha blending will not require multiple passes. However, if you get to a point where you're using multiple translucent objects in your scene, you'll need to sort them from back-to-front (so the distant ones are drawn first). The alpha blending function is not commutative, and so it has to be done in that order. This means it won't double your rendering time, but since you're sorting your draw calls by distance instead of by state, you'll incur some penalty there.
At some point, you may want to look into using premultiplied alpha.
It is not possible to know the values of the adjacent pixels. One big reason for this is that we can't be sure if those pixels have even been calculated yet. The pixel shader is executed in parallel for large batches of pixels at a time, and there's no way of knowing which pixels have been drawn and which haven't. Generally speaking, you can never read from the same buffer that you're drawing to.
As for reading the previous frame, there is no way to do that directly. You can do it indirectly, however, if you draw each frame to an off-screen texture. So, you would need two such textures (call them texture A and texture B). During the first frame, you render the scene to texture A. Then you copy that texture to the main back buffer. Then, on the next frame, you bind Texture A so that you can sample from it, and you draw the scene to Texture B. This allows you to sample from texture A while you draw the scene. Then, you copy texture B to the back buffer. On the third frame, you one again draw to texture A. At this point, texture B contains the previous frame, so you can sample from it. And so on, back and forth. Kind of a pain.
I'm not sure what grass effect you're after, but your fragment shader is only capable of drawing within the boundaries of the triangle that it is shading. So, it can't make anything seem to "pop out" of that triangle.