OpenSceneGraph Forum Forum Index OpenSceneGraph Forum
Official forum which mirrors the existent OSG mailing lists. Messages posted here are forwarded to the mailing list and vice versa.
 
   FAQFAQ    SearchSearch    MemberlistMemberlist    RulesRules    UsergroupsUsergroups    RegisterRegister 
 Mail2Forum SettingsMail2Forum Settings  ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
   AlbumAlbum  OpenSceneGraph IRC ChatOpenSceneGraph IRC Chat   SmartFeedSmartFeed 

Masked FFTOceanSurface


 
Post new topic   Reply to topic    OpenSceneGraph Forum Forum Index -> osgOcean [osgOcean]
View previous topic :: View next topic  
Author Message
9Volt
User


Joined: 30 Nov 2010
Posts: 29

PostPosted: Wed May 30, 2012 12:32 pm    Post subject:
Masked FFTOceanSurface
Reply with quote

Hi,

I added a user-definable mask functionallity to FFTOceanSurface. The mask applies a height offset to the ocean tiles which allows the usage of the FFTOceanSurface as rivers and lakes (even waterfalls) on different altitudes in the same scene without having it protrude the ground (I plan to combine this with osgEarth).

Its currently more of a dirty hack, but still its quite usable.

In the FFTOceanSurface Header I added 2 variables and changed the ctor:
Code:

osg::Image *_surfMask;
float _sufMaskMaxDist;

public:
FFTOceanSurface(unsigned int FFTGridSize = 64,
 unsigned int resolution = 256,
 unsigned int numTiles = 17,
 const osg::Vec2f& windDirection = osg::Vec2f(1.1f, 1.1f),
 float windSpeed = 12.f,
 float depth = 1000.f,
 float reflectionDamping = 0.35f,
 float waveScale = 1e-8f,
 bool isChoppy = true,
 float choppyFactor = -2.5f,
 float animLoopTime = 10.f,
 unsigned int numFrames = 256,
 osg::Image *_surfMask=NULL,
 float _sufMaskMaxDist=100.0f
);


In FFTOceanSurface.cpp I added this to the computeSea method:

Before the frame loop:
Code:

int imgDim = 0;
int imgBytesPerLine = 0;
int imgBytePerPixel = 0;

if(_surfMask)
{
 imgDim =__min(_surfMask->s(),_surfMask->t());
 imgBytePerPixel = _surfMask->computeNumComponents(_surfMask->getPixelFormat());
 imgBytesPerLine = _surfMask->s()*imgBytePerPixel;
}


Within the frame loop before calling OceanTile() for level 0:

Code:

int sizeHeights = heights->size();
int dimHeights = (int)floor(sqrt((float)sizeHeights)+0.5f);

if(_surfMask && imgDim>0 && dimHeights>0) // Apply surface mask
{
  //Handle scaling difference between
  if(dimHeights >= imgDim)
  {
    int imgScaling = dimHeights/imgDim;
    int scaledImgDim = imgDim*imgScaling;
    for(int y= 0; y < dimHeights;y++)
    {
      int yRow = dimHeights*y;
      unsigned char* pImgOsgLine = ((unsigned char*)_surfMask->data())+ imgBytesPerLine * (y/imgScaling);
      for(int x = 0; x < dimHeights;x++)
      {
        if((x < scaledImgDim) &&(y < scaledImgDim))
        {
          float alpha =(float)*((unsigned char*)(pImgOsgLine+(x/imgScaling)*imgBytePerPixel))/255.0f;
          float oldVal = heights->at(yRow+x);
          heights->at(yRow+x) = alpha*oldVal - _sufMaskMaxDist*(1.0f-alpha);
        }
        else
        {
          heights->at(yRow+x) = -_sufMaskMaxDist;
        }
      }
    }
  }
  else
  {
    int imgScaling_d1 = imgDim/dimHeights;
    int scaledImgDim = imgDim/imgScaling_d1;
    for(int y= 0; y < dimHeights;y++)
    {
      int yRow = dimHeights*y;
      unsigned char* pImgOsgLine = ((unsigned char*)_surfMask->data()) + imgBytesPerLine * y*imgScaling_d1;
      for(int x = 0; x < dimHeights;x++)
      {
        if((x < scaledImgDim) &&(y < scaledImgDim) )
        {
          float alpha =(float)*((unsigned char*)(pImgOsgLine+x*imgScaling_d1*imgBytePerPixel))/255.0f;
          float oldVal = heights->at(yRow+x);
          heights->at(yRow+x) = alpha*oldVal - _sufMaskMaxDist*(1.0f-alpha);
        }
        else
        {
          heights->at(yRow+x) = -_sufMaskMaxDist;
        }
      }
    }
  }
}


Greetings,
Oliver
Back to top
View user's profile Send private message
kcbale
User


Joined: 04 Mar 2011
Posts: 68

PostPosted: Thu May 31, 2012 8:48 am    Post subject:
Masked FFTOceanSurface
Reply with quote

Hi Oliver,

Any chance you could send me the modified files so I can run it and get a feel for it?


Cheers,


Kim.

On 30 May 2012 13:32, Oliver Neumann < (
Only registered users can see emails on this board!
Get registred or enter the forums!
)> wrote:
Quote:
Hi,

I added a user-definable mask functionallity to FFTOceanSurface. The mask applies a height offset to the ocean tiles which allows the usage of the FFTOceanSurface as rivers and lakes on different altitudes in the same scene without having it protrude the ground (I plan to combine this with osgEarth).

Its currently more of a dirty hack, but still its quite usable.

In the FFTOceanSurface Header I added 2 variables and changed the ctor:

Code:

osg::Image *_surfMask;
float _sufMaskMaxDist;

public:
FFTOceanSurface(unsigned int FFTGridSize = 64,
 unsigned int resolution = 256,
 unsigned int numTiles = 17,
 const osg::Vec2f& windDirection = osg::Vec2f(1.1f, 1.1f),
 float windSpeed = 12.f,
 float depth = 1000.f,
 float reflectionDamping = 0.35f,
 float waveScale = 1e-8f,
 bool isChoppy = true,
 float choppyFactor = -2.5f,
 float animLoopTime = 10.f,
 unsigned int numFrames = 256,
 osg::Image *_surfMask=NULL,
 float _sufMaskMaxDist=100.0f
);




In FFTOceanSurface.cpp I added this to the computeSea method:

Before the frame loop:

Code:

int imgDim = 0;
int imgBytesPerLine = 0;
int imgBytePerPixel = 0;

if(_surfMask)
{
 imgDim =__min(_surfMask->s(),_surfMask->t());
 imgBytePerPixel = _surfMask->computeNumComponents(_surfMask->getPixelFormat());
 imgBytesPerLine = _surfMask->s()*imgBytePerPixel;
}




Within the frame loop before calling OceanTile() for level 0:


Code:

int sizeHeights = heights->size();
int dimHeights = (int)floor(sqrt((float)sizeHeights)+0.5f);

if(_surfMask && imgDim>0 && dimHeights>0) // Apply surface mask
{
 //Handle scaling difference between
 if(dimHeights >= imgDim)
 {
   int imgScaling = dimHeights/imgDim;
   int scaledImgDim = imgDim*imgScaling;
   for(int y= 0; y < dimHeights;y++)
   {
     int yRow = dimHeights*y;
     unsigned char* pImgOsgLine = ((unsigned char*)_surfMask->data())+ imgBytesPerLine * (y/imgScaling);
     for(int x = 0; x < dimHeights;x++)
     {
       if((x < scaledImgDim) &&(y < scaledImgDim))
       {
         float alpha =(float)*((unsigned char*)(pImgOsgLine+(x/imgScaling)*imgBytePerPixel))/255.0f;
         float oldVal = heights->at(yRow+x);
         heights->at(yRow+x) = alpha*oldVal - _sufMaskMaxDist*(1.0f-alpha);
       }
       else
       {
         heights->at(yRow+x) = -_sufMaskMaxDist;
       }
     }
   }
 }
 else
 {
   int imgScaling_d1 = imgDim/dimHeights;
   int scaledImgDim = imgDim/imgScaling_d1;
   for(int y= 0; y < dimHeights;y++)
   {
     int yRow = dimHeights*y;
     unsigned char* pImgOsgLine = ((unsigned char*)_surfMask->data()) + imgBytesPerLine * y*imgScaling_d1;
     for(int x = 0; x < dimHeights;x++)
     {
       if((x < scaledImgDim) &&(y < scaledImgDim) )
       {
         float alpha =(float)*((unsigned char*)(pImgOsgLine+x*imgScaling_d1*imgBytePerPixel))/255.0f;
         float oldVal = heights->at(yRow+x);
         heights->at(yRow+x) = alpha*oldVal - _sufMaskMaxDist*(1.0f-alpha);
       }
       else
       {
         heights->at(yRow+x) = -_sufMaskMaxDist;
       }
     }
   }
 }
}




Greetings,
Oliver

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=47939#47939




Attachments:
http://forum.openscenegraph.org//files/ocean_masked_157.png


_______________________________________________
osg-users mailing list
(
Only registered users can see emails on this board!
Get registred or enter the forums!
)
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org




--
osgOcean - http://code.google.com/p/osgocean/

------------------
Post generated by Mail2Forum
Back to top
View user's profile Send private message
9Volt
User


Joined: 30 Nov 2010
Posts: 29

PostPosted: Fri Jun 01, 2012 7:19 am    Post subject:
Reply with quote

Hi Kim,

I attached the two files to this posting. The usage is simple, just
use osgDB::readImageFile("FILEPATH") to get the a mask image that will then be applied to modulate the heights in the computeSea function. The mask is white where no change is needed and black where the ocean should not be visible.

Currently it has some drawbacks:
-The average height and the height of the lesser LOD's treats the masking height (e.g. -100.0f) like the valid heights
-It is not easy to produce a specific height distribution aside from a plain surface thats bounded by a definable shore. River that flows down some rapids or multiple waterfalls are hard to get correctly. It would be better if the mask is supplied with specific (relative) ground heights so that e.g. 0 means no change and a mask value of e.g. 10 means the surface should on average be 10 units elevated
-LOD 0 (1 Quad) currently cannot benefit from the masking, maybe by using a shader/texture that has alpha values set like the mask, this effect can still be conveyed at LOD0

Cheers,
Oliver
Back to top
View user's profile Send private message
kcbale
User


Joined: 04 Mar 2011
Posts: 68

PostPosted: Fri Jun 01, 2012 7:32 am    Post subject:
Masked FFTOceanSurface
Reply with quote

Thanks Oliver, I'll have a look.

K.

On 1 June 2012 08:19, Oliver Neumann < (
Only registered users can see emails on this board!
Get registred or enter the forums!
)> wrote:
Quote:
Hi Kim,

I attached the two files to this posting. The usage is simple, just
use osgDB::readImageFile("FILEPATH") to get the a mask image that will then be applied to modulate the heights in the computeSea function. The mask is white where no change is needed and black where the ocean should not be visible.

Currently it has some drawbacks:
-The average height and the height of the lesser LOD's treats the masking height (e.g. -100.0f) like the valid heights
-It is not easy to produce a specific height distribution aside from a plain surface thats bounded by a definable shore. A river that flows down some rapids or multiple waterfalls are hard to get correctly. It would be better if the mask is supplied with specific (relative) ground heights so that e.g. 0 means no change and a mask value of e.g. 10 means the surface should on average be 10 units elevated
-LOD 0 (1 Quad) currently cannot benefit from the masking, maybe by using a shader/texture that has alpha values set like the mask, this effect can still be conveyed at LOD0

Cheers,
Oliver

------------------
Read this topic online here:

http://forum.openscenegraph.org/viewtopic.php?p=47991#47991




Attachments:
http://forum.openscenegraph.org//files/fftoceansurface_864.cpp
http://forum.openscenegraph.org//files/1719_1338534512._126.


_______________________________________________
osg-users mailing list
(
Only registered users can see emails on this board!
Get registred or enter the forums!
)
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org






--
osgOcean - http://code.google.com/p/osgocean/

------------------
Post generated by Mail2Forum
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    OpenSceneGraph Forum Forum Index -> osgOcean [osgOcean] All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum

Similar Topics
Topic Author Forum Replies Posted
No new posts Masked Occlusion Culling bbjorn General 0 Thu Jun 16, 2016 9:40 pm View latest post


Board Security Anti Bot Question MOD - phpBB MOD against Spam Bots
Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP