   Improving terrain shader
  Hi all,Currently I have a bit of a problem to figure something out for my terrain shader. First let me explain a bit about the current workings. The system I am using a bit of a combination of texture spatting and using detail texturing. I have 1 colortexture, to add the detail I use a lookup table. Each channel represents one of three detail textures. These are then combined in the fragment shaders with normal mapping and then blended with the color texture. It`s a pretty simple system and gives nice results. Here are some screenshots of the terrain in action and a preview of the lookup table and the shaders.http://img155.imageshack.us/my.php?image=61675359sl3.jpghttp://img132.imageshack.us/my.php?image=81021571zt3.jpghttp://img409.imageshack.us/my.php?image=detailmapbg4.jpgVertex shader:uniform float F_MIN_VIEW_DISTANCE;uniform float F_MAX_VIEW_DISTANCE;varying vec2  ColorUV;varying vec2  DetailUV;varying vec2  CausticUV;varying vec2  CoverageUV;varying float Fog;varying vec3  lightVec; varying vec3  viewVec;vec3 CalculateTangent(){ vec3 binormal; vec3 tangent; vec3 c1 = cross( vec3(0.0, 1.0, 0.0), vec3(0.0, 0.0, 1.0)); vec3 c2 = cross( vec3(0.0, 1.0, 0.0), vec3(0.0, 1.0, 0.0)); if(length(c1)>length(c2)){tangent = c1;}else{tangent = -c2;}tangent = normalize(tangent);return tangent;}void main(void){vec4 Eye  = ftransform();gl_Position    = Eye;Fog  = clamp((length(Eye) - F_MIN_VIEW_DISTANCE) / F_MAX_VIEW_DISTANCE, 0.0, 1.0);ColorUV   = gl_MultiTexCoord0.xy;DetailUV  = gl_MultiTexCoord1.xy;CausticUV = gl_MultiTexCoord2.xy;CoverageUV= gl_MultiTexCoord3.xy;vec3 n = normalize(gl_NormalMatrix * vec3(0.0, 1.0, 0.0));vec3 t = normalize(gl_NormalMatrix * CalculateTangent());vec3 b = normalize(cross(n, t));vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);vec3 tmpVec  = gl_LightSource[0].position.xyz - vVertex;vec3 v;v.x = dot(tmpVec , t);v.y = dot(tmpVec , b);v.z = dot(tmpVec , n);lightVec = v;vec3 vVec = -vVertex;v.x = dot(vVec, t);v.y = dot(vVec, b);v.z = dot(vVec, n);viewVec = v;}Fragment shader:uniform sampler2D T_COLORMAP;uniform sampler2D T_DETAILLOOKUPMAP;uniform sampler2D T_DETAILMAP1;uniform sampler2D T_DETAILMAP2;uniform sampler2D T_DETAILMAP3;uniform sampler2D T_DETAILNORMALMAP1;uniform sampler2D T_DETAILNORMALMAP2;uniform sampler2D T_DETAILNORMALMAP3;uniform sampler2D T_CAUSTICMAP;uniform int I_UNDER_WATER;varying vec2 ColorUV;varying vec2 DetailUV;varying vec2 CausticUV;varying vec2 CoverageUV;uniform vec4 V_FOG_COLOR;varying float Fog;varying vec3 lightVec; varying vec3 viewVec;void main(void){  vec4 Color    = texture2D(T_COLORMAP,    ColorUV);  vec4 Weights  = texture2D(T_DETAILLOOKUPMAP,  CoverageUV);  vec4 Detail1  = texture2D(T_DETAILMAP1,  DetailUV);  vec4 Detail2  = texture2D(T_DETAILMAP2,  DetailUV);  vec4 Detail3  = texture2D(T_DETAILMAP3,  DetailUV);  Weights  = Weights / (Weights.x + Weights.y + Weights.z);  vec4 DetailFinal   = (Detail1*Weights.x + Detail2*Weights.y + Detail3*Weights.z);  DetailFinal   = Color + DetailFinal - 0.5;  if(I_UNDER_WATER == 0)  {vec3 lVec = normalize(lightVec);vec3 vVec = normalize(viewVec);vec3 DetailNormal1 = normalize( texture2D(T_DETAILNORMALMAP1, DetailUV).xyz * 2.0 - 1.0);   vec3 DetailNormal2 = normalize( texture2D(T_DETAILNORMALMAP2, DetailUV).xyz * 2.0 - 1.0);   vec3 DetailNormal3 = normalize( texture2D(T_DETAILNORMALMAP3, DetailUV).xyz * 2.0 - 1.0);   vec3 DetailNormalFinal = normalize( ((DetailNormal1*Weights.x + DetailNormal2*Weights.y + DetailNormal3*Weights.z) * 2.0) - 1.0 );float diffuse   = max( dot(lVec, DetailNormalFinal ), 0.0 ); float specular  = pow(clamp(dot(reflect(-lVec, DetailNormalFinal ), vVec), 0.0, 1.0), gl_FrontMaterial.shininess );vec4  vAmbient  = gl_LightSource[0].ambient * gl_FrontMaterial.ambient;vec4  vDiffuse  = gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * diffuse;vec4  vSpecular = gl_LightSource[0].specular * gl_FrontMaterial.specular * specular;gl_FragColor   = mix( (vAmbient*DetailFinal + vDiffuse*DetailFinal + vSpecular) , V_FOG_COLOR, Fog);  }  else  {vec4 Caustic   = texture2D(T_CAUSTICMAP, CausticUV);gl_FragColor   = mix( DetailFinal + Caustic - 0.5, V_FOG_COLOR, Fog);    }}As you can see it now uses all 8 texture units and this is a problem because I need aditional ones for shadowmapping and adding some other stuff. As you can see in the shader I alreay have to compromise when I need to use caustics. Also Want to add parallaxmapping. I have already have a thought on how to fix this but there is one part I just cant figure out. I want to use one texture per detail instead of the 2 required now and the three I want to add parallaxmapping.I want to create a texture like this:----------------------------|********|********|********| |*Detail*|*Normal*|*Height*||********|********|********| ----------------------------The V of the DetailUV doesnt have to change but Iam having trouble figuring out how to calculate the U. I dont care that the texture is a rectangle. Any one any Idears?  Greetz Luukps. Sorry for not using codeblocks:)[Edited by - Luuk van Venrooij on February 3, 2008 5:47:33 AM]
  Multipass rendering? :)   ;  If you have 4 detail textures why not put them in the different channels of a single texture?  red, green, blue, alpha?  As a detail texture only needs the values between 0 and 255.Just a suggestion, and something I was thinking of trying.   ;  Multipass rendering would work but would probebly be to costfull. Also the idear with the layers wont work because my I 3 textures per detail. A grayscale color image, normal map and heightmap.The only problem I have is calculating the U of the detailUV If use the textures Decribed in the above post.   