A function only landscape

Started by David Burnett, February 18, 2007, 08:19:57 AM

Previous topic - Next topic

David Burnett

I will go in the tutorial section eventually, I've put it here for now for better feedback.

Dave

cyphyr

#16
This looks extremly prommising, thanks for the file and the explanations.

On an allied subject, I was wondering if it would be possible to use functions to work out the "depth" of a water plane (it may be necessary to use a simple imported plane with a water shader attached, or even construct a custom water shader more fit for pourpose) so one could give it a degrading transparency dependant on the virtical distance to the terrain benieth it. Hopefully this would allow us to have transparant edges to our water effects and the possibility of changing the hue of the water according to the derrived "depth". I'll have an investigate when I get home after the eclipse and if I can understand Davids tutorial I'll post my results.

Richard Fraser
cyphyr
www.richardfraservfx.com
https://www.facebook.com/RichardFraserVFX/
/|\

Ryzen 9 5950X OC@4Ghz, 64Gb (TG4 benchmark 4:13)

dhavalmistry

Quote from: David Burnett on March 02, 2007, 08:09:05 AM
Tell me where you get lost and I'll try and clarify the bit's you don't understand.

Dave

I am sorry Dave I didnt meant to say I was lost in your tutorial but I am lost because I dont know what any of the functions mean and what they do.
"His blood-terragen level is 99.99%...he is definitely drunk on Terragen!"

Sengin

I doubt it, but is there a way to "trick" TG2 into using functions that can have more than one z value for an x value?  (yes, I know it's not called a function then)  Maybe by using a few condintional scalars or something?

David Burnett

I'm not at my Mac at the moment however from memory in Get Functions/Convert there's a function called ...erm... something like Build Vertex.

It excepts co-ordinates in the input node then allows you to replace the x, y and/or z co-ordinates with another scalar feed using the three other input. If you replace all three you probably do not need  anything attached the input node.

So for example
Using Get Position feeding into a Z to scalar and the Build Vertex (or whatever it is called) input node, with the Z to Scalar feed into the y input, you would get co-ordinates using x,z,z.

You could use a similar arrangement but with a conditional scalar between the Z to scalar and Build Vertex, with the conditional scalar feeding into the Build Vertex's z input.

You could feed Get Position into a number of Build Vertex's and replace the z co-ordinate with different scalars.


Do any of those fit your needs?

Dave

David Burnett

Tutorial Part Three

A Detour into Perlin's Noise.


Ken Perlin's noise function forms the basis of much that is good about Terrain Generators, from
Ken Musgrave's early images to the quite possibly the last thing you rendered in TG2.

At its heart it's very simple, it just interpolates between a grid of random vectors, and
it creates noise that looks like this.

Figure 1.
[attachimg=1]

Not very terrain like is it. To make it more interesting Perlin introduced Turbulence.
Given a function perlin(x, y, z) we then add 0.5 * perlin (x*2.0, y*2.0, z*2.0)
then 0.25 * perlin (x*4.0, y*4.0, z*4.0) and so on....

value =
   perlin(x, y, z)  +
   0.5     * perlin (x*2.0,  y*2.0,  z*2.0) +
        0.25    * perlin (x*4.0,  y*4.0,  z*4.0) +
        0.125   * perlin (x*8.0,  y*8.0,  z*8.0) +
        0.0625 * perlin (x*16.0, y*16.0, z*16.0)


Each line is called an octave, a word you might have seen on the power fractal shader.
The effect of each octave is to shrink the grid of random vectors, adding more detail to
the noise. This is why decreasing the smallest scale on the Power Fractal Shader increases the number of
Noise Octaves and vice versa, to add more detail you need to add more octaves.

Figure 2.
[attachimg=2]


The Perlin Function in T2TP is very simple, there's no turbulence to make things interesting
unless you willing to manually create a node tree to do it. This however does not make it totally unless,
and I'll use it twice for the function only image we're creating.

Let's a see see what we can do with it first.

Start with a new TGD, delete the height field shader and generator.
Add the Displacement Shader and join it to Compute Terrain.

Add the Perlin noise function, Create Function/Noise/Perlin 3D scalar
Connect it to the Displacement Shader function input

The 3D preview will still be flat, we need to feed it co-ordinates.

Add a Get Position function
Connect it the the left hand input (input node) on the Perlin 3D scalar function.

It still looks flat, but you may notice some patterning. The problem is the camera is
too high, we start a 1000 metres up, bring into down to 10 metres, and volia bumps
on the ground. If you move your cursor over the preview you'll notice that the bumps
are around metre apart. This gives a degree of predictabilty and makes it useful for distorting things.
It's also the reason you need turbulence to make interesting terrains.

The Perlin 3D scalar function has two other inputs, the first is scale. This scales the co-ordinates going into the noise.
The second is seed, which changed the random value generation, change it an you get another variation on the same noise.

Add a Get Constant Scalar function. Set the value to 2.
Attach it to the scale input of the  Perlin 3D scalar function

The distance between peaks should now be around 2 metres. Change the constant to 10, the peaks are now 10 metres apart,
and the terrian has a more gentle look to it.

Scale does not have to be a constant, lets have some fun.

Move the Render camera to 0,10,0 with a rotation of -90,0,0 which is looking straight down.
Disconnect the Constant from the scale input.
Add a Sin function (Get Function/Trig/Sin Scalar).
Connect the Sin function to the scale input of the Perlin 3D scalar.

If you select the Sin function you'll see you get a series of rings in the noise preview.

In the 3D preview the peaks are close together where the Sin function returns small values,
and further part where the Sin function returns larger values. A rendered version looks like this...

Figure 3.
[attachimg=3]

Another common use for Perlin's Noise is to distort things. There's a number of ways to do this. We could
simply add the noise to roughen things up, add the noise to co-orinates going into other functions or shaders
or to simply add the noise to other parameters into into functions.

Lets start from scratch.

Add a Get Position Function, an X to Scalar Function, and a Sin scalar function, and join them together
in that order.
Add a Displacement shader and join the Sin function to the function input of the Displacement shader and the output
of ther Displacement to the Compute Terrain as usual.
Change the Camera to position 0,25,0 with a rotation of -90,0,0.
Change the Sun to a angle of 45.

You should have a ploughed field look. Let's add some noise to the X co-ordinate.

Add a Perlin 3D scalar and an Add Scalar function.
Connect the Get Position to the Perlin 3D scalar, The Perlin 3D Scalar and the X to Scalar to the Add Scalar.
Connect the Add Scalar node to the Sin Scalar node.

There should now be indentations now (Fig 4 'a') 

Add a Constant Scalar, set to 20, and connect it to the Scale input of the Perlin 3D scalar.

The smoothnes is back, but you may notice some subtle distortions, the poughing is not as straight as
it used to be. Set the Camera to 0,100,0 to see it a little better. (Fig 4 'b')

Perlin noise tends to give values between -1.0 and +1.0 so lets increase those and see what happens.

Add a Mulitply Scalar. Connect the Perlin 3D scalar and the Constant Scalar to the Multiply scalar.
Use the Multiply Scalar output to replace the Perlin 3D Scalar input to the Add Scalar.

That distortion is not so subtle now is it (Fig 4 'c') :-)


Now lets change things around.

Delete the Multiply Scalar node and the Constant Scalar.
Connect the X to Scalar node back directly to the Sin Scalar node, and feed the Sin Scalar node
and Perlin 3D Scalar node into the Add Node. The Add Node now feeds into the Displacemet Shader.

This looks like the original distored render but is subletly different (Fig 4 'd').

Figure 4.
[attachimg=4]

old_blaggard

Thanks for the very descriptive tutorial!  You're really helping to make the functions more understandable to those of us who haven't got math degrees ;).
http://www.terragen.org - A great Terragen resource with models, contests, galleries, and forums.

Sengin

#22
Quote from: David Burnett on March 09, 2007, 05:54:28 AM
Do any of those fit your needs?

Hmmm...I'm not sure.  Basically I had an idea that it might be possible to create waves with crests using functions to connect to the water shader of a lake object.  I came up with two intersecting circles that I thought would at least be a proof on concept (see image below, yes, I know those aren't circles, it's just a quick image in ms paint).  But the condition statement would have to be if the calculated value is less than Eq 1 AND greater than Eq 2, then use that value.  But it would also have more than one height for a value of x, and it wouldn't be considered a "function" anymore.  I believe the equations I used were y=sqrt((x-0.5)^2 - 0.55)-0.25 and y=sqrt((x-0.25)^2 - 0.32)-0.25, butI could be mistaken because I don't have the calculator I used to try those equations with me and have since changed the equation in the .tgd.  I do know the equations are similar to the ones above, just some of the constants might be a little off.  I also tried using two intersecting circles that didn't have more than one value for every x, but the terrain rendered wasn't there (it just rendered black, and I made sure the camera was above ground), so I don't think terragen likes the equation for circles (it probably has to do with the fact of the square root of negative numbers and such - I used the min conditional you had used for your sand dunes, but modified for my function).  Do you have any ideas on how this idea could be implemented with functions?  If the circles can be a proof of concept, then I'm sure a more complicated a more realistic looking wave/crest could be thought up (using ellipses/more than 2 equations/etc...).

David Burnett

Okay I get what to want now but I'm not sure if I can help you.

Using the displacement shader is more about moving terrain straight up, well along the normal to be accurate.
I would guess that your algorithm requires new geometry, or volumetrics.

It might be interesting to try an acute triangle as a wave and then use the redirection shader to curve it based on
height.

Dave

David Burnett

All right so an acute triangle was not that good so I tried exp(sin(x)) instead.
Anyone got a board...

[attachimg=1]




Sengin

#25
Hey, cool.

Ok, I came up with another idea for using functions to make wave crests involving ellipses (http://www.analyzemath.com/EllipseEq/EllipseEq.html).  But instead of trying it the same way, I'm trying it a bit differently.  First, I want two equations for ellipses to be computed, but only used if the number before taking the square root is positive (to get rid of any sqare root of negative numbers - that would be bad because I don't think TGD2 can support imaginary numbers :P).  Let's call that result Q1 and Q2.  I then want to get the altitude of that position where the X value computed came from (let's call that value Y because it's the altitude).  If Y is less than or equal to Q1 AND greater than or equal to Q2, I want the computer terrain to use that Y value for it's generation of terrain.  But as you can guess, it doesn't work (all I get is a flat terrain).  I'm guessing my problem is not knowing what shader or something to use the functions for, or an error on using the altitude.  I've tried using a displacement shader into the compute terrain, and I've tried using it into the displacement input for a surface layer.  I don't know anything else to try to acheive my idea, but I have a feeling it can work because it's not relying on functions to generate the terrain, but rather the boundaries.  Can anyone help me here on a correct shader or something?  Oh, nevermind the default shaders, the names are just reference for the equations used and the default equation for an ellipse.

old_blaggard

I wonder if a similar thing could be done using some form of calculus.  In class right now we're doing integrals, which (for those who don't know) is using calculus functions to find the area under a curve.  When you subtract two integrals, you find the area between the curves.  I wonder if you could define a repeating curve (maybe a sine function of some sort) and another (maybe a slightly offset sine curve), take the integrals, subtract them, and have your waves.

I don't pretend to be an expert on this, as I haven't even finished the calculus class and am just diving into function nodes, but it seems like a possibility.
http://www.terragen.org - A great Terragen resource with models, contests, galleries, and forums.

Sengin

#27
Hmm..I don't think so.  Integrals are used to find only the area between two curves, it doesn't define any shape (the "shape" is defined by the two curves).  If you were to find the integral, you're left with just a number, the area.  You wouldn't be able to do anything with that number.

old_blaggard

Well, for the record, you can also use integrals to rotate images and find their volume, but in this case the next step would be to stretch the two-dimensional area laterally to get a straight 3-D figure shaped like a wave.
http://www.terragen.org - A great Terragen resource with models, contests, galleries, and forums.

Sengin

Quote from: old_blaggard on March 13, 2007, 09:26:35 PM
Well, for the record, you can also use integrals to rotate images and find their volume

Right, but I meant for the example you provided.