Sign in to follow this  

Water shader physics synchronisation

This topic is 4030 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a certain problem with synchronizing my shader behaviour of a water/ocean shader with the physics API, enabling my objects to float on the water. I already posted in all the forums concerning my problem, but nobody could help me there, so I tried to get an answer in a more interdisciplinary forum ;-) I have written an ocean shader using the Gerstner Waves approach, here's the necessary code: (it's Cg) #define NWAVES 2 Wave wave[NWAVES] = { { 1.0, 1.0, 0.5, float2(-1, 0) }, { 2.0, 0.5, 1.7, float2(-0.7, 0.7) } }; wave[0].freq = waveFreq; wave[0].amp = waveAmp; wave[0].dir = waveDirections.xy; wave[1].freq = waveFreq * 3.0; wave[1].amp = waveAmp * 0.33; wave[1].dir = waveDirections.zw; float4 P = IN.Position; // 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.xz) * wave[i].freq + time * wave[i].phase; P.y += 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; } OUT.Position = mul(WorldViewProj, P); When trying to synchronize it with my physics solutions I ran into certain problems, like the C++ code didn't seem to output the same results. Here is the C++ code I will explain it below then: Wave wave[2]; wave[0].freq = 0.001f * Math::Sqr(selLevel.Windkraft + 0.001f); wave[0].amp = 1.5f * selLevel.Windkraft; wave[0].phase = 0.7f; wave[0].dir = Vector2(WindDirectionShaderConstant.x,WindDirectionShaderConstant.y); wave[1].freq = wave[0].freq * 3.0f; wave[1].amp = wave[0].amp * 0.33f; wave[1].phase = 1.5f; wave[1].dir = Vector2(WindDirectionShaderConstant.z,WindDirectionShaderConstant.w); //Real P; //P = waterLevel; int triangle = 0; // sum waves float deltax = 0.0f, deltay = 0.0f; float deriv = 0.0f; //float angle = 0.0f; WaveTime += evt.timeSinceLastFrame; if (WaveTime >= Math::PI * 100.0f) WaveTime -= WaveTime; float dotProd[3] = {0.0f,0.0f,0.0f}; float angle[3] = {0.0f,0.0f,0.0f}; //float P[3] = {waterLevel,waterLevel,waterLevel}; Vector3 samplePositions[3] = {Vector3::ZERO,Vector3::ZERO,Vector3::ZERO}; WaveParam->setNamedConstant("time", WaveTime); // wave synthesis using two sine waves at different frequencies and phase shift //samplePos = ObjectSpace (im Bezug auf das Wasser) Koordinate des Fluidsamples Vector3 samplePos = mSceneMgr->getSceneNode("WaterNode")->_getFullTransform().inverse() * shipNode->getWorldPosition(); float fx = samplePos.x / 1025.0f; float fz = samplePos.z / 1025.0f; int ix,iz; if (fx >= 0.0f) ix = fx + 0.5f; else ix = fx - 0.5f; if (fz >= 0.0f) iz = fz + 0.5f; else iz = fz - 0.5f; samplePositions[0] = Vector3(ix * 1025, waterLevel, iz * 1025); //check in which triangle of the section the ship is if ((iz >= fz && ix >= fx) || (iz >= fz && ix < fx) || (iz < fz && ix >= fx)) { samplePositions[1] = Vector3((ix - 1) * 1025, waterLevel, iz * 1025); samplePositions[2] = Vector3(ix * 1025, waterLevel, (iz - 1) * 1025); triangle = 1; } else { samplePositions[1] = Vector3((ix + 1) * 1025, waterLevel, iz * 1025); samplePositions[2] = Vector3(ix * 1025, waterLevel, (iz + 1) * 1025); triangle = 0; } //Vector3 samplePos = mFluidSamples[j]->curPos; for (int j = 0; j < 3; j++) { for(int i = 0; i < 2; ++i) { dotProd[j] = Vector2(samplePositions[j].x,samplePositions[j].z).dotProduct(wave[i].dir); angle[j] = dotProd[j] * wave[i].freq + WaveTime * wave[i].phase; samplePositions[j].y += wave[i].amp * Math::Sin(angle[j]); //calculate derivate of wave function //deriv = wave[i].freq * wave[i].amp * Math::Cos(angle); //deltax += deriv * wave[i].dir.x; //deltay += deriv * wave[i].dir.y; } } samplePositions[0] = mSceneMgr->getSceneNode("WaterNode")->_getFullTransform() * samplePositions[0]; samplePositions[1] = mSceneMgr->getSceneNode("WaterNode")->_getFullTransform() * samplePositions[1]; samplePositions[2] = mSceneMgr->getSceneNode("WaterNode")->_getFullTransform() * samplePositions[2]; buoyancyPlane.redefine(samplePositions[0],samplePositions[1],samplePositions[2]); Real Planedistance = buoyancyPlane.getDistance(Vector3(shipNode->getWorldPosition().x,waterLevel,shipNode->getWorldPosition().z)); //buoyancyPlane = Plane(samplePositions[0], samplePositions[1], samplePositions[2]); buoyancyPlane.d = -(Planedistance + waterLevel); buoyancyPlane.normal = Vector3(0,1,0); What I do here is, I take the position of my floating object, here it is a ship, and determine on which triangle of the water I am now, then I calculate the positions relevant depending on the tesselation of the water surface (20x20 in this case) and calculate the displacement for the three resulting samples. Then I construct a plane from these sample points for a buoyancy plane. I calculate the distance then to the defined water level to determine the height of water at the certain place. The APIs used are Ogre and OgreNewt, a wrapper for the Newton API which supports buoyancy planes. The problem is it works and the ship floats somehow, but it doesn't seem to float on the water surface. I synchronized also the time with the shader. Do you see some programmatical or logical mistakes in it? Can I even expect the same results from C++ and a shader program (Cg)? Please feel free to ask any further questions if something is unclear! Help would be very much appreciated!

Share this post


Link to post
Share on other sites
Another question: Can this be a precision issue between CPU and GPU, namely calculation of the sine function? Tests implied that to me since all other code sections work well and synched but the sine calculation.

Share this post


Link to post
Share on other sites

This topic is 4030 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this