[MOD] Distant Terrain

A curated forum for compatible and maintained mods. Users are unable to create new topics in this forum but can reply to existing topics. Please message a moderator to have your mod moved into this forum area.
Post Reply
User avatar
Nystul
Posts: 1501
Joined: Mon Mar 23, 2015 8:31 am

Re: Project "Increased Terrain Distance"

Post by Nystul »

LypyL wrote:I got a real appreciation for the scale of the mountains now using the changes with improved terrain... :shock: They're absolutely huge, both vertically and wide/deep. The peaks around (875, 446) is like 23k units high :lol:
I am not sure if we are anywhere near to realistic scale, but it looks interesting at least now ;)

you can try these values in ImprovedWorldTerrain script if you do not like the extreme heights, they are more realistic, but also terrain becomes more flat:
const float exaggerationFactorWaterDistance = 0.15f;
const float extraExaggerationFactorLocationDistance = 0.0275f;

User avatar
Nystul
Posts: 1501
Joined: Mon Mar 23, 2015 8:31 am

Re: Project "Increased Terrain Distance"

Post by Nystul »


User avatar
LypyL
Posts: 512
Joined: Sun Mar 22, 2015 3:48 am

Re: Project "Increased Terrain Distance"

Post by LypyL »

I'm continuing the discussion from the demo thread about Floating origin / Increased Terrain here so we don't clutter it up :D

I've (possibly) made some headway in making increased terrain work with floating origin.

Updated Floating Origin script:

https://drive.google.com/file/d/0B8_oQw ... sp=sharing

Code change in IncreasedTerrainDistance:


In private void updatePositionWorldTerrain()

Code: Select all


// world map level transform (for whole world map pixels)

Vector3 offset = FloatingOrigin.instance.totalOffset;
            
Vector3 worldMapLevelTransform;
            worldMapLevelTransform.x = (xdif) * scale;
            worldMapLevelTransform.y = offset.y;
            worldMapLevelTransform.z = -(ydif) * scale;

            // local world level transform (for inter- world map pixels)
            float localTransformX = (float)Math.Floor((cameraPos.x) / scale) * scale;
            float localTransformZ = (float)Math.Floor((cameraPos.z) / scale) * scale;
            

            // compute composite transform and apply it to terrain object
            
            Vector3 finalTransform = new Vector3(worldMapLevelTransform.x + localTransformX, worldMapLevelTransform.y, worldMapLevelTransform.z + localTransformZ);
            terrainGameObject.gameObject.transform.localPosition = finalTransform;
And you can either attach the script to streaming world and it be offset automatically, or put it on a new game object and add the following in updatePositionWorldTerrain()

Code: Select all

// Create Unity Terrain game object
            GameObject terrainGameObject = Terrain.CreateTerrainGameObject(null);
            terrainGameObject.AddComponent<PositionUpdate>();
PositionUpdate was included in the Zip w/ floating origin if you didn't copy into your assets already

It's not perfect, but it seems to keep the far terrain position close to correct as the player moves around - (though I think the y might need to be offset tiny bit? I left it alone to keep it simple for now) - Iit doesn't do anything about the terrain textures / meshes - they'll still turn to water and so on if the player changes height.

edit: It seems just resetting the water height each update before updating the textures solves the water issue.

I just copied the relevant code from generateWorldTerrain() and put it in update:

Code: Select all

secondaryCamera.transform.SetParent(Camera.main.transform); // make 2nd camera inherit transform from main camera
                
            }


//## new water height code:
            Vector3 vecWaterHeight = new Vector3(0.0f, (TerrainHelper.scaledOceanElevation + 1.0f) * streamingWorld.TerrainScale, 0.0f); // water height level on y-axis (+1.0f some coastlines are incorrect otherwise)
            Vector3 vecWaterHeightTransformed = terrainGameObject.transform.TransformPoint(vecWaterHeight); // transform to world coordinates
            terrainMaterial.SetFloat("_WaterHeightTransformed", vecWaterHeightTransformed.y);


            // Handle moving to new map pixel or first-time init
I'm testing this all without the improved terrain, so I'll need to check later and see how that's working now

User avatar
Interkarma
Posts: 7236
Joined: Sun Mar 22, 2015 1:51 am

Re: Project "Increased Terrain Distance"

Post by Interkarma »

LypyL, thanks so much for all your work on this. You made my job that much easier. :)

I've download the linked FloatingOriginUpdate.7z above, but the script FloatingOrigin.cs does contain a field or property called totalOffset, so the following line of code does not build.

Code: Select all

Vector3 offset = FloatingOrigin.instance.totalOffset;
Is there another version or am I missing something else obvious? Thanks again man.

User avatar
LypyL
Posts: 512
Joined: Sun Mar 22, 2015 3:48 am

Re: Project "Increased Terrain Distance"

Post by LypyL »

Whoops! That was the wrong link :oops:

https://drive.google.com/file/d/0B8_oQw ... sp=sharing

I basically changed it so instead of using last position, it uses the origin. There is no need to Initialize() anymore as far as I can tell, because it's always checking for distance from the origin (I noticed when testing the jet it's possible to jump over the threshold, so your last position can keep climbing higher and higher from the origin until physics bugs start occurring).

And of course I added totalOffset

User avatar
Interkarma
Posts: 7236
Joined: Sun Mar 22, 2015 1:51 am

Re: Project "Increased Terrain Distance"

Post by Interkarma »

Awesome, you're a legend. :)

User avatar
LypyL
Posts: 512
Joined: Sun Mar 22, 2015 3:48 am

Re: Project "Increased Terrain Distance"

Post by LypyL »

It seems after fast traveling, the terrain height is off by the exact amount of totalOffset.y. (in other words, if the y is offset by -1000, raising the distant terrain up by 1000 fixes it). I'm too tired to think of why, but I have feeling it's obvious. :lol:

User avatar
Interkarma
Posts: 7236
Joined: Sun Mar 22, 2015 1:51 am

Re: Project "Increased Terrain Distance"

Post by Interkarma »

When it comes to increased terrain distance, I'm experiencing similar inconsistencies with both of our approaches to floating origin. I just run down into the water north of Privateer's Hold then run west along the water and observe the coastline changes. Without any floating origin, everything looks perfectly in sync. Once the origin kicks in there are some obvious jumps in the distant terrain that don't look quite right. It's not too bad, and many users may not even notice, but I think it could be a lot better.

This fall squarely on my shoulders - I just hacked in the floating origin without much consideration for anything other than vanilla StreamingWorld, and no support for extensions on my side. This is something I need to improve on. There's nothing quite like putting myself in your shoes for a couple of days to understand just what an incredible job you've all done extending things, and where I need to improve.

So! Because we're just putting a demo together right now, I'm just going to find the best general outcome based on what we have right now. It's still freaking amazing after all. But moving forward, I'm going to use this as an opportunity to learn from what you guys are doing and think about how I can do things better.

I tweeted the below last night, and I meant every word. :)

https://twitter.com/dfinterkarma/status ... 3149154304

User avatar
LypyL
Posts: 512
Joined: Sun Mar 22, 2015 3:48 am

Re: Project "Increased Terrain Distance"

Post by LypyL »

Interkarma wrote:When it comes to increased terrain distance, I'm experiencing similar inconsistencies with both of our approaches to floating origin. I just run down into the water north of Privateer's Hold then run west along the water and observe the coastline changes. Without any floating origin, everything looks perfectly in sync. Once the origin kicks in there are some obvious jumps in the distant terrain that don't look quite right. It's not too bad, and many users may not even notice, but I think it could be a lot better.
Yeah the shifty-ness is unfortunately still there. It seems improved to me compared to before (though that would have nothing to do with my floating origin changes). I can only guess, but I think maybe it's being caused by precision loss due to the size of the terrain + size of the offset? If so, that sucks because there probably isn't an easy fix for that. Maybe the extended terrain will have to be split up into chunks or something.
I tweeted the below last night, and I meant every word. :)
I assumed you were drunk tweeting or something :mrgreen:

User avatar
Interkarma
Posts: 7236
Joined: Sun Mar 22, 2015 1:51 am

Re: Project "Increased Terrain Distance"

Post by Interkarma »

Nystul, let me know how you feel about the following.

Basically your WorldTerrain is a fixed bit of detail that sits under player position. Instead of creating/destroying small tiles like the main terrain, you use the approach of setting new terrain heights based on player position in world. In this way, height data "flows through" the WorldTerrain. This is very clever and I think it's a great approach.

What I would suggest changing is how the player world position is calculated. You're deriving player world position using map pixel + camera coordinates scaled into Daggerfall-space. The reason floating origin mucks things up is because the camera is being shifted around with other gameobjects. This throws out the calculations for player world position in Daggerfall-space. The good news is that you shouldn't need to use the camera at all.

Rather than use camera position, I would suggest trying the WorldX and WorldZ values from PlayerGPS. These are the actual player coordinates in Daggerfall's world space (at inch resolution) and already marry up the camera in Unity-space to the player in Daggerfall-space. It should have more than enough resolution to handle aligning height data of distant terrain. As an example, I use WorldX/WorldZ values to determine when a player is inside a world location rect, no camera coordinates needed.

In this way, the WorldTerrain game object can happily float around with other children under StreamingWorld (or just aligning itself to player position) without needing to care about camera position and recalculating player position in world. That's what PlayerGPS is there for. Height data will still flow through the world terrain and line up with the high-detail terrains.

Hopefully I have understood everything correctly and communicated effectively. Let me know your thoughts. :)

Post Reply