- Home /
Moving Terrains causes severe lag, why?
I have this project at work where we are displaying certain simulations (Solar System sized) and need double precision accuracy. Since Unity only uses single precision, we have incorporated a "Floating Origin" system where the camera stays at 0,0,0 and the objects move around the camera, instead of the other way around.
This all works great when we are just moving standard GameObjects, but when we start moving Terrains, the performance is significantly degraded. Going from about 60fps down to 5 or 10fps. If we were to run our simulations the normal way, no floating origin and the camera moves about the scene as usual, the performance stays at 60fps or so. We just get the spatial jitter when played this way, so we prefer the floating origin approach.
I know the Terrain system does some dynamic LOD switching based on heightmapMaximumLOD, heightmapPixelError, and other parameters, as you move about, but I would think those calculations are done based on the camera's relative position/orientation to the terrain and it shouldn't matter if you move the camera or the terrain.
I've been able to track down where the lag occurs using the profiler. Inside the Terrain.CullAllTerrains() call there is a call to a TerrainRenderer.RenderStep3(), which is a wrapper to an internal call that I cannot look inside to see what is going on.
I was wondering if anybody knows what may be causing this and has a possible work around? I would think the performance of moving the camera relative to a terrain vs moving the terrain relative to the camera would be the same. Apparently it isn't.
I have made a simple fix where I allow the camera to move a certain threshold from the origin and then reset the origin when needed, which allows the terrain to stay in place more often and therefor keeps performance up most of the time. But this isn't ideal and it would be nice to know why the terrain system doesn't like to be moved.
Sorry for the long-winded question... and thanks for any information.
Answer by sharpshot124 · Mar 09, 2013 at 06:19 AM
well i dont have a true workaround but a plausible idea that could solve this since you said regular objects work fine, assuming you are using unity 4.
u could use a low res plane as ur base object then use ur terrain height map to displace it with the standard tessellated displacement shader. and the tessellation will work much like the dynamic lods. and it wouldnt be hard to write a shader that read the splat maps to use textures like the terrains do. you seem to have a good understanding of the terrain system but just in case ill explain the splat maps and a basic idea to turn it into the shader.
you have four textures (which u can use tiling to control detail) that correspond with a 5th texture's RGBA channels (the splat map). Then u blend all the textures together and determine the weight of each based off the splat.
for example (assuming u know a bit of shader coding)
fixed4 splatTex = tex2D(_Splat, IN.uv_Tex1);
fixed4 finalColor = (tex2D(_Tex1, IN.uv_Tex1) * splatTex.r) *
(tex2D(_Tex2, IN.uv_Tex1) * splatTex.g) *
(tex2D(_Tex3, IN.uv_Tex1) * splatTex.b) *
(tex2D(_Tex4, IN.uv_Tex1) * splatTex.a);
im not sure if this is how color blending works but u can see what i mean here
That's an interesting idea, thank you. We are currently using Unity 3.5 and are about to upgrade soon, so I'll keep that in $$anonymous$$d as a possibility. That would probably give much better performance than Unity's Terrain engine LODing too. Unfortunately, we will also be deploying on $$anonymous$$acs so that may limit our deployment a bit. From what I can gather, there isn't any plan for Unity to support OpenGL 4 in the near future. Would be nice though.
Your answer
Follow this Question
Related Questions
Distribute terrain in zones 3 Answers
Making a bubble level (not a game but work tool) 1 Answer
Unity Terrain Performance 2 Answers
Terrain Performance on Shaded Terrain 0 Answers
How do I check where my character is moving before he moves there? 1 Answer