more about terrain shaders

continuing for bigkahunas question-the multitexture stuff is almost but not quite working for me yet:

I need to use one UV map for the textures soo I can tile them and a second UV map for the alpha maps which separate cliff and grass. But wait it doesn’t end there, because I also need a self illuminating (or lightmap) channel which also uses the alpha UV map so I can add self light and shadows into the mix - lol, not asking much then. Is it right that I’m thinking all these things need to be in one shader to get what I’m after?
I noticed in the source of the lightmap shader there is this:

// Ambient pass
	Pass {
		Name "BASE"
		Tags {"LightMode" = "PixelOrNone"}
		Color [_PPLAmbient]
		BindChannels {
			Bind "Vertex", vertex
			Bind "normal", normal
			Bind "texcoord1", texcoord0 // lightmap uses 2nd uv
			Bind "texcoord", texcoord1 // main uses 1st uv

Would it be relevant for me to think in terms of somehow trying to combine this with the multitexture stuff?

TIA for any help. On the plus side I wrote my first script today without asking anyone - ha, triggering lights to switch on and off yay :wink:
Boxy

Sorry to be persistent, I realise I’m trying to fly at supersonic speed before walking but I’m nearly there :slight_smile:
I have used Pete’s mountain shader as a base and have just been experimenting while trying to follow the docs, but I am not understanding what blending method I need to use to make the base rock texture show through. I just know my error will show how spectacularly ignorant I am at writing shaders, but that’s because I (currently) am.
I’d really appreciate any help.
Thanks
Boxy

Shader "Three Layers" {
	Properties {
		_Color ("Main Color", Color) = (1,1,1,1)
		
		_MainTex ("Base (RGB)", 2D) = "white"
		_MainTexMask ("Base Mask (Grey)", 2D) = "white"
		
		_Layer1 ("Layer 1 (RGB)", 2D) = "white"
		_Layer1Mask ("Layer 1 (Grey)", 2D) = "white"
		
		_Layer2 ("Layer 2 (RGB)", 2D) = "white"
		_Layer2Mask ("Layer 2 (Grey)", 2D) = "white"
	}
	
	
	SubShader {
	
			Pass{
            Material { 
            Diffuse (0,0,0,0) 
            }
            Blend one one
			SetTexture [_MainTex] 
			SetTexture [_MainTexMask] { combine texture * previous }
			} // end pass
			
		
		Pass{ 

		SetTexture [_Layer1Mask]   
       		SetTexture [_Layer1] { combine texture * previous }
          	} // end pass  


		Pass{
		Blend one one  
		SetTexture [_Layer2Mask] 
       		SetTexture [_Layer2] { combine texture * previous }
          	} // end pass  		
	} 
	
	FallBack " Diffuse", 1
}

EDIT: I should add that I suspect the problem is

Pass{ 

		SetTexture [_Layer1Mask]   
       		SetTexture [_Layer1] { combine texture * previous }
          	} // end pass

If I put Blend one one at the beginning of this pass it bleaches the whole effect out, which confuses me because i understand Blend one one to be a multiply whereas the effect is more like a Screen.
Thanks
Boxy

Well, in the slight chance that some other complete ‘cut paste and see what happens’ shade scripting virgin comes across this and is scratching their head, it was a lot simpler than I thought - more a matter of finding the right combination of blends for the masks in Photoshop rather than in code.
Thanks to everyone who helped and provided the code over the last couple of weeks, I can only apologise for being very slow at picking some things up!!

Edit: I have no idea if the code is as it should be but it seems to work as I wanted, so if I have put things in there which are unnecessary please do tell me, gotta learn somehow :slight_smile:
Boxy

Shader "Three Layers" {
	Properties {
		_Color ("Main Color", Color) = (1,1,1,1)
		
		_MainTex ("Base (RGB)", 2D) = "white"
		_MainTexMask ("Base (Grey)", 2D) = "white"
		
		_Layer1 ("Layer 1 (RGB)", 2D) = "white"
		_LayerMask ("Layer 1 Mask (Grey)", 2D) = "white"
		
		_Layer2 ("Layer 2 (RGB)", 2D) = "white"
		_LayerMask2 ("Layer 2 Mask (Grey)", 2D) = "white"
	}
	
	
	SubShader {
			
		Pass{
		Lighting On
            Material { 
            Diffuse (0,0,0,0)
            Ambient [_Color] 
            }
         
			} // end pass
			
		
		Pass{ 
	       SetTexture [_LayerMask]   
       	SetTexture [_Layer1] { combine texture * previous }
          	} // end pass  


		Pass{
	  		Blend one one
			        SetTexture [_LayerMask2] 
       			 SetTexture [_Layer2] { combine texture * previous }
          	} // end pass  
          	
          	
        Pass{
		     Blend one one
				     SetTexture [_MainTexMask]
			        SetTexture [_MainTex] {combine texture * previous}
			   } // end pass
		
	} 
	
	FallBack " Diffuse", 1
}

Lol
I know I’m just talking to myself here but its all very exciting when against all odds the things you hope happen happen.

Rock with detail texture, awesome.
Boxy

Shader "Three Layers" {
	Properties {
		_Color ("Main Color", Color) = (1,1,1,1)
		
		_MainTex ("Base (RGB)", 2D) = "white"
		_Detail ("Base Detail (RGB)", 2D) = "gray"
		_MainTexMask ("Base (Grey)", 2D) = "white"
		
		
		_Layer1 ("Layer 1 (RGB)", 2D) = "white"
		_LayerMask ("Layer 1 Mask (Grey)", 2D) = "white"
		
		_Layer2 ("Layer 2 (RGB)", 2D) = "white"
		_LayerMask2 ("Layer 2 Mask (Grey)", 2D) = "white"
	}
	
	


	SubShader {
			
					
		
		Pass{ 
				SetTexture [_LayerMask]   
       			SetTexture [_Layer1] { combine texture * previous }
          	} // end pass  


		Pass{
	  		Blend one one
				SetTexture [_LayerMask2] 
       			SetTexture [_Layer2] { combine texture * previous }
          	} // end pass  
          	
          	
        Pass{
		     Blend one one
				SetTexture [_MainTexMask]
				SetTexture [_Detail] {combine previous * texture DOUBLE, previous}
				SetTexture [_MainTex] {combine texture * previous}
			} // end pass
		
	}



	
	
	FallBack " Diffuse", 1
}

[/img]

You may be talking to yourself, but a lot of people are listening (100 views of this one-man thread until now). And I bet that I’m not the only one who is impressed and excited about this new shader.

You might want to upload it to the Unify wiki, for a bit of fame and glory :slight_smile:

d.

hey sorry for letting you talk to yourself, boxy! barely been lurking lately. didn’t see the thread. glad you got it figured out and yes, it’s really the way you build masks in pshop/gimp. i used duplicate layer then invert quite a bit. another trick is to draw paths. you can fill/stroke them with black or white for your opposing layers and they’re easy to edit later. use a soft or hard brush depending on the texture transition you want. you can get some cool effects… turn off aliasing for a hard edge or blur one mask but not the other, paint spots at 80% black in the mask for your top texture to create variations like random oil stains on a road… lots of stuff to play with!

the one thing i haven’t gotten around to is playing with the fallback. i was planning to fall back to a 512 or 1024 single texture. i believe the diffuse fallback as it is will just be whatever color is your base color. not sure though and the shader in the mountain track showed fine on an inteligrated 82815 pc. so might not be a worry except for really super old machines.

is your code right? in the immortal words of nicholas… if it looks good, ship it!

[edit: and oh yeah… i was as giddy as a school girl when i got it working! :wink: ]

Very nice Boxy. How is this different from the 3 layer shader in this post:

http://forum.unity3d.com/viewtopic.php?t=1335&highlight=terrain

sorry i’m not boxy! but his is based on mine which is 100% based on richard’s work. lerp wasn’t working for me but combine texture * previous did. why? beats me! i was just fiddling til it worked… unity makes me happy! :smile:

Hey thanks David, too kind, but I can’t claim any glory for cutting and pasting and scratching my head :slight_smile: It should go up on the Wiki as a variation though.

Pete, no problem, actually I’m glad because the things you figure out for yourself are the things you remember. The masking does have a huge lot of potential though, can’t wait to try and get it sorted but I do need to at least play with the idea of a ‘lightmap’ type channel first so I can add baked colour/shadows from C4D. I like texture as fallback idea to.

Bigkahuna - as Pete said, but I couldn’t get either of them working without a bit of tinkering, like changing the order of the passes and removing a ‘Blend one one’. I also have no idea why this should be but isn’t that great the about Unity, you still get results despite knowing nothing :wink:

Thanks
Boxy

I love this app :slight_smile:
This is pretty much everything I wanted to do with the shader. The shadow layer multiply makes things a bit dark but I could adjust the textures I think.
Cheers
Boxy

Shader "Layered Detail Illum" {
	Properties {
		_Color ("Main Color", Color) = (1,1,1,1)
		
		_MainTex ("Base (RGB)", 2D) = "white"
		_Detail ("Base Detail (RGB)", 2D) = "gray"
		_MainTexMask ("Base (Grey)", 2D) = "white"
		
		_Layer1 ("Layer 1 (RGB)", 2D) = "white"
		_Detail1 ("Layer 1 Detail (RGB)", 2D) = "gray"
		_LayerMask ("Layer 1 Mask (Grey)", 2D) = "white"
		
		_Layer2 ("Layer 2 (RGB)", 2D) = "white"
		_Detail2 ("Layer 2 Detail (RGB)", 2D) = "gray"
		_LayerMask2 ("Layer 2 Mask (Grey)", 2D) = "white"
		
		_BumpMap ("Self-Illumin (A)", 2D) = "bump" {}
	}
	
	
	SubShader {
	
		Pass{ 
				SetTexture [_LayerMask]
				SetTexture [_Detail1] { combine previous * texture DOUBLE, previous }   
       	  SetTexture [_Layer1] { combine texture * previous }
          	} //end pass  

		Pass{
	  		Blend one one
				SetTexture [_LayerMask2]
				SetTexture [_Detail2] { combine previous * texture DOUBLE, previous } 
       	  SetTexture [_Layer2] { combine texture * previous }
          	} //end pass  
          	
        Pass{
		     Blend one one
				SetTexture [_MainTexMask]
				SetTexture [_Detail] { combine previous * texture DOUBLE, previous }
				SetTexture [_MainTex] { combine texture * previous }
			} //end pass
			
		Pass{
			Blend DstColor Zero
				SetTexture [_BumpMap] { combine texture lerp (texture) previous }
			} //end pass
		
		}
	
	FallBack " Diffuse", 1
}

Boxy,
This is the shader that I use - it is a bit of a hack but does the job for the moment. I did use one with more layers (and consequently more passes) but it killed my frame rate. Thus the one below works well for the “foreground” terrain (I use a much faster material for the distant terrain). I have no lighting on the terrain as I bake all of my lighting.

I would REALLY like to know how to get two more masked layers without adding any more passes.

Richard.

Shader "terrain/Three Tiled Textures with Shadowmap" {
Properties {    
	_Shadowmap ("Shadow map (RGB)", 2D) = "white" 
	_PathTex ("Path (RGB)", 2D) = "white"
	_PathMask ("- Alpha Mask for Path Layer (A) ", 2D) = "white"
	_HillsTex ("Hills (RGB)", 2D) = "white"     
	_HillsMask ("- Alpha Mask for hills Layer (A) ", 2D) = "white"
	_BaseTex ("Base (RGB)", 2D) = "white"  
}
SubShader {      
 
	Pass {
		// Apply base texture
		SetTexture [_BaseTex] {   combine texture   }
		
		// Load in the alpha  blending texture  
     	SetTexture [_HillsMask] {		combine previous, texture   }  
		  
		// Blend in top layer with base layer using the alpha  
        SetTexture [_HillsTex] {		 combine texture lerp (previous) previous    } 
		

 		SetTexture [_Shadowmap] {		combine   texture*previous    }
		
	} // end pass
 
	Pass{  Blend SrcAlpha OneMinusSrcAlpha    

	  	// Load in the alpha blending texture  
       	SetTexture [_PathMask] {		combine previous, texture     }
   	  	// Blend in top layer with base layer using the alpha  
        SetTexture [_PathTex] {		combine texture lerp (previous) previous ,previous  }  


		SetTexture [_Shadowmap] {		combine   texture*previous    }
   	
	}  //end pass
        
  
} // end subshader  

  FallBack " Diffuse", 1  
} // end shader

Thanks Richard that looks interesting. When I try it I can only get the shadow map and Path channels to work, do you have a screenshot of what it should look like?

I was wandering whether you could use different blend functions that get blocked/not blocked by different masks in the same pass but I couldn’t get it to work and I don’t know enough to know whether that would solve your problem - but its a good point and the fact that the shader goes on a large terrain probably won’t help frame rates either.
Thanks for the help, please do let us know if you find a way. I would be interested to learn more about this.
Boxy

Boxy,
These shader masks work a little different to the previous version in that they are similar to Photoshop layer masks which I find much easier to use than the previous shader. I am away for the next few days so will post some examples when I get back.
cheers,
Richard.

Hi Richard
You lost me, I thought these were quite photoshoppish :slight_smile:
But I’d really appreciate some samples when you get back, thanks very much
Boxy

Definitely starting to get somewhere with this shader, the grass is almost what I want, haven’t yet finished the alpha masks to allow the layer 2 mud patches to show through and the lightmap is a quicky just to test it but very cool.
Interestingly Richard, my game performance has shot up since adding this shader to the terrain, which is an even better surprise considering there are many more polygons in it than the last terrain. (I rebuilt the terrain from a square plane draped over the old one with C4D’s cloth tool to get an even grid UV map so the textures in the shader would not distort as much). It’ll be interesting to see if it also improves play on my TiBook 867mhz, which I consider will be a reasonable lowest common denominator by the time this actually ships as a game :slight_smile:

Keep the layer shaders coming :slight_smile:
Thanks
Boxy

Final post (hope its not a double post, I thought I’d submitted this!!)

A web player of the terrain shader with all three layers active. Its a terrain test so apologies for continued non development of everything else! There will be more tweaking but this works…

The performance shot up noticeably when I replaced the old realtime lit terrain with this self illuminating shader so though the baking process is longer its definitely worth it. Thanks for everyone’s help, now to add that awsome grass script those Unity genii just added :wink:

Boxy

Web Player:
http://www.savbox.pwp.blueyonder.co.uk/posts/Test/Test.html

Shader "Layered Detail Illum" {
	Properties {
		_Color ("Main Color", Color) = (1,1,1,1)
		
		_MainTex ("Base (RGB)", 2D) = "white"
		_Detail ("Base Detail (RGB)", 2D) = "gray"
		_MainTexMask ("Base (Grey)", 2D) = "white"
		
		_Layer1 ("Layer 1 (RGB)", 2D) = "white"
		_Detail1 ("Layer 1 Detail (RGB)", 2D) = "gray"
		_LayerMask ("Layer 1 Mask (Grey)", 2D) = "white"
		
		_Layer2 ("Layer 2 (RGB)", 2D) = "white"
		_Detail2 ("Layer 2 Detail (RGB)", 2D) = "gray"
		_LayerMask2 ("Layer 2 Mask (Grey)", 2D) = "white"
		
		_BumpMap ("Self-Illumin (A)", 2D) = "bump" {}
	}
	
	
	SubShader {
	
	
		Pass{ 
			 
				SetTexture [_LayerMask]
				SetTexture [_Detail1] { combine previous * texture DOUBLE, previous }   
       			SetTexture [_Layer1] { combine texture * previous }
          	} //end pass  
          	
          	
          	
        
		Pass{
	  		Blend one one
				SetTexture [_LayerMask2]
				SetTexture [_Detail2] { combine previous * texture DOUBLE, previous }
				SetTexture [_Layer2] { combine texture * previous }
          	} //end pass  


		
		Pass{
		     Blend one one
				SetTexture [_MainTexMask]
				SetTexture [_Detail] { combine previous * texture DOUBLE, previous }
				SetTexture [_MainTex] { combine texture * previous }
			} //end pass

		
				
		Pass{
			Blend DstColor Zero
				SetTexture [_BumpMap] { combine texture lerp (texture) texture DOUBLE, previous }
			} //end pass
		
		}
	
	FallBack " Diffuse", 1
}

Hi Boxy,

Thanks for sharing! I’ll have to give this a try to see what I can learn from it. This thread has been very helpful and has motivated me to try an write a shader of my own. What I’d like to create will have 2 bump mapped textures and a lightmap, I don’t think a shader has been posted like that yet.

Good one, thanks. Keep a thread of your progress too if you don’t mind, I’d be interested to see how bump mapping looks compared to detail shaders. I wondered if I should try a bump for the mud layer as it currently looks a bit flat, but my head is hurting too much from all the thinking, need a couple of earlier nights I think :wink:
Cheers
Boxy

I’ve been trying to create a 3 layer version of the 2 layer shader found here:

http://www.unifycommunity.com/wiki/index.php?title=LayerShader

I just want the ability to add another texture and layer mask on top of what’s already available, but I’m not having much luck. This is probably very simple to do but this is the first time I’ve tried to write a shader. Can anyone help?

Here’s the 3-layer shader I did for the Wilderness Walk demo thingy:

Shader "MyShaders/3LayerTerrain" {
	Properties {
		_Color ("Main Color", Color) = (1,1,1,1)
		_MainTex ("Main Texture (RGB)", 2D) = "white"
		_Detail ("Base Detail (RGB)", 2D) = "gray" 
		_Tex2 ("Texture2 (RGB)", 2D) = "white"
		_Tex2Mask ("Texture2 Mask (Grey)", 2D) = "white"
		_Tex3 ("Texture3 (RGB)", 2D) = "white"
		_Tex3Mask ("Texture3 Mask (Grey)", 2D) = "white"
	}
	Category {
		ZWrite On
		Lighting On
		Cull Back
		SubShader {
			Material {
				Diffuse [_Color]
				Ambient [_Color]
			}

			Pass {
				SetTexture [_MainTex] {combine texture * primary DOUBLE, texture * primary}
				SetTexture [_Detail] {combine previous * texture DOUBLE, previous} 
			}
            
			Pass {
				Blend SrcAlpha OneMinusSrcAlpha
				SetTexture [_Tex2] {combine texture}
				SetTexture [_Tex2Mask] {combine previous * primary DOUBLE, previous - texture}
			}

			Pass {
				Blend SrcAlpha OneMinusSrcAlpha
				SetTexture [_Tex3] {combine texture}
				SetTexture [_Tex3Mask] {combine previous * primary DOUBLE, previous - texture}
			}	
		}
	}
	FallBack " Diffuse", 1 
}

One of the layers also has a detail texture (that’s how I did the grass because otherwise it always looked tiled no matter how I tried to disguise it), but you can just take that out if you don’t want it. Not sure if I did everything ideally (I’m not much of shader writer), but it works. :wink:

–Eric