Search Unity

Ceto (Scrawks Ocean)

Discussion in 'Assets and Asset Store' started by scrawk, May 4, 2015.

  1. CaptainMurphy

    CaptainMurphy

    Joined:
    Jul 15, 2014
    Posts:
    746
    Thank you for not letting feature creep kill the asset. I have lost too many good assets to their developers wanting to add everything and the kitchen sink to it without actually fixing/perfecting what is in the core first.
     
  2. FargleBargle

    FargleBargle

    Joined:
    Oct 15, 2011
    Posts:
    774
    MIT's Law of Software Development: "Every program in development at MIT expands until it can read mail."
    Some features are nice, but hardly necessary. Best to keep things as light as possible. ;)
     
    Peter77 likes this.
  3. Imhotebkin

    Imhotebkin

    Joined:
    Feb 10, 2015
    Posts:
    18
    To be fair the guy did say SEPARATE asset:D
     
  4. FargleBargle

    FargleBargle

    Joined:
    Oct 15, 2011
    Posts:
    774
    Right, but as @scrawk pointed out, there are already lots of assets that handle skies, many of which have been discussed here already. No need to make another, especially if it's outside of his interests or expertise. Better to focus on making Ceto the best ocean it can be, and let others worry about the rest, a philosophy many other software makers could benefit from. ;)
     
    hopeful likes this.
  5. Imhotebkin

    Imhotebkin

    Joined:
    Feb 10, 2015
    Posts:
    18
    It's already the best ;) Add a good buoyancy and masking system in it and there will be nothing to compete with it:)
     
    Mogpolgludh and FargleBargle like this.
  6. Killersan

    Killersan

    Joined:
    May 27, 2014
    Posts:
    76
    Is there any way that I could disable planar reflection but only where water is culled by by the Mask Script which You provided Scrawk ? My map is large with many objects and reflections are killing performance at this point, but I would like to keep them when they should be.
     
  7. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    No, it doesn't work like that sorry.

    You have to use the reflection mask on the planar reflection script to reduce what gets drawn. The best way is to create a mask layer with just the objects that are near the water and use that. Even then you won't be able to reflection lots of small objects.
     
  8. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    You might also want to try this new script that's for the next update.

    Attach it to your camera and it lets you set the culling distances for each layer on the reflection camera Ceto creates.

    You might be able to reduce the culling distance to help with the number of reflection draw calls ( 0 means no culling).

    There will be some popping however.
     

    Attached Files:

  9. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Any tests done with Unity's SSR in the new cinematic effects? Would not require rendering planar reflections, and probes will pick up sky.
     
  10. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    I have not had a chance to look at it yet and I am expecting there to be issues but it is something I want to have work for the ocean.
     
  11. Recluse

    Recluse

    Joined:
    May 16, 2010
    Posts:
    485
    I can't do that. I need particles in my game!
     
  12. gibmation

    gibmation

    Joined:
    Dec 1, 2014
    Posts:
    311
    Well done great product so far.

    My terrain has tunnel below sea level but these fill up with water also.
    Is it possible to block off water using a collider or similar?

    Thanks & regards

    G.
     

    Attached Files:

  13. John-G

    John-G

    Joined:
    Mar 21, 2013
    Posts:
    1,122
    Look up the Wave Overlay section in the documentation it describes how to achieve that.
     
    gibmation likes this.
  14. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    Thanks.

    You can create a new game object and add Ceto's AddWaveOverlay component.

    position it over the hole, resize it and rotate with the width, height and rotation settings (there will be a yellow box in editor). The add a texture to the clip texture slot. Where the texture is white it will cut a hole in the ocean. Make sure the texture has alpha from grey scale ticked. Theres some basic masks in Cetos texture folder you can use.

    You can also try these 2 new script that will be in the next version. Add them to the Ceto folder and add the AddAutoShoreMask to your terrain. It will automatically cut a hole under your terrain.

    Note - these scripts are a WIP and will be further improved when the update goes out.
     

    Attached Files:

  15. jpfranssen

    jpfranssen

    Joined:
    Apr 7, 2014
    Posts:
    12
    We are using the ceto ocean with our custom warping and blending solution (for multi-display and dome projections). In some situations we need to skew the projection-matrix of the camera. I found that when skewing over the Y axis the ocean grid is rendered incorrectly (exploded) causing the fps to drop significantly.

    I understand that with 'normal use' this will never happen, but I was wondering if you could think of a 'quickfix' or workaround for this?

    See attached script for quickly testing a skewed projection matrix.
     

    Attached Files:

  16. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    Hi,

    I will take a look at it but it may not be fixable.

    I have had a few people use scripts like this to modify the projection matrix and they have worked but I would expect there will be some situations that wont. The projected grid Ceto uses is based of the projection matrix so the skewing may be causing it to to explode.
     
    jpfranssen likes this.
  17. Tony-Lovell

    Tony-Lovell

    Joined:
    Jul 14, 2014
    Posts:
    127
    When I try to use the new short masking script, I get this:

    Assets/Ceto/ShoreMaskGenerator.cs(42,30): error CS1061: Type `UnityEngine.Texture2D' does not contain a definition for `alphaIsTransparency' and no extension method `alphaIsTransparency' of type `UnityEngine.Texture2D' could be found (are you missing a using directive or an assembly reference?)

    oddly, in my script editor, it fully understands this bool data member.

    I am using Unity 5.3.2f1

    tone
     
  18. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    Ahh, yes. Forgot about that sorry.

    Unity has a alphaIsTransparency setting on the texture that you can use in the editor but it gives a error if you try and build with it for some stupid reason.

    I don't really need it anyway so I removed it. Try this one.
     

    Attached Files:

    Tony-Lovell likes this.
  19. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,619
    I guess he also needs to enable Bypass sRGB Sampling, as the texture encodes data rather than color information?
     
  20. jpfranssen

    jpfranssen

    Joined:
    Apr 7, 2014
    Posts:
    12
    Thanks, I would really appreciate it! Keep up the good work!
     
  21. CaptainMurphy

    CaptainMurphy

    Joined:
    Jul 15, 2014
    Posts:
    746
    In our project I just put all of the particles onto a new layer and excluded it from the planar reflection. Seems to be working good so far. It will get us by until Unity fixes the issue. There are several bugs listed on the tracker already with the IsFinite error in them.
     
  22. gibmation

    gibmation

    Joined:
    Dec 1, 2014
    Posts:
    311
    Thanks for this. Just got the new docs as well.

    I'll give this a shot and report back.

    BR
    G.
     
  23. Tony-Lovell

    Tony-Lovell

    Joined:
    Jul 14, 2014
    Posts:
    127
    Scrawk, I hope to eventually come up with a dynamic weather system which would *like* to be able to alter parameters such as wind direction and speed, chop level, etc as weather goes from one state to the next, altering them as continuously as feasible.

    It would be great to have an outline of which Ceto parameters can be altered without incurring a great computational overhead and which cannot.

    I think the biggies are

    1. Wind direction
    2. Wind speed
    3. Choppyness
    4. Foam amount/coverage
    5. Level (for tides)

    Also, does lowering Fourier size to 32/low/cpu significantly reduce any costs associated with changes to the parameters above?

    Thanks in advance!

    tone
     
    RJS likes this.
  24. CaptainMurphy

    CaptainMurphy

    Joined:
    Jul 15, 2014
    Posts:
    746
    We change all of those (and more I think) in ours over a lerp during weather changes. We base the weather on a wind speed system so everything responds to the same parameters (clouds, water, cloth objects, etc). We slow down the reaction of the water to the wind over time, so the wind could veer or back quickly and the waves will slowly shift to match over time rather than be instant. As long as you pace the changes over a long enough time there is almost 0 computation hit.
     
  25. Killersan

    Killersan

    Joined:
    May 27, 2014
    Posts:
    76
    It's temporary until Unity will fix it. Normally You can create second camera with particles layer on it.
     
  26. KingLlama

    KingLlama

    Joined:
    Jul 18, 2015
    Posts:
    199
    Does this asset support infinite ocean??
     
  27. John-G

    John-G

    Joined:
    Mar 21, 2013
    Posts:
    1,122
    Yes.
     
  28. JJJohan1

    JJJohan1

    Joined:
    Oct 13, 2013
    Posts:
    11
    Hi guys,

    experiencing some issues with what looks kind of like floating point error. In my project I use the ocean at a slightly smaller scale than the demo and am experiencing very bad deformation when rotating or moving my view. This only happens when displacement is turned on.

    This is also reproducable in the demo scene that comes with Ceto but you'll need to zoom in quite close to the water as it's at a somewhat larger scale.

    Please see the below recording for info.
    Becomes very noticable 40 seconds in!

     
    kideternal likes this.
  29. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    There are some parameters that can be quite expensive to change. Ceto does a good job of hiding this.

    The foam amount/coverage, level and choppiness are all free to change. There is no cost.

    The wind direction, wind speed, wave age and Fourier size are costly to change as they require the spectrum data to be recreated. This takes about 80ms at a Fouier size of 64.

    The data is created on a separate thread so you don't really notice a impact on the fps but there will still be a lag from the time the settings change to the time the waves change. Ceto will also cache the last 10 spectrums and will check to set if there is a previous one it can use in which case theres no cost.

    A Fourier size of 32 is cheaper but I don't think its much less than 64. I would not use 32 unless its low end hardware like mobiles.

    It is infinite but there is a bug where the grid can disappear if you go to far from the horizon. If you get that let me know and I will show you what line to comment out to fix it.

    Ahh, thanks. Someone else did report that recently (@spraycanmansam) but I have had trouble reproducing it.

    It has to do with the camera rotation. The projected grid is having trouble dealing with it.

    Would it be possible to get a copy of your scene in the video with the same camera controller?
     
    Last edited: Feb 11, 2016
  30. JJJohan1

    JJJohan1

    Joined:
    Oct 13, 2013
    Posts:
    11
    What I'll do is modify the demo scene with a freelook camera and the ocean settings (read: no shader or script code modified so reproducable just fine). Unfortunately I can't send you the video's project file as proprietary to the company I work for :).

    Will post it up shortly.

    Err.. Just realised it'd be a bit rude to post the project seeing as it'd contain your assets so I'll PM them.
     
  31. Kiwi-Hawk

    Kiwi-Hawk

    Joined:
    Jul 17, 2015
    Posts:
    288
    Kia ora

    Just wanted to say Thank you, a lot of what I'm doing here is way over my head and a vert steep learning curve but a short read and a drag and drop and I got:



    Just need to work out where and what if need be to tweak
     
    scrawk likes this.
  32. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    Got thanks. I can see the issue. Think I know what it is but not sure at the moment.
     
    kideternal likes this.
  33. shuao23

    shuao23

    Joined:
    Dec 19, 2013
    Posts:
    33
    Calling Query waves multiple times (for buoyancy) can create a large amount of garbage. Will there be a garbage collection optimization (object pooling i guess) anytime soon? I am getting more than 100kb of alloc. Thanks

     
  34. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    Yes these will be. I had not taken a look at the wave queries memory allocations until recently.

    In the next update the wave query allocations have been reduce to 0.
     
    shuao23 likes this.
  35. Kiwi-Hawk

    Kiwi-Hawk

    Joined:
    Jul 17, 2015
    Posts:
    288
    Would I need to change to the Transparent Prefab to blend out the waters edge a little or can I tweak that?
     
  36. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    Nope. The blending works on both the opaque and transparent prefabs. Both should look the same. Its just there render queue that's different.

    If you go to the UnderWater component on the ocean object there is a edge fade setting you can adjust to increase the fading.
     
  37. Kiwi-Hawk

    Kiwi-Hawk

    Joined:
    Jul 17, 2015
    Posts:
    288
    Thanks so much mate,.. looking much better at the edges
     
  38. gibmation

    gibmation

    Joined:
    Dec 1, 2014
    Posts:
    311
    Thanks this worked really well.

    I also tried the shoremask scripts and they seem to work well.

    However is it possible to increase the size or width of the shore foam.

    Thanks again

    Gus.
     

    Attached Files:

  39. gibmation

    gibmation

    Joined:
    Dec 1, 2014
    Posts:
    311
    ok figured it out thanks.
     
  40. Tony-Lovell

    Tony-Lovell

    Joined:
    Jul 14, 2014
    Posts:
    127
    Can you share some settings that you found nice?

    Thanks.

    tone
     
  41. rageingnonsense

    rageingnonsense

    Joined:
    Dec 3, 2014
    Posts:
    99
    Not sure if this has been addressed or not, but I just had an issue compiling my project into a build due to include paths in these ocean shaders not using "./" before the filenames. It is unable to find them on build (curiously though it is ok in the editor).
     
  42. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    Is this with the 1.1.0 test version I sent you? All the shaders should have the "./" added to them in that version.
     
  43. Louen_ZT

    Louen_ZT

    Joined:
    Dec 11, 2015
    Posts:
    4
    Hi there. First of all, great work! Ceto is amazing! Also, I'm having an issue when using it. For some reason, when having the Planar Reflection script turned on, I'm getting a weird glitch. I'm getting small black and white rectangles popping every X frames around the water, they last only 1 frame. Sometimes bigger, sometimes smaller, they're like the one in the photo I'm attaching or totally black ones. Any clues where this problem might be coming from? Thank you for your help.

    Bug1.png
     
  44. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    Hi, Thanks.

    Do you have any particles in the scene? What version of Unity or you using?

    If so that sounds like it might be one of the issues Unity 5.3 is having with the particles. On the PlanarReflection script is a layer mask. Can you deselect what ever layer your particles are on and see if it goes away. You may need to make a layer just for your particles if you have not already.

    If that does not work can you deselect each layer from the reflection mask until you find which one is causing it.

    Basically the issue is there is something in your scene (most likely a particle effect) that does not like being render by the reflection camera. I cant help much more until I know what it is.
     
  45. rageingnonsense

    rageingnonsense

    Joined:
    Dec 3, 2014
    Posts:
    99
    No this is with 1.0.9. I'll stop bugging you with this path thing, seems like it will be fixed in the next release.
     
  46. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    The new Ceto version 1.1.0 is now complete and will be submitted to the asset store tomorrow. It then normally takes 5 days to be approved.

    A few people did get a early version for testing. Thanks for your input. It help pick up some critical bugs. That issue this version was having with the dark patches on the ocean when using certain image effects (like global fog) has been fixed. You can download the final version from the same link if your interested.

    There are lots of new features for this version but nothing major. This version has been mostly about polishing and improving performance of what is already there and of course lots of bug fixes.

    This version has however had the most new features added since release and I expect the new few versions to add even more. The next version will focus on buoyancy, boat wakes and shore waves as I know it has been much requested and long delayed.

    Ceto Version 1.1.0

    - Fixed a crash caused by using the normal overlay in SM2.

    - Fixed a exception being thrown if heights queried before spectrum buffers being created.

    - CPU Fourier math now 30% faster.

    - CPU spectrum init now 30% faster.

    - Creation of spectrum (from wind speed, wave age, etc) now 30% faster.
    This is only calculated if the settings change.

    - There is now a AddAutoShoreMask script. Add this to your terrain and it will create
    a shore line automatically at run time. This is not recommended for very large terrain
    as it will be to slow. You will still need to make the masks manually in this case.

    - There is now a editor window (Windows/Ceto/ShoreMaskExporter) that can be used to create
    the shore mask for a terrain and save them as a png to the asset folder. You must have a terrain
    selected in the scene before clicking the 'Export Shore Masks' button. You can then use Ceto's
    AddShoreMask script and add the masks to the appropriate slots. More detail on this will be
    added to the manual soon.

    - There are now two spectrum type options, Unified and Phillips. Phillips is cheaper but
    does not scale well when wind speed is increased. Unified is more expensive but scales
    better when wind speed increased. Both have there own unique look. There is also a
    UnifiedPhillips option which is a mix of the two.

    - There is now a CUSTOM spectrum type option. This allows you to create your own spectrum.
    You need to create a script that implements the ICustomWaveSpectrum interface.
    See the CustonWaveSpectrumExample script to see how to do this.

    - A new Shader key word has been added (CETO_USE_4_SPECTRUM_GRIDS). This is used to reduce the
    amount of texture look ups in the shader when only 1 or 2 grids are used.

    - There are now options to use 1 to 4 spectrum grids. Each grid requires its own Fourier
    transform so less grids is cheaper but will have less detail and the texture tiling will
    be more visible. The ocean shader is also cheaper to render when 1 or 2 grids are used.
    There are a number of spectrum settings like grid size, wave amp and choppyness that can be
    changed per grid in the scripts. These can be found in the WaveSpectrumCondition parent classes
    such as PhillipsSpectrumCondition, UnifiedSpectrumCondition and UnifiedPhillipsSpectrumCondition.
    Adjusting these settings during run time not currently supported.

    - Moved some data processing of CPU fourier results off main thread saving about 1.0ms at default settings.
    If you suspect this has caused a threading bug you can disable it by settings DISABLE_PROCESSDATA_MULTITHREADING
    to true in the Ocean script.

    - Fixed a issue with the refraction distortions when using USE_OCEAN_DEPTH_PASS mode causing
    pixels above the water being distorted. The last version broke this.

    - Fixed a issue where the ocean was disappearing in certain cases like if the camera was moved
    a very far distance in a single frame or if another camera thats was far away was enabled.

    - Fixed a issue where a mesh was not being destroyed between scenes.

    - Fixed a issue where the reflection and ocean depth cam were not using the culling distances from camera.
    You can enable this by ticking the 'Copy Cull Distances' on the PlanarReflection script on the ocean.
    Note - The reflection cam uses a oblique projection matrix so its distance culling must be spherical.
    This means that the culling does not quite match up with the camera. The reflections will be culled slightly
    before the cameras. This mismatch can be reduced by also setting the camera to spherical culling.

    - There is now a ReflectionCameraCullingDistances script that can be used to manually adjust the culling
    distances on the reflection camera if you want. You must add this script to your camera and the script
    will update the culling distances on the reflection camera created for this camera. You must untick the
    'Copy Cull Distances' on the PlanarReflection script on the ocean otherwise it will copy directly from
    the camera and over write these distances.

    - Applying the global foam texture to the spectrum foam is now optional. Untick the 'texture foam' option on the
    WaveSpectrum script to disable it.

    - Applying the global foam texture to the overlay foam is now optional. Untick the 'texture foam' option on the
    overlay script to disable it.

    - Spectrum foam now uses the same choppyness value as the waves so the foam location better matches that of the waves. This does mean that foam will be less visible at the default choppyness value of 0.8. See me if you want change it back. You may need to adjust your foam and coverage settings.

    - Fixed a crash in the Fourier task that could occur if the displacements were disabled as a multithreading task was running.

    - The shaders have been restructured where they now contain no code, just defines and cginc's.
    This has been done so support for SM5 specific features (or SM2 lack of features) will be easier to add
    in a future update.

    - Wave queries now have 0 memory allocations.

    - You can now change the sampling for the default query used by the ocean using the SetQueryWavesSampling function on the ocean instance.

    - You can now query the ocean normal at any location by calling the QueryNormal function on the ocean instance
    This calculates the normal using finite difference which is not 100% accurate and will be a bit slow but this is the only option.

    - Fixed a bug where underwater effect was dependant on far plane distance. This meant if the far plane value changes the fog looks different. Effect should now look the same if far plane value changed. You may need to re-adjust the below inscatter scale and the below absorption scale settings.

    - Fixed a recursive culling error in Unity 5.4

    - Task scheduler will now cancel threaded tasks when scene/game exits.

    - Added ./ to the folder path for cginc files.

    - Fixed a bug where spectrum max displacement was using MAX_WAVE_HEIGHT instead of MAX_SPECTRUM_WAVE_HEIGHT.

    - Fixed a bug where the queried wave height was not being clamped to MAX_SPECTRUM_WAVE_HEIGHT.

    - max overlay and spectrum heights lowered (overlay from 30 to 20 and spectrum from 50 to 40) as the larger
    values could cause problems and they were higher than most people needed.

    - The AddWaveOverlay and AddShoreMask scripts rotation will now be relative to the parent. There is a rotation
    mode setting on the script that can disable this if needed.

    - AddShoreMask now has a offset value so you can add the script to your terrain and use the offset to match the terrains position.

    - The wave foam and slopes will no longer be sampled by manually providing the derivatives. Turned out this was not
    supported on PS4 and was of little use anyway. It also saved 10-20 math instructions in the shader.
    This means the slope and foam smoothing settings are not on the wave spectrum script any more.

    - There is now a OceanCameraSettings script you can add to any camera to adjust how the ocean is rendered for this camera.You can do things like disable the reflection, underwater, or overlays as well as adjust there resolution.
    This is designed for secondary cameras in the scene that dont need to render the ocean at full detail
    and will help with performance. If the camera does not have one of these scripts attached to it will just use the
    default settings on the ocean.

    - Fixed a issue where the projection was not taking the grid scale into account. This was causing the grid resolution to
    be lest than optimal and causing it to jitter in some cases. On screen grid resolution should now be about 5 times better with no extra cost.

    - Fixed a issue with the height overlays being flipped on Mac.

    - The AddWaveOverlayBase class now has a Translate function you can call if you offset your scene.
    This will offset the overlays correctly for the foam trail script.
     
  47. Louen_ZT

    Louen_ZT

    Joined:
    Dec 11, 2015
    Posts:
    4
    Thanks for the reply @scrawk. You were right about it being a layer, but nothing to do with particles, for now there are no particle systems at all in the scene. The only layer I was reflecting was a "Terrain" layer that only contains the terrain you can see in the picture. If I disable the reflection of the terrain, the glitch disappears. Any clue what might be causing that in a terrain? :O Thanks once more!
     
    Last edited: Feb 16, 2016
  48. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    Im not sure what would cause the terrain to do that. Never heard of that before.

    If you can make a simple example scene with the issue in it or work out instructions on how to reproduce it I can normally fix theses sorts of things pretty quick.

    It may also be worth waiting for the next Ceto update to come out and try that.

    EDIT - It might also be worth setting the reflection resolution to full and the downsize to none and see if it goes away.
     
  49. Louen_ZT

    Louen_ZT

    Joined:
    Dec 11, 2015
    Posts:
    4
    Hi again @scrawk. Ok, I did what you suggested and inmediately found out what was causing it. The terrain texture had smoothness set to 1. I just reduced it to 0 and played a bit with the light to get a similar look in the scene. The glitch was gone.

    So the problem seems to be something like reflecting very smooth materials? . Just in case the information can give you a hint of a bug or something :). Looking forward to the new Ceto version, although I won't be able to implement it on this same project, I've got a super tight deadline!
     
    Last edited: Feb 16, 2016
    hopeful and scrawk like this.
  50. gibmation

    gibmation

    Joined:
    Dec 1, 2014
    Posts:
    311
    Apologies for not sharing...

    What I found is that the foam at shore line is dependent on the slope you have at edge of terrain - on say the beach, the steeper the slope the less foam.
    So to achieve the type of foam I wanted I just made slopes to replace cliffs at edges of my beaches.

    I also noticed that edge effect is not visible in editor only in game window.

    Pic A: Cliff edge
    Pic B: Slope edge
     

    Attached Files:

    • a.JPG
      a.JPG
      File size:
      121.3 KB
      Views:
      1,043
    • b.JPG
      b.JPG
      File size:
      66.3 KB
      Views:
      1,005
    • 01.JPG
      01.JPG
      File size:
      106.3 KB
      Views:
      1,034
    • 02.JPG
      02.JPG
      File size:
      117.8 KB
      Views:
      988
    • 03.JPG
      03.JPG
      File size:
      86.3 KB
      Views:
      999
    Tony-Lovell likes this.