Shader from the Ocean Sample isn't animated

Problems building or running the engine, queries about how to use features etc.
Tom Duhamel
Gnoblar
Posts: 9
Joined: Fri Nov 15, 2019 2:07 pm
x 3

Shader from the Ocean Sample isn't animated

Post by Tom Duhamel »

Ogre Version: 1.9
Operating System: Fedora 41/KDE
Render System: OpenGL

I have copied the material from the Ocean sample, along with the 2 programs that it needs. I'm using GLSL.

The shader displays perfectly on a plane, all bumps and reflections are correct. However, the expected animation isn't happening. I'm assuming I'm missing something really stupid, but I can't figure it out. Some update or something?

rpgplayerrobin
Orc Shaman
Posts: 723
Joined: Wed Mar 18, 2009 3:03 am
x 401

Re: Shader from the Ocean Sample isn't animated

Post by rpgplayerrobin »

Make sure you are using this in the material:

Code: Select all

param_named_auto time_0_X time_0_x 100.0

And also, make sure that you actually have a variable in the vertex shader that is called "time_0_X".

Your shader and material might instead name it "time" though.

If you still have issues after you have checked this, post your material, shader material, and vertex+fragment shaders here.

Tom Duhamel
Gnoblar
Posts: 9
Joined: Fri Nov 15, 2019 2:07 pm
x 3

Re: Shader from the Ocean Sample isn't animated

Post by Tom Duhamel »

Thank you for your assistance.

it's literally the files from the samples, unmodified. Although I simplified the material by removing all the bits I don't need, but using the unmodified one doesn't make a difference.

Ocean.material

Code: Select all


vertex_program GLSL/Ocean2VS glsl
{
	source Ocean2GLSL.vert

}

fragment_program GLSL/Ocean2FS glsl
{
	source Ocean2GLSL.frag
}


material Ocean2_HLSL_GLSL
{
	technique GLSL
	{
		pass
		{
			vertex_program_ref GLSL/Ocean2VS
			{
				param_named_auto worldViewProj worldviewproj_matrix
				param_named_auto eyePosition camera_position_object_space
				param_named_auto time time_0_x 100.0
				param_named BumpScale float 0.2
				param_named textureScale float2 25 26
				param_named bumpSpeed float2 0.015 0.005
				param_named waveFreq float 0.028
				param_named waveAmp float 1.8
			}

		fragment_program_ref GLSL/Ocean2FS
		{
			param_named deepColor float4 0 0.3 0.5 1.0
			param_named shallowColor float4 0 1 1 1.0
			param_named reflectionColor float4 0.95 1 1 1.0
			param_named reflectionAmount float 1.0
			param_named reflectionBlur float 0.0
			param_named waterAmount float 0.3
			param_named fresnelPower float 5.0
			param_named fresnelBias float 0.328
			param_named hdrMultiplier float 0.471
			param_named NormalMap int 0
			param_named EnvironmentMap int 1
		}

		texture_unit
		{
			texture waves2.dds
			tex_coord_set 0
			filtering linear linear linear
		}

		texture_unit
		{
			cubic_texture morning.jpg combinedUVW
			tex_address_mode clamp
			tex_coord_set 1
			filtering linear linear linear
		}

	}

}

}

material SkyBox
{
	technique
	{
		pass
		{
			lighting off
			depth_write off
			depth_check off

		texture_unit
		{
			cubic_texture morning.jpg separateUV
			tex_address_mode clamp
		}
	}
}
}

material LightFlare
{
	technique
	{
		pass
		{
			lighting off
			scene_blend add
			depth_write off

		texture_unit
		{
			texture flare.png
		}
	}
}
}

Ocean2GLSL.vert

Code: Select all

/*********************************************************************NVMH3****
Copyright NVIDIA Corporation 2003
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.


Comments:
	Simple ocean shader with animated bump map and geometric waves
	Based partly on "Effective Water Simulation From Physical Models", GPU Gems

11 Aug 05: converted from HLSL to GLSL by Jeff Doyle (nfz) to work in Ogre

******************************************************************************/

uniform vec3 eyePosition;
uniform float BumpScale;
uniform vec2 textureScale;
uniform vec2 bumpSpeed;
uniform float time;
uniform float waveFreq;
uniform float waveAmp;
uniform mat4 worldViewProj;

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.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;
}

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

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;


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

Ocean2GLSL.frag

Code: Select all

/*********************************************************************NVMH3****
Copyright NVIDIA Corporation 2003
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.


Comments:
	Simple ocean shader with animated bump map and geometric waves
	Based partly on "Effective Water Simulation From Physical Models", GPU Gems

11 Aug 05: converted from HLSL to GLSL by Jeff Doyle (nfz) to work in Ogre

******************************************************************************/


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.z = -R.z;

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;
}
rpgplayerrobin
Orc Shaman
Posts: 723
Joined: Wed Mar 18, 2009 3:03 am
x 401

Re: Shader from the Ocean Sample isn't animated

Post by rpgplayerrobin »

It is hard to say why it does not work without debugging it.

If you have access to the source in your project with debugging information (which should be automatic if you built it from source) you can put a breakpoint in "FrameTimeControllerValue::frameStarted" (in OgrePredefinedControllers.cpp) and see if the timer is actually updated there.

Then, also put a breakpoint in "GpuProgramParameters::_updateAutoParams" (in OgreGpuProgramParams.cpp) at this code:

Code: Select all

case ACT_TIME_0_X:
	_writeRawConstant(i->physicalIndex, source->getTime_0_X(i->fData));
	break;

See that the getTime_0_X function actually gets the time correctly (and that it does not stay at 0 for example).

Tom Duhamel
Gnoblar
Posts: 9
Joined: Fri Nov 15, 2019 2:07 pm
x 3

Re: Shader from the Ocean Sample isn't animated

Post by Tom Duhamel »

Alright.

I'm using 1.9 because that's the version that comes precompiled in Fedora's repos. (Although I successfully built 14.3 from source on my other machine and plan to update to that soon, but that's not within the scope of this thread.) The ocean sample works, so obviously the issue isn't within Ogre itself.

Having never used that type of shader before (totally learning my way here) I was assuming I probably did something stupid and my question was more in relation to what I could have missed in my own project that would do that. For skeletal animations, for example, you need to call a function that advances the timer for these to be processed. There isn't anything similar that needs to be done for a shader program, does it?

Below is the prototype code I'm using to test this feature. This is assembled from a couple of other posts, so no judgement on the style please, I promise the final code will be rewritten properly :)

Code: Select all

    /* Water */
    Ogre::String strMeshName = "OceanSurface";

if ( !Ogre::MeshManager::getSingleton().resourceExists( strMeshName ) )
{
    Ogre::Plane oceanSurface;
    oceanSurface.normal = Ogre::Vector3::UNIT_Z;
    oceanSurface.d = 0;
    Ogre::MeshManager::getSingleton().createPlane( strMeshName,
                                                   Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
                                                   oceanSurface,
                                                   4000, 4000, 100, 100, true, 1, 1, 1, Ogre::Vector3::UNIT_Y);
}

 // Create the water plane mesh
Ogre::Entity* pOceanSurface = SceneMgr->
createEntity( strMeshName, strMeshName);
assert(pOceanSurface);

SceneMgr->getRootSceneNode()->createChildSceneNode()->
attachObject(pOceanSurface);

// Assign it a material
pOceanSurface->setMaterialName( "Ocean2_HLSL_GLSL" );

Is there more to it that I'm missing?

More:
As I was typing this post, I decided to test a few more things, and realised that the shader doesn't even show at all on the Nvidia card (tested on 2 different computers), only the iGPU (Intel UHD) on my laptop. There's something more obscure going on, but maybe this will give you a clue?

rpgplayerrobin
Orc Shaman
Posts: 723
Joined: Wed Mar 18, 2009 3:03 am
x 401

Re: Shader from the Ocean Sample isn't animated

Post by rpgplayerrobin »

For skeletal animations, for example, you need to call a function that advances the timer for these to be processed. There isn't anything similar that needs to be done for a shader program, does it?

The ocean sample works, so obviously the issue isn't within Ogre itself.

My previous post had to do exactly with this, to debug if the timer is automatically getting updated or not.
For my game in my version of Ogre (later than 1.9 that you are using) I can easily debug when the timer is updated, which is on root->renderOneFrame. But that might not happen automatically in Ogre 1.9, and the samplebrowser might do it for you, which is why debugging it in the sample browser and then in your own application would solve your issue.

As I was typing this post, I decided to test a few more things, and realised that the shader doesn't even show at all on the Nvidia card (tested on 2 different computers), only the iGPU (Intel UHD) on my laptop. There's something more obscure going on, but maybe this will give you a clue?

A lot more debug information would be needed to know why it does not work there, for example, the Ogre.log could help.