Originally posted by Inveramsay -
http://forums.firearms-source.com/sh...ghlight=custom
This tutorial aim at creating an alive water surface, it is done in two levels of difficulty, one using a completely custom water texture. This is recommended for experienced creators as it takes a really long time and will look like crap if you do it wrong. The easy one takes a minute or two to do but only allow you to change the colour and how foggy the water is.
I tried to learn this on my own but I didn't really like the tut I found on the web so I decided to one of my own. This is the first of my three sessions on creating advanced textures, the others will follow asap.
So you've decided to dabble with water textures. Let me tell you some tricks in making your water purty, first off, go off looking for a nice water texture . A water texture is a non-coloured texture in a size of 256 x 256 px. What makes the water come alive is the animated normal maps and dudv. Don't have a clue what these are then skip to the easy part. The reason the water is at 256 x 256 is that the texture would be far too big otherwise as many textured are used to create the movement of the water. The standard HL2 water consist of 29 frames, keep that in mind when creating. All water is consist of an animated base texture and a beneath water. Prettier water than the most basic contain an animated normal map and an animated dudv map as well. How much of theis you create is up tp you.
The hard way (for the easy way skip to the very last bit)
To do it the hard way you will need a photo of a water surface, preferably if it is possible a series in order to create the animated texture but you can distort the picture to get it to look nice. How you do it is up to you to discover, I would have gone with maybe 50 photos of a pond surface and made my texture out of them. If you go by distortion, try out the different filters there is in photoshop, you don't have to make em seamless if you're unsure about the results. Normal maps encode height in a texture and dudv maps encode height used for refraction of the surface.
Just a bit of advice: to get something to move, you animate textures, in theory it's real easy but irl it can be a bit of a hassle. You need smooth transitions and not to much then it will look crap later in the animation cycle.
1. Pick a series of pictures of at least ten, preferably more but too many will be harder to distribute and use more memory resources as they will be larger. They all need to be seamless. They also don't have to be anywhere near the right colour you want, that will be dealt with later on. You can use the slideshow function in windows to look at them so they don't look too jumpy after smoothing em out. Call them for example water000, it is only the numerical ending which is important. If you have ten frames then save the first one as 000 and 018, the second as 001 and 017 and so on. This is so the the animation will go back to it's original starting point without a jump. You can create an alpha channel for each of them as well so they get transparent. Save all of them also as water_dx70 as well. This will be your fall back material for low end systems.
2. Load up crazybump to create normalmaps:
http://www.crazybump.com/beta/download.html Create normalmaps for all of the textures calling them for example water_normal000 and so on. They are supposed to end with _normal in order for vtex to figure the file out correctly. Save all of them with the same numbers and a _dudv ending as well instead of the _normal.
3. Place all of the normal maps and standard .tga's in your materialsrc sub folder and create a text file with the same name as the texture containg this:
"startframe" "000"
"endframe" "0xx" //where xx replaced by the last number in the series.
For the dudv files to process correctly add the line "normaltodudv" "1" as well as well as startframe etc.
For the standard texture: do the same as normal map .txt
Now compile all three of them, as you can see the files get to be rather large.
Now you have created the all of your necessary textures, now only the .vmt's remain. You will need five .vmt's, one called water_expensive (or whatever you decide to call your water) water_cheap and water_beneath and water_dx70 and water_beneath_dx70
The water_expensive should contain:
"Water"
{
"Water_DX60"
{
"$fallbackmaterial" "inveramsay/water_dx70"
}
"Water_DX80"
{
"$refractamount" ".13"
}
"Water_DX81"
{
"$refractamount" ".13"
}
"$abovewater" 1
"%tooltexture" "inveramsay/water_normal"
"$refracttexture" "_rt_WaterRefraction"
"$refractamount" "1.0"
"$refracttint" "[0.9 1.0 0.95]" //This is where you decide the tint of the refraction
"$reflecttexture" "_rt_WaterReflection"
"$reflectamount" "1.0"
"$reflecttint" "[.9 .9 .9]" //This is where you decide the tint of the relection
"$envmap" "env_cubemap"
"$scale" "[1 1]"
"$bumpmap" "inveramsay/water_dudv"
"$normalmap" "inveramsay/water_normal"
"%compilewater" 1
"$surfaceprop" "water"
"$bottommaterial" "inveramsay/beneath"
"$subdivsize" 64
"$bumpframe" "0"
"$fogenable" 1
"$fogcolor" "{61 129 230}" //This is where you change fog colour as well as the colour of the waters appereance, should be the same for both beneath water and above water
"$fogstart" 0 //This has to be set to zero to work properly
"$fogend" 1200.00 //Max distance you can see through the fog
"$bumpoffset" "[0 0]"
"Proxies"
{
"AnimatedTexture"
{
"animatedtexturevar" "$normalmap"
"animatedtextureframenumvar" "$bumpframe"
"animatedtextureframerate" 30.00 //This is standard HL2 animation speed, depends on your number of frames, the number is likely going to need tweaking unless you have 29 frames.
}
"TextureScroll"
{
"texturescrollvar" "$bumptransform"
"texturescrollrate" .05
"texturescrollangle" 45.00
}
"WaterLOD"
{
}
}
}
water_cheap should contain:
"Water"
{
"Water_DX60"
{
"$fallbackmaterial" "inveramsay/water_dx70"
}
"%compilewater" 1
"$forcecheap" 1
"$CHEAPWATERSTARTDISTANCE" 500.0
"$CHEAPWATERENDDISTANCE" 1000.0
"$envmap" "env_cubemap"
"%tooltexture" "inveramsay/water_normal"
"$refractamount" "1.0"
"$refracttint" "[0.95 1.0 0.97]"
"$reflectamount" "1.0"
"$reflecttint" "[1 1 1]"
"$refracttexture" "_rt_WaterRefraction"
"$reflecttexture" "_rt_WaterReflection"
"$scale" "[1 1]"
"$bumpmap" "inveramsay/water_dudv"
"$normalmap" "inveramsay/water_normal"
"$surfaceprop" "water"
"$bottommaterial" "inveramsay/water_beneath"
"$bumpframe" "0"
"$fogenable" 1
"$fogcolor" "{20 130 20}"
"$fogstart" 0.00
"$fogend" 400.00
"Proxies"
{
"AnimatedTexture"
{
"animatedtexturevar" "$normalmap"
"animatedtextureframenumvar" "$bumpframe"
"animatedtextureframerate" 30.00
}
"TextureScroll"
{
"texturescrollvar" "$bumptransform"
"texturescrollrate" .05
"texturescrollangle" 45.00
}
"WaterLOD"
{
}
}
}
water_beneath should contain:
"Water"
{
"Water_DX60"
{
"$fallbackmaterial" "nature/water_beneath_dx70"
}
"$abovewater" 0
"%compilewater" 1
"$CHEAPWATERSTARTDISTANCE" 500.0
"$CHEAPWATERENDDISTANCE" 1000.0
"%tooltexture" "inveramsay/water_normal"
"$refractamount" "1.0"
"$refracttint" "[0.95 1.0 0.97]"
"$reflectamount" "1.0"
"$reflecttint" "[1 1 1]"
"$refracttexture" "_rt_WaterRefraction"
"$scale" "[1 1]"
"$bumpmap" "inveramsay/water_dudv"
"$normalmap" "inveramsay/water_normal"
"$surfaceprop" "water"
"$bumpframe" "0"
"$fogenable" 1
"$fogcolor" "{22 20 10}"
"$fogstart" 1.00
"$fogend" 400.00
"Proxies"
{
"AnimatedTexture"
{
"animatedtexturevar" "$normalmap"
"animatedtextureframenumvar" "$bumpframe"
"animatedtextureframerate" 30.00
}
"TextureScroll"
{
"texturescrollvar" "$bumptransform"
"texturescrollrate" .05
"texturescrollangle" 45.00
}
"WaterLOD"
{
}
}
}
Water_dx70 should contain
"LightmappedGeneric" //this water doesn't use the expensive water shader and is excellent for performance
{
"$basetexture" "inveramsay/water"
"$color" "{160 187 201}"
"$scale" "[1 1]"
"$translucent" "1"
"%compilewater" 1
"$surfaceprop" "water"
"$bottommaterial" "inveramsay/water_beneath_dx70"
"$bumpframe" "0"
"$fogenable" 1
"$fogcolor" "{25 25 15}"
"$fogstart" 0.00
"$fogend" 150.00
"$abovewater" 1
"$texoffset" "[0 0]"
"$texscale" "0.5"
"Proxies"
{
"AnimatedTexture"
{
"animatedtexturevar" "$basetexture"
"animatedtextureframenumvar" "$frame"
"animatedtextureframerate" 20.00
}
"TextureScroll"
{
"texturescrollvar" "$texoffset"
"texturescrollrate" .025
"texturescrollangle" 45.00
}
"TextureTransform"
{
"translateVar" "$texoffset"
"scaleVar" "$texscale"
"resultVar" "$basetexturetransform"
}
}
}
water_beneath_dx70 should contain:
"LightmappedGeneric"
{
"$abovewater" 0
"%compilewater" 1
"$basetexture" "inveramsay/water"
"$scale" "[1 1]"
"$translucent" "1"
"$nocull" "1"
"$surfaceprop" "water"
"$fogenable" 1
"$fogcolor" "{25 25 15}"
"$fogstart" 0.00
"$fogend" 450.00
"$texoffset" "[0 0]"
"$texscale" "0.5"
"Proxies"
{
"AnimatedTexture"
{
"animatedtexturevar" "$basetexture"
"animatedtextureframenumvar" "$frame"
"animatedtextureframerate" 20.00
}
"TextureScroll"
{
"texturescrollvar" "$texoffset"
"texturescrollrate" .025
"texturescrollangle" 45.00
}
"TextureTransform"
{
"translateVar" "$texoffset"
"scaleVar" "$texscale"
"resultVar" "$basetexturetransform"
}
}
}
These are your five .vmt's. Replace all inveramsay with the folder you are working from as usual.
From this you have created a new custom water from which you can create an endless stream of different water colours. Valve only made one base water texture and used it throughout the entire of HL2 but changed the tints and the fog colour and fog distances to get the different colours you can see in game.
Here follows the easy way to create a new water, almost no hassle, distributes are small and easy and you don't have to work for more than two minutes to get a colour you want. Go ahead and create new .vmt's and alter the tints, fog color and fog distance to create the kind of water you want. All you distribute are some new .vmt's each at a size of 2kb instead of a 30 mb water texture.
.vmt for an expensive water:
"Water"
{
"Water_DX60"
{
"$fallbackmaterial" "nature/water_canals03_dx70" //Create a fall back material of your own if you want to
}
"Water_DX80"
{
"$refractamount" ".13"
}
"Water_DX81"
{
"$refractamount" ".13"
}
"$abovewater" 1
"%tooltexture" "dev/water_normal"
"$refracttexture" "_rt_WaterRefraction"
"$refractamount" "1.0"
"$refracttint" "[0.9 1.0 0.95]" //change to get another tint of the refraction
"$reflecttexture" "_rt_WaterReflection"
"$reflectamount" "1.0"
"$reflecttint" "[.9 .9 .9]" //Change this as well
"$envmap" "env_cubemap"
"$scale" "[1 1]"
"$bumpmap" "dev/water_dudv" //Use valves own
"$normalmap" "dev/water_normal" //same as above
"%compilewater" 1
"$surfaceprop" "water"
"$bottommaterial" "inveramsay/beneath" //Bottom material is needed as well
"$subdivsize" 64
"$bumpframe" "0"
"$fogenable" 1
"$fogcolor" "{61 129 230}" //This is where you control the colour of the water, should be the same for both the above and beneath waters
"$fogstart" 0
"$fogend" 1200.00 //How foggy the water should appear, the number tell you the max view distance in inches
"$bumpoffset" "[0 0]"
"Proxies"
{
"AnimatedTexture"
{
"animatedtexturevar" "$normalmap"
"animatedtextureframenumvar" "$bumpframe"
"animatedtextureframerate" 30.00
}
"TextureScroll"
{
"texturescrollvar" "$bumptransform"
"texturescrollrate" .05
"texturescrollangle" 45.00
}
"WaterLOD"
{
}
}
}
for a cheap water:
"Water"
{
"Water_DX60"
{
"$fallbackmaterial" "nature/water_dx70"
}
"%compilewater" 1
"$forcecheap" 1
"$CHEAPWATERSTARTDISTANCE" 500.0
"$CHEAPWATERENDDISTANCE" 1000.0
"$envmap" "env_cubemap"
"%tooltexture" "dev/water_normal"
"$refractamount" "1.0"
"$refracttint" "[0.95 1.0 0.97]"
"$reflectamount" "1.0"
"$reflecttint" "[1 1 1]"
"$refracttexture" "_rt_WaterRefraction"
"$reflecttexture" "_rt_WaterReflection"
"$scale" "[1 1]"
"$bumpmap" "dev/water_dudv"
"$normalmap" "dev/water_normal"
"$surfaceprop" "water"
"$bottommaterial" "inveramsay/water_beneath"
"$bumpframe" "0"
"$fogenable" 1
"$fogcolor" "{113 202 255}"
"$fogstart" 1.00
"$fogend" 400.00
"Proxies"
{
"AnimatedTexture"
{
"animatedtexturevar" "$normalmap"
"animatedtextureframenumvar" "$bumpframe"
"animatedtextureframerate" 30.00
}
"TextureScroll"
{
"texturescrollvar" "$bumptransform"
"texturescrollrate" .05
"texturescrollangle" 45.00
}
"WaterLOD"
{
}
}
}
beneath water
"Water"
{
"Water_DX60"
{
"$fallbackmaterial" "nature/water_dx70_beneath"
}
"$abovewater" 0
"%compilewater" 1
"$CHEAPWATERSTARTDISTANCE" 500.0
"$CHEAPWATERENDDISTANCE" 1000.0
"%tooltexture" "dev/water_normal"
"$refractamount" "1.0"
"$refracttint" "[0.95 1.0 0.97]"
"$reflectamount" "1.0"
"$reflecttint" "[1 1 1]"
"$refracttexture" "_rt_WaterRefraction"
"$scale" "[1 1]"
"$bumpmap" "dev/water_dudv"
"$normalmap" "dev/water_normal"
"$surfaceprop" "water"
"$bumpframe" "0"
"$fogenable" 1
"$fogcolor" "{22 20 10}"
"$fogstart" 1.00
"$fogend" 400.00
"Proxies"
{
"AnimatedTexture"
{
"animatedtexturevar" "$normalmap"
"animatedtextureframenumvar" "$bumpframe"
"animatedtextureframerate" 30.00
}
"TextureScroll"
{
"texturescrollvar" "$bumptransform"
"texturescrollrate" .05
"texturescrollangle" 45.00
}
"WaterLOD"
{
}
}
}
then some fallback materials:
above water
"LightmappedGeneric"
{
"$basetexture" "dev/water"
"$color" "{130 144 169}"
"$scale" "[1 1]"
"$translucent" "1"
"%compilewater" 1
"$surfaceprop" "water"
"$bottommaterial" "nature/water_dx70_beneath"
"$bumpframe" "0"
"$fogenable" 1
"$fogcolor" "{25 25 15}"
"$fogstart" 0.00
"$fogend" 150.00
"$abovewater" 1
"$texoffset" "[0 0]"
"$texscale" "0.5"
"Proxies"
{
"AnimatedTexture"
{
"animatedtexturevar" "$basetexture"
"animatedtextureframenumvar" "$frame"
"animatedtextureframerate" 20.00
}
"TextureScroll"
{
"texturescrollvar" "$texoffset"
"texturescrollrate" .025
"texturescrollangle" 45.00
}
"TextureTransform"
{
"translateVar" "$texoffset"
"scaleVar" "$texscale"
"resultVar" "$basetexturetransform"
}
}
}
and then beneath water
"LightmappedGeneric"
{
"$abovewater" 0
"%compilewater" 1
"$basetexture" "dev/water"
"$scale" "[1 1]"
"$translucent" "1"
"$nocull" "1"
"$surfaceprop" "water"
"$fogenable" 1
"$fogcolor" "{25 25 15}"
"$fogstart" 0.00
"$fogend" 450.00
"$texoffset" "[0 0]"
"$texscale" "0.5"
"Proxies"
{
"AnimatedTexture"
{
"animatedtexturevar" "$basetexture"
"animatedtextureframenumvar" "$frame"
"animatedtextureframerate" 20.00
}
"TextureScroll"
{
"texturescrollvar" "$texoffset"
"texturescrollrate" .025
"texturescrollangle" 45.00
}
"TextureTransform"
{
"translateVar" "$texoffset"
"scaleVar" "$texscale"
"resultVar" "$basetexturetransform"
}
}
}
And off you go, now you have created your water texture. Valve made some really nice ground work with the normal maps of the water, it's up to you to use them or not.