I created custom vertex shader (copy of the jME Lighting.vert, plus my modification) that is supposed to make wave effect on a water surface. It works. However, the wave movement is driven by a WaveTime parameter that I pass to the shader via material parameters. In the update-loop of my app I increase the WaveTime value of the material that uses the shader. I have two issues/questins.
I noticed that every time I increase the material parameter value using material.setFloat("WaveTime", timeAccumulated); the shader count displayed in the debug HUD increases:
I’m surprised to see that… is that normal? Why does it happen?
I have performance issues: the “frames per second” count drops significantly when using the shader. (I only use one mesh with this material). Might be related to the issue above (multiplying shaders)…?
It seems that sending the parameter value to GPU is the bottleneck: if I limit the material parameter update rate, then FPS gets higher. But I can’t adjust the update rate high enough for the effect too look nice without dropping FPS too badly.
What is the best way to drive vertex shader with a parameter? Is there a better way than material.setFloat()? I was thinking about some tricks for the shader itself to make it able to accumulate time instead of taking it from CPU… perhaps storing it in a texture or something. I’m not sure. I’d be grateful for any advise on the topic.
you have to specify the variable in the Defines list only if you actually use then in an #ifdef
so in your case, remove all but USE_WAVE.
The reason behind is that the shader has to be recompiled if a variable used as define is changed. Variables only declared in the material parameters can be updated without recompilation
This helped!
Shader count no longer rising. And no more FPS drop.
I’m including the fixed .j3md below - maybe it will help someone:
MaterialDef Phong Lighting {
MaterialParameters {
(...)
Boolean UseWave // <--- bunch of my parameters
Float WaveTime
Float WaveAmplitude
Float WaveLength
Int WaveSpeedEnum // enum: NONE = 0, SLOW = 1, NORMAL = 2, FAST = 3
}
(...)
Technique {
LightMode SinglePass
(...)
Defines {
(...)
USE_WAVE : UseWave // <--- only this here (will be used in #ifdef in shader)
}
}
Technique {
LightMode MultiPass
(...)
Defines {
(...)
USE_WAVE : UseWave // <---only this here (will be used in #ifdef in shader)
}
}
(...)
}
Indeed, the g_Time variable starts to work in the shader, after adding Time to the list of WorldParameters in the Technique descriptions in .j3md
Good to know.