Hi all,

I'm trying to port the Ogre3D ocean demo to OpenSceneGraph but I've problem 
achieving the ocean demo effect. Has anybody did this before?

VP:


Code:

uniform float BumpScale;
uniform vec2 textureScale;
uniform vec2 bumpSpeed;
uniform float time;
uniform float waveFreq;
uniform float waveAmp;
uniform mat4 osg_ViewMatrix;

varying vec3 eyePosition;
varying mat3 rotMatrix; //  transform from tangent to obj space
varying vec2 bumpCoord0;
varying vec2 bumpCoord1;
varying vec2 bumpCoord2;
varying vec3 eyeVector;

// wave functions
struct Wave {
  float freq;  // 2*PI / wavelength
  float amp;   // amplitude
  float phase; // speed * 2*PI / wavelength
  vec2 dir;
};

void main(void)
{
        #define NWAVES 2

        Wave wave[NWAVES];

        wave[0] = Wave( waveFreq, waveAmp, 0.5, vec2(-1, 0) );
        wave[1] = Wave( 3.0 * waveFreq, 0.33 * waveAmp, 1.7, vec2(-0.7, 0.7) );

    vec4 P = gl_Vertex;

        // sum waves
        float ddx = 0.0, ddy = 0.0;
        float deriv;
        float angle;

        // wave synthesis using two sine waves at different frequencies and 
phase shift
        for(int i = 0; i<NWAVES; ++i)
        {
                angle = dot(wave[i].dir, P.xy) * wave[i].freq + time * 
wave[i].phase;
                P.z += wave[i].amp * sin( angle );
                
                // calculate derivate of wave function
                deriv = wave[i].freq * wave[i].amp * cos(angle);
                ddx += deriv * wave[i].dir.x;
                ddy += deriv * wave[i].dir.y;
        }

        // compute the 3x3 tranform from tangent space to object space
        // compute tangent basis
        vec3 T = normalize(vec3(0.0, 1.0, ddy)) * BumpScale;
    vec3 B = normalize(vec3(1.0, 0.0, ddx)) * BumpScale;
    vec3 N = normalize(vec3(-ddx, -ddy, 1.0));

        rotMatrix = mat3(T, B, N);

        gl_Position = gl_ModelViewProjectionMatrix * P;

        // calculate texture coordinates for normal map lookup
        bumpCoord0.xy = gl_MultiTexCoord0.xy * textureScale + time * bumpSpeed;
        bumpCoord1.xy = gl_MultiTexCoord0.xy * textureScale * 2.0 + time * 
bumpSpeed * 4.0;
        bumpCoord2.xy = gl_MultiTexCoord0.xy * textureScale * 4.0 + time * 
bumpSpeed * 8.0;
        
        eyePosition = -osg_ViewMatrix[3].xyz / osg_ViewMatrix[3].w; 
//vec3(gl_ModelViewMatrix * P);

        eyeVector = P.xyz - eyePosition; // eye position in vertex space
}




FP:


Code:

uniform sampler2D NormalMap;
uniform samplerCube EnvironmentMap;
uniform vec4 deepColor;
uniform vec4 shallowColor;
uniform vec4 reflectionColor;
uniform float reflectionAmount;
uniform float reflectionBlur;
uniform float waterAmount;
uniform float fresnelPower;
uniform float fresnelBias;
uniform float hdrMultiplier;

varying mat3 rotMatrix; // first row of the 3x3 transform from tangent to cube 
space
varying vec2 bumpCoord0;
varying vec2 bumpCoord1;
varying vec2 bumpCoord2;
varying vec3 eyeVector;

void main(void)
{
        // sum normal maps
        // sample from 3 different points so no texture repetition is noticeable
    vec4 t0 = texture2D(NormalMap, bumpCoord0) * 2.0 - 1.0;
    vec4 t1 = texture2D(NormalMap, bumpCoord1) * 2.0 - 1.0;
    vec4 t2 = texture2D(NormalMap, bumpCoord2) * 2.0 - 1.0;
    vec3 N = t0.xyz + t1.xyz + t2.xyz;

    N = normalize(rotMatrix * N);

        // reflection
    vec3 E = normalize(eyeVector);
    vec3 R = reflect(E, N);
    // Ogre conversion for cube map lookup
    R.y = -R.y;

    vec4 reflection = textureCube(EnvironmentMap, R, reflectionBlur);
    // cheap hdr effect
    reflection.rgb *= (reflection.r + reflection.g + reflection.b) * 
hdrMultiplier;

        // fresnel
    float facing = 1.0 - dot(-E, N);
    float fresnel = clamp(fresnelBias + pow(facing, fresnelPower), 0.0, 1.0);

    vec4 waterColor = mix(shallowColor, deepColor, facing) * waterAmount;

    reflection = mix(waterColor,  reflection * reflectionColor, fresnel) * 
reflectionAmount;
    gl_FragColor = waterColor + reflection;
}




Main code:


Code:

osg::TextureCubeMap* readCubeMap()
{
        osg::TextureCubeMap* cubemap = new osg::TextureCubeMap;

        osg::Image* imagePosX = osgDB::readImageFile( 
"./Images/cubemapsJS/morning_RT.jpg" );
        osg::Image* imageNegX = osgDB::readImageFile( 
"./Images/cubemapsJS/morning_LF.jpg" );
        osg::Image* imagePosY = osgDB::readImageFile( 
"./Images/cubemapsJS/morning_FR.jpg" );
        osg::Image* imageNegY = osgDB::readImageFile( 
"./Images/cubemapsJS/morning_BK.jpg" );
        osg::Image* imagePosZ = osgDB::readImageFile( 
"./Images/cubemapsJS/morning_DN.jpg" );
        osg::Image* imageNegZ = osgDB::readImageFile( 
"./Images/cubemapsJS/morning_UP.jpg" );

        if (imagePosX && imageNegX && imagePosY /*&& imageNegY && imagePosZ && 
imageNegZ*/)
        {
                cubemap->setImage(osg::TextureCubeMap::POSITIVE_X, imagePosX);
                cubemap->setImage(osg::TextureCubeMap::NEGATIVE_X, imageNegX);
                cubemap->setImage(osg::TextureCubeMap::POSITIVE_Y, imagePosY);
                cubemap->setImage(osg::TextureCubeMap::NEGATIVE_Y, imageNegY);
                cubemap->setImage(osg::TextureCubeMap::POSITIVE_Z, imagePosZ);
                cubemap->setImage(osg::TextureCubeMap::NEGATIVE_Z, imageNegZ);

                cubemap->setWrap(osg::Texture::WRAP_S, 
osg::Texture::CLAMP_TO_EDGE);
                cubemap->setWrap(osg::Texture::WRAP_T, 
osg::Texture::CLAMP_TO_EDGE);
                cubemap->setWrap(osg::Texture::WRAP_R, 
osg::Texture::CLAMP_TO_EDGE);

                cubemap->setFilter(osg::Texture::MIN_FILTER, 
osg::Texture::LINEAR_MIPMAP_NEAREST);
                cubemap->setFilter(osg::Texture::MAG_FILTER, 
osg::Texture::LINEAR);
        }

        return cubemap;
}

class updateShader : public osg::Uniform::Callback
{
public:
        updateShader() : time(0.0), dir(true) {}
        virtual void operator() ( osg::Uniform* uniform, osg::NodeVisitor* nv )
        {
                time = nv->getFrameStamp()->getSimulationTime();
                
                uniform->set( fmod(time, 100.0f) );
        }

        bool dir;
        float time;
};

void setupOceanShader(osg::StateSet* stateset)
{
        osg::Shader* vertexShader = new osg::Shader( osg::Shader::VERTEX );
        osg::Shader* fragmentShader = new osg::Shader( osg::Shader::FRAGMENT );

        vertexShader->loadShaderSourceFromFile( "./shaders/ocean2GLSL.vert" );
        fragmentShader->loadShaderSourceFromFile( "./shaders/ocean2GLSL.frag" );

        osg::Program* program = new osg::Program;
        program->addShader( vertexShader );
        program->addShader( fragmentShader );
        stateset->setAttributeAndModes( program, osg::StateAttribute::ON );

        osg::Uniform* param1 = new osg::Uniform( "BumpScale", 0.2f );
        stateset->addUniform( param1 );
        osg::Uniform* param2 = new osg::Uniform( "textureScale", 
osg::Vec2(25.0, 26.0) );
        stateset->addUniform( param2 );
        osg::Uniform* param3 = new osg::Uniform( "bumpSpeed", osg::Vec2(0.015, 
0.005) );
        stateset->addUniform( param3 );
        osg::Uniform* param4 = new osg::Uniform( "time", 100.0f );
        param4->setUpdateCallback( new updateShader );
        stateset->addUniform( param4 );
        osg::Uniform* param5 = new osg::Uniform( "waveFreq", 0.028f );
        stateset->addUniform( param5 );
        osg::Uniform* param6 = new osg::Uniform( "waveAmp", 1.8f );
        stateset->addUniform( param6 );

        osg::Uniform* param7 = new osg::Uniform( "deepColor", osg::Vec4(0, 0.3, 
0.5, 1.0) );
        stateset->addUniform( param7 );
        osg::Uniform* param8 = new osg::Uniform( "shallowColor", osg::Vec4(0, 
1, 1, 1.0) );
        stateset->addUniform( param8 );
        osg::Uniform* param9 = new osg::Uniform( "reflectionColor", 
osg::Vec4(0.95, 1, 1, 1.0) );
        stateset->addUniform( param9 );
        osg::Uniform* param10 = new osg::Uniform( "reflectionAmount", 1.0f);
        stateset->addUniform( param10 );
        osg::Uniform* param11 = new osg::Uniform( "reflectionBlur", 0.0f);
        stateset->addUniform( param11 );
        osg::Uniform* param12 = new osg::Uniform( "waterAmount", 0.3f);
        stateset->addUniform( param12 );
        osg::Uniform* param13 = new osg::Uniform( "fresnelPower", 5.0f);
        stateset->addUniform( param13 );
        osg::Uniform* param14 = new osg::Uniform( "fresnelBias", 0.328f);
        stateset->addUniform( param14 );
        osg::Uniform* param15 = new osg::Uniform( "hdrMultiplier", 0.471f);
        stateset->addUniform( param15 );
        osg::Uniform* param16 = new osg::Uniform( "NormalMap", 0 );
        stateset->addUniform( param16 );
        osg::Uniform* param17 = new osg::Uniform( "EnvironmentMap", 1 );
        stateset->addUniform( param17 );

        osg::Image* image = osgDB::readImageFile( "./Images/waves2.dds" );
        osg::Texture2D* tex = new osg::Texture2D( image );
        tex->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
        tex->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
        //tex->setWrap(osg::Texture::WRAP_R, osg::Texture::REPEAT);
        tex->setFilter(osg::Texture::MIN_FILTER, 
osg::Texture::LINEAR_MIPMAP_NEAREST);
        tex->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);

        stateset->setTextureAttributeAndModes( 0, tex, osg::StateAttribute::ON 
);
        stateset->setTextureAttributeAndModes( 1, readCubeMap(), 
osg::StateAttribute::ON );
}

int main(int argc, char** argv)
{
        osg::Group* root = new osg::Group;
        osg::Geode* model = new osg::Geode;

        model->addDrawable( GenTriGrid(1000, 1000, 50, 50).get() );

        root->addChild( model );
        
        osg::StateSet* stateset = model->getOrCreateStateSet();

        osg::BlendFunc* trans = new osg::BlendFunc;
        trans->setFunction(osg::BlendFunc::SRC_ALPHA, 
osg::BlendFunc::ONE_MINUS_SRC_ALPHA);

        stateset->setAttributeAndModes(trans, osg::StateAttribute::ON);

        setupOceanShader(stateset);

        osgViewer::Viewer viewer;

        viewer.addEventHandler( new 
osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
        viewer.addEventHandler(new osgViewer::StatsHandler);

        viewer.setSceneData( root );
        viewer.realize();

        return viewer.run();
}




Thank you.

Regards,
Tim

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



<<attachment: ocean.jpg>>

_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to