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