The kind of data that is passed between nodes depends on the types of nodes. But we can start off by talking about shaders. Your model of how data is passed between shaders is reasonable and fairly accurate. There is a large band of data which is passed from one shader to a next. Each shader modifies one or more of those data. Exactly what it modifies depends on what shader it is (and perhaps some of the selected options). It is designed this way so that shaders can do all sorts of different tasks, and can do so in any order that the user wants.
Let's say you have a Planet with just one shader plugged into it, as in the following simple diagram:
Shader
|
\/
Planet
When you get down to it, the line connecting the Planet and the shader doesn't actually contain much data. It is simply a pointer back to the shader that tells the Planet "this is the shader that you should use to shade the surface". During rendering, Terragen uses that pointer to know which shader to use to modify the surface of the planet. While rendering, Terragen will render many points on the planet. For each point that it renders, there is a broad band of data associated with that point. This band of data is called the
Render State. The Render State contains information about the position of the point, the surface normal, the surface colour, etc. For each point, the renderer
calls the shader to modify the Render State. This is known as "shading" the Render State. After the Render State has been shaded, the information in the state is used to render the point to the screen.
http://www.planetside.co.uk/wiki/index.php?title=Render_StateSo, during rendering you might think of it this way:
Unshaded Planet ==(Render State)==> Shader ==(Render State)==> Shaded PlanetUsually there is more than one shader affecting a planet. Usually, in the node network, they are chained one after the other via the "input node" plug. For example, let's say there's a shader called "Base Colours" connected to the Planet, and above this there is a "Fractal Terrain" shader plugged into the "input node" of "Base Colours", as follows:
Fractal Terrain
|
\/
Base Colours
|
\/
Planet.
This is a similar to the default project if you were to take out some of the other shaders. In this setup, "Base Colours" is used to shade each point on the planet. However, each time "Base Colours" is called, the first thing is does is call "Fractal Terrain", before doing any of its own modifications to the state. This causes Fractal Terrain to do all of its important work first, then pass the modified state to Base Colours, then Base Colours does all of its important work. The reason the renderer starts off by callling Base Colours is to give Base Colours the chance to modify the state before calling Fractal Terrain, if it wants to, thereby changing what Fractal Terrain will do. This sort of thing is done by Warp Shaders and other types of shader connections to change the texture coordinates used by the shaders that are input to them.
In the above example, you can think of the flow like this:
Unshaded Planet ==(Render State)==> Fractal Terrain ==(Render State)==> Base Colours ==(Render State)==> Shaded PlanetIt's a bit more complicated with some shaders such as the Warp Shader which do some work to modify texture coordinates
before they call their input shader:
Fractal Terrain
|
\/
Warp Input Shader
|
\/
Base Colours
|
\/
Planet
The above nodes cause a data flow like this:
Unshaded Planet ==(Render State with original texture coordinates)==> Warp Input Shader ==(Render State with warped texture coords)==> Fractal Terrain ==(Render State with warped texture coordinates)==> Warp Input Shader ==(Render State with original texture coordinates)==> Base Colours ==(Render State with original texture coordinates)==> Shaded PlanetThat looks like it calls the shaders in a strange, unexpected order, but this is how the data have to flow to give the result you want when you put the Warp Input Shader between Fractal Terrain and Base Colours. It looks complicated here, but it's easy for the system to do, because the system always calls the very last shader and each shader can choose how to call its input and what to do at each step. Even so, the node layout is quite simple.
Now, with other types of nodes, the connections may be used for other things. For example, a populator node has a connection to an object node, as in this example:
OBJ Reader
|
\/
Populator v4
Obviously the OBJ Reader can transmit object data to the populator, but the connection does more than that. As with the shader connection to the planet, the connection is really just a simple pointer back to the object node, and the populator may use this connection in various ways. One of the things it does is to change certain attributes on the object node automatically, such as settings its "population mode" to "Member of a population". A connection is not just a pipe for a specific kind of information - it is a way for the user to tell the system which nodes are supposed to interact with each other, and the system uses this information in ways that are most appropriate for the given task.
I haven't covered Function nodes (blue nodes) here. In some ways they are much simpler because they usually only modify a single piece of data (a vector of 3 values for vectors and colours, or a single value for scalars), but the system can automatically convert between these simple values and complete Render States depending on how the nodes are used. But I'll link to this as a starting point:
http://www.planetside.co.uk/wiki/index.php?title=Node_Input_Type_ConversionMatt