Tanuki Digital Forum
UNITY => SUIMONO 2.0 - Interactive Water System => Topic started by: Fatalis on March 19, 2016, 10:31:22 PM
-
Hi, I'm trying to get access to a collection of positions in world space of the occurrences of shorelines in a terrain, and since Suimono already seems to calculate them for its shoreline effects I was wondering if there is a way I can get access to the results of those calculations to use for myself rather than writing my own script to do the calculations again. Is this possible?
Thank you!
-
Hi Fatalis,
This is an interesting question! In Suimono the 'shorelineObject' gameobject handles the generatio of a top-down depth texture which gets passed to other Suimono components. You can access this texture directly from the shorelineObject by accessing the RenderTexture that it generates, as per the example below...
#pragma strict
var shorelineTexture : RenderTexture;
private var shorelineRenderer : Renderer;
function Start () {
shorelineRenderer = GameObject.Find("shorelineObject").GetComponent(Renderer) as Renderer;
}
function LateUpdate () {
if (shorelineRenderer != null){
shorelineTexture = shorelineRenderer.sharedMaterial.GetTexture("_MainTex");
}
}
You can replace the "shorelineObject" above with whatever you've named it in your scene, and then use the captured shorelineTexture how you like. To extrapolate world positions from this texture you should be able to cross reference the position/scale of your shorelineObject with the resolution and pixel positions in the captured RenderTexture.
This is the first time anyone has ever asked about doing this, so I hope the above helps! Let me know if you have any more questions on this.
-
Thank you for your reply! This helps greatly. My only other questions are how is the position of foam calculated as it seems to not need the shoreline object to appear? And I noticed in the Suimono 2.1.1 preview that the presence of a shoreline object in a scene greatly reduces fps and didn't really seem to change the behavior of the shoreline?
-
After some fiddling I have gotten some shoreline waves working with the shoreline object, but no matter what I try the fps is terrible compared to have no active shoreline object. Any info as to why this is?
-
So are you saying that just by having a ShorelineObject in your scene that the fps performance is severely impacted? The shorelineObject is supposed to only render once when the scene is first started (in order to capture the scene depth info for the shoreline generation), but it sounds like it might be continuously firing for some reason on your end...?
Edit: Actually I just double checked the 2.1.1 Preview code and there indeed might b an issue there with continuous rendering. If you like I can email you a link to the latest dev version, which I think will improve your performance, and give you a few more options/settings on the shoreline component. Unfortunately there's too many dependencies to do a simple patch for this, so you'd need to uninstall suimono before installing the latest.
These edits wll of course also be in the final dev version which I'm putting the finishing touches on this week and hope to have ready for everyone soon.
-
Thanks! No hit to fps while using the shoreline object in the dev version. Another problem I have come across in the 2.1.1 preview that I didn't notice before is that Suimono actually significantly affects fps in scenes with lots of Speedtree foliage. I have been struggling with getting good performance with tens of thousands of Speedtree assets for a while, with Suimono always in the scene. It doesn't come up in the profiler, but when I disable Suimono in the scene, I go from having 30 fps to 60 fps in the most dense parts of the foliaged parts of the map, even though my camera is not actively looking at any part of the Suimono surface. Looking at the Suimono surface actually is less intensive. Any idea why this might be?
-
There's two possibilities here... dynamic reflections and the scene transparency function. Each one is re-rendering your scene for it's own internal purposes, so when it comes to a heavy rendering obstacle (like lots of trees) you're getting an exponential fps hit. The first thing I would recommend is perhaps lowering the reflection resolution/distance on your Suimono Surface to see if that eeks out more performance. You can also reduce the transparency resolution/distance on the module.
The more extreme fix for this is to separate the trees onto a separate game layer from your terrain. This involves duplicating the terrain, and then turning off tree/grass rendering on the original and simultaneously turning off terrain rendering on the copy, and placing it onto it's own game layer. This allows you to determine individually whether the transparency/reflections will render the terrain, trees, or both.
And regardless of the above I would also try to optimize your speedtrees as much as possible, as they don't really come with the most optimized settings by default. I'm speaking of adjusting the LOD thresholds, adjusting (or eliminating) their fading functions etc. You can also simplify their colliders which can really help improve their general performance.
-
I haven't tried everything you suggested as of yet, but turning off scene reflections does nothing to improve performance. I have to disable both the Suimono surface and module to get any type of performance increase.
-
Hmm... perhaps try turning off transparency as well as caustics to see where the bottle neck is(?), before moving on to the more drastic scene/tree optimizations I posted about.
-
Tried turning off everything in the module without disabling it, including transparency and caustics, no change in performance. I also halved the scale of my Suimono surface from 100 to 50 and moved it so that it was only where the beach part of my map is so that there was no surface "under" where I have forest. This did not change performance either.
-
Hi Fatalis,
Sorry for the late reply. I've been going through every component in the Suimono system doing cleanup and optimizations in anticipation of the final 2.1.1 release, and I believe I've isolated and corrected a few underground issues that may have been contributing to a bleed of performance here.
I've added a 'generation mode' option to the shoreline component so you can choose to run it once on play, or continuously (defaults to once).
I've also added some additional handling for background tasks in suimono (such as height calculation) to prevent these functions from firing unnecessarily.
I'm Just doing some final cleanup and testing today and tomorrow. The final version of 2.1.1 should be ready in the next few days.
-
Sounds awesome, thanks for the update! Reading back though the thread I noticed I had a question that had been overlooked:
How is the position of foam calculated as it seems to not need the shoreline object to appear?
-
Foam is calculated based on view-dependent depth mask... essentially comparing depth values between the water surface and other objects in the scene... so you're right the normal foam doesn't need the shoreline object. There is also a second foam specific to the shoreline effect (on top of shoreline waves) and this does require the shoreline object since it relies on the position/calculations from this object..
-
Had another question for ya:
How much has Suimono_ShorelineObject changed from Suimono_flowGenerator ? I used to successfully access the shoreline Texture2D from flowGenerator, but now it seems like the "customDepthTex" field (which I'm assuming is analogous to "shoreMapTex" in flowGenerator) in Suimono_ShorelineGenerator is always null when I access it--why is this?
-
'customDepthTex' is only used for the manual texture function. When shorelineObject is set to automatic mode (which is probably going to be most of the time for most people) the texture is generated by the 'cameraTools' component which is on the cam_LocalShore sub-object. so instead of accessing shorelineObject, you should access a child of this object called 'cam_LocalShore'. This object is normally hidden in the scene view, but you should still be able to access it through code regardless.
The texture variable you're looking for on this component is a RenderTexture called 'renderTexDiff'.
Here's an example that should work:
#pragma strict
var renderTex : RenderTexture;
private var renderComponent : cameraTools;
function Start () {
renderComponent = GameObject.Find("shorelineObject").transform.GetChild(0).GetComponent(cameraTools) as cameraTools;
}
function LateUpdate () {
if (renderComponent != null){
renderTex = renderComponent.renderTexDiff;
}
}
Note: The other method I posted at the top of this thread works as well, it gets the same texture data but reads it from the shader renderer instead. I'm not sure if one is faster than the other.
-
I changed my code to try and grab the RenderTexture rather than the Texture2D, but a few things aren't working as well with the new shoreline object compared to the last. The main problem now seems to be that the RenderTexture only captures a certain portion of the terrain (see attached image) when before with flow_Generator it would capture the entire area of the Suimono Surface. The 2nd problem I have is that it seems like the RenderTexture calculates the shorelines as actually being on land rather than being on the water at the edge of the land, which has some problems such as inland areas being marked as shorelines. (see image). How can I get better results that are closer to what was produced by flowGenerator? If I can't, is there a way for me to reimplement the old shoreline object with the flowGenerator without causing problems? Thank you!
(https://cdn.discordapp.com/attachments/143977212163522560/169302435204956161/suimonoProb.png)
-
Hi Fatalis,
Have you setup your shoreline object properly for your terrain/water...? I just posted an updated documentation file that has shoreline setup instructions (page 13): http://www.tanukidigital.com/suimono/documentation/suimono2_documentation.pdf
Essentially you need to make sure that your surface is set on the shorelineobject's 'Attach to surface' slot, and that it is scaled to fully surround your terrain. With the debug mode enabled you'll be able to see where the shoreline is being generated, and adjust the depths etc. The green in your shoreline texture makes me think the depths haven't been adjusted. Below is the shorelineobject from the demo with debug mode on, so you can see how it's scaled/placed and the general red-->green gradient you should expect... but it's important to attach your water surface in the expected slot, or it won't know where to generate depth from.
(http://www.tanukidigital.com/suimono/misc_images/suiShore.jpg)
-
Thanks for the heads up about updated documentation, that definitely solved some of my problems. I'm still encountering one though. So I set up my shoreline object so that the texture in debug mode matched the one in the screenshot you posted. Everything seems set.
(https://cdn.discordapp.com/attachments/143977212163522560/171509327419539457/suimonoProb2a.png)
When I run the scene, all of a sudden the texture has changed and doesn't reflect the shoreline at all, although the black parts seem to occur around the bases of hilly areas. Why is this?
(https://cdn.discordapp.com/attachments/143977212163522560/171509811458998273/suimonoProb2b.png)
It might be worth mentioning that when I run the scene I access that RenderTexture through reflection, but that's the only way that I interact with it. Also, for what it's worth, before I had settings that resulted in a debug texture that didn't look like the one you posted, but that, once run, produced a texture with the shoreline in (roughly) the right place. [Below is a b/w converted version of the green/black image produced]. However I didn't use it because the texture was still far enough off (capturing more of the on-land shore than off-land) that I couldn't use it, so I tried to emulate the settings in your screenshot. (I can't remember what the shoreline settings were though, would have to mess around again)
(https://cdn.discordapp.com/attachments/143977212163522560/171510838367223809/SuimonoProb2c_processedShoreline.png)
Thanks for the prompt and helpful responses!
-
Hi -- update on the situation. I replaced the ShorelineObject with a fresh prefab and things seem to be ok (although this is the second time I've had to do it, mysteriously fixing the above problem again). Now I'm accessing the correct RenderTexture (image 1) but when I try and convert it to a Texture2D, I get the following result (image 2)
(https://cdn.discordapp.com/attachments/143977212163522560/171740123891761153/suimonoProb3a.png)
(https://cdn.discordapp.com/attachments/143977212163522560/171741313933377537/suimonoProb3b.png)
This is the code I use to transfer pixels from RenderTexture to Texture2D; trying to specify TextureFormat hasn't helped:
RenderTexture currentActiveRT = RenderTexture.active;
RenderTexture.active = shorelineRenderTexture;
shorelineTexture = new Texture2D(shorelineRenderTexture.width, shorelineRenderTexture.height);//, TextureFormat.RGBAFloat, false);
shorelineTexture.ReadPixels(new Rect(0, 0, shorelineRenderTexture.width, shorelineRenderTexture.height), 0, 0);
shorelineTexture.Apply();
RenderTexture.active = currentActiveRT;(edited)
Thanks!
-
Hi Fatalis,
This is a texture format issue. Try changing your Texture2D creation above to use the following...
shorelineTexture = new Texture2D(shorelineRenderTexture.width, shorelineRenderTexture.height,TextureFormat.RGBAHalf,false,true);
This switches the format to rgbaHalf (which is the format in use by the rendertexture), sets mipmaps to off, and linear write mode to on. I'm not sure why the shorelineobject would need to be replaced... let me know if this continues to be a problem!
-
I changed that line of code, and I'm still having the same problem, here is the Texture2D that results:
(https://cdn.discordapp.com/attachments/143977212163522560/171885204552679425/suimonoProb3c.png)
Updated code:
RenderTexture currentActiveRT = RenderTexture.active;
RenderTexture.active = shorelineRenderTexture;
shorelineTexture = new Texture2D(shorelineRenderTexture.width, shorelineRenderTexture.height, TextureFormat.RGBAHalf, false, true);
shorelineTexture.ReadPixels(new Rect(0, 0, shorelineRenderTexture.width, shorelineRenderTexture.height), 0, 0);
shorelineTexture.Apply();
RenderTexture.active = currentActiveRT;
-
This is pretty strange. I can't see anything wrong with your code here on my end... technically you don't need the first line which is saving the RenderTexture, nor do you need the last line... you can instead just set RenderTexture.active = null;. This is the code I'm using (.JS, but the relevant parts are identical) and all is groovy here...
#pragma strict
var shorelineTexture : RenderTexture;
private var shorelineRenderer : Renderer;
private var testRenderer : Renderer;
function Start () {
shorelineRenderer = GameObject.Find("shorelineObject").GetComponent(Renderer) as Renderer;
testRenderer = gameObject.GetComponent(Renderer) as Renderer;
}
function LateUpdate () {
if (shorelineRenderer != null){
shorelineTexture = shorelineRenderer.sharedMaterial.GetTexture("_MainTex");
if (testRenderer != null){
RenderTexture.active = shorelineTexture;
var shorelineTex : Texture2D = new Texture2D(shorelineTexture.width, shorelineTexture.height,TextureFormat.RGBAHalf,false,true);
shorelineTex.ReadPixels(new Rect(0, 0, shorelineTexture.width, shorelineTexture.height), 0, 0);
shorelineTex.Apply();
RenderTexture.active = null;
testRenderer.sharedMaterial.SetTexture("_MainTex",shorelineTex);
}
}
}
Can you double check that the 'Calculate layers' attribute on the shorelineObject is actually rendering a layer with scene objects/terrain on it... and also that it is NOT rendering any of the Suimono layers? Also double check that the Suimono Surface is on the "Suimono_Water" layer. If you hit the 'Debug Mode' checkbox while playing your scene does the surface have the same texture info as the texture2d?
-
The only layer being rendered is the Terrain layer, and no Suimono layers. The Suimono Surface is on the Suimono_Water layer.
These are the settings of the RenderTexture I extract using reflection:
(https://cdn.discordapp.com/attachments/143977212163522560/172135981196115969/suimonoProb3d.png)
and on the resulting Texture2D:
(https://cdn.discordapp.com/attachments/143977212163522560/172136249920847873/suimonoProb3d.png)
-
Really not sure what's going on here. As long as the textureMode is correct I've not experienced any problems converting the RenderTexture to Texture2D here on my end. Any chance you can send me a small project that I could take a look at directly?
-
I've sent an email to your address from your contact thread. Thanks!