Jump to content
  • Advertisement
Sign in to follow this  
Luuk van Venrooij

Improving terrain shader

This topic is 3796 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.jpg http://img132.imageshack.us/my.php?image=81021571zt3.jpg http://img409.imageshack.us/my.php?image=detailmapbg4.jpg Vertex 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 Luuk ps. Sorry for not using codeblocks:) [Edited by - Luuk van Venrooij on February 3, 2008 5:47:33 AM]

Share this post


Link to post
Share on other sites
Advertisement
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!