Login
Username:

Password:

Remember me



Lost Password?

Register now!

Sections

Who's Online
83 user(s) are online (44 user(s) are browsing Forums)

Members: 0
Guests: 83

more...

Headlines

 
  Register To Post  

(1) 2 »
Need help with shader optimisation
Home away from home
Home away from home


See User information
@All

I do have some new stuff in progress, and have issue with one game, which do use some heavy shader enabling of which drop the FPS from 40 fps to just 10. Maybe anyone can spot issues with or bring ideas of how to optimise/reduce it so to make it not loose that much ?

Or at least to make it "half working" just without loosing so much FPS..

Shaders is "water" effect happens in the whole gameplay. Originally in fragment one "FogMode" was a bool, so i replace it on "int". There they are:

Vertex one:

uniform mat4    WorldViewProj;  // World * View * Projection transformation
uniform mat4    WorldReflectionViewProj;  // World * Reflection View * Projection transformation

uniform float    WaveLength;

uniform float    Time;
uniform float    WindForce;
uniform vec2    WindDirection;

// Vertex shader output structure
varying vec2 bumpMapTexCoord;
varying vec3 refractionMapTexCoord;
varying vec3 reflectionMapTexCoord;
varying vec3 position3D;

void main()
{
    
//color = gl_Color;

    // transform position to clip space
    
vec4 pos WorldViewProj gl_Vertex;
    
gl_Position pos;
    
    
// calculate vawe coords
    
bumpMapTexCoord gl_MultiTexCoord0.xy WaveLength Time WindForce WindDirection;

    
// refraction texcoords
    
refractionMapTexCoord.0.5 * (pos.pos.x);
    
refractionMapTexCoord.0.5 * (pos.pos.y);
    
refractionMapTexCoord.pos.w;
                                
    
// reflection texcoords
    
pos WorldReflectionViewProj gl_Vertex;
    
reflectionMapTexCoord.0.5 * (pos.pos.x);
    
reflectionMapTexCoord.0.5 * (pos.pos.y);
    
reflectionMapTexCoord.pos.w;
    
    
// position of the vertex
    
position3D gl_Vertex.xyz;
}


Fragment one:

const float LOG2 1.442695;

uniform vec3        CameraPosition;  // Position of main position
uniform float        WaveHeight;

uniform vec4        WaterColor;
uniform float        ColorBlendFactor;

uniform sampler2D    WaterBump//coverage
uniform sampler2D    RefractionMap//coverage
uniform sampler2D    ReflectionMap//coverage

uniform int        FogEnabled;
uniform int        FogMode;

varying vec2 bumpMapTexCoord;
varying vec3 refractionMapTexCoord;
varying vec3 reflectionMapTexCoord;
varying vec3 position3D;
    
void main()
{
    
//bump color
    
vec4 bumpColor texture2D(WaterBumpbumpMapTexCoord);
    
vec2 perturbation WaveHeight * (bumpColor.rg 0.5);
    
    
//refraction
    
vec2 ProjectedRefractionTexCoords clamp(refractionMapTexCoord.xy refractionMapTexCoord.perturbation0.01.0);
    
//calculate final refraction color
    
vec4 refractiveColor texture2D(RefractionMapProjectedRefractionTexCoords );
    
    
//reflection
    
vec2 ProjectedReflectionTexCoords clamp(reflectionMapTexCoord.xy reflectionMapTexCoord.perturbation0.01.0);
    
//calculate final reflection color
    
vec4 reflectiveColor texture2D(ReflectionMapProjectedReflectionTexCoords );

    
//fresnel
    
vec3 eyeVector normalize(CameraPosition position3D);
    
vec3 upVector vec3(0.01.00.0);
    
    
//fresnel can not be lower than 0
    
float fresnelTerm maxdot(eyeVectorupVector), 0.0 );
    
    
float fogFactor 1.0;
    
    if (
FogEnabled!=0)
    {
        
float z gl_FragCoord.gl_FragCoord.w;

        if (
FogMode == 1//exp
        
{
            
float fogFactor exp2(-gl_Fog.density LOG2);
            
fogFactor clamp(fogFactor0.01.0);
        }
        else if (
FogMode == 0//linear
        
{
            
fogFactor = (gl_Fog.end z) / (gl_Fog.end gl_Fog.start);
        }
        else if (
FogMode == 2//exp2
        
{
            
float fogFactor exp2(-gl_Fog.density gl_Fog.density LOG2);
            
fogFactor clamp(fogFactor0.01.0);
        }
    }
    
    
vec4 combinedColor refractiveColor fresnelTerm reflectiveColor * (1.0 fresnelTerm);
    
    
vec4 finalColor ColorBlendFactor WaterColor + (1.0 ColorBlendFactor) * combinedColor;
    
    
gl_FragColor mix(gl_Fog.colorfinalColorfogFactor );
}


There how shader loads-up:

RealisticWaterSceneNode::RealisticWaterSceneNode(scene::ISceneManagersceneManagerf32 widthf32 height,
                                                 const 
irr::core::stringcresourcePathcore::dimension2du renderTargetSize,
                                                 
scene::ISceneNodeparents32 id):
    
scene::ISceneNode(parentsceneManagerid), _time(0),
    
_size(widthheight), _sceneManager(sceneManager), _refractionMap(NULL), _reflectionMap(NULL),
    
_windForce(20.0f),_windDirection(01),_waveHeight(0.3f), _waterColor(0.1f0.1f0.6f1.0f), _colorBlendFactor(0.2f), _camera(NULL)
{
    
_videoDriver sceneManager->getVideoDriver();

    
// create new camera
    
_camera sceneManager->addCameraSceneNode(0core::vector3df(000), core::vector3df(000), -1false);

    
_waterMesh sceneManager->addHillPlaneMesh("RealisticWater"_sizecore::dimension2d<u32>(11));

    
_waterSceneNode sceneManager->addMeshSceneNode(_waterMesh->getMesh(0), this);

    
video::IGPUProgrammingServicesGPUProgrammingServices _videoDriver->getGPUProgrammingServices();

    
core::stringc waterPixelShader;
    
core::stringc waterVertexShader;

    if (
_videoDriver->getDriverType() == video::EDT_DIRECT3D9)
    {
        
waterPixelShader resourcePath "/shaders/Water_ps.hlsl";
        
waterVertexShader resourcePath "/shaders/Water_vs.hlsl";
    }
    else if (
_videoDriver->getDriverType() == video::EDT_OPENGL)
    {
        
waterPixelShader resourcePath "/shaders/Water_ps.glsl";
        
waterVertexShader resourcePath "/shaders/Water_vs.glsl";
    }

    
_shaderMaterial GPUProgrammingServices->addHighLevelShaderMaterialFromFiles(
        
waterVertexShader.c_str(), "main"video::EVST_VS_1_1,
        
waterPixelShader.c_str(), "main"video::EPST_PS_1_1,
        
this);

    
_waterSceneNode->setMaterialType((video::E_MATERIAL_TYPE)_shaderMaterial);

    
irr::video::ITexturebumpTexture _videoDriver->getTexture(resourcePath "/data/waterbump.png");
    
_waterSceneNode->setMaterialTexture(0bumpTexture);

    
_refractionMap _videoDriver->addRenderTargetTexture(renderTargetSize);
    
_reflectionMap _videoDriver->addRenderTargetTexture(renderTargetSize);

    
_waterSceneNode->setMaterialTexture(1_refractionMap);
    
_waterSceneNode->setMaterialTexture(2_reflectionMap);
}

RealisticWaterSceneNode::~RealisticWaterSceneNode()
{
    if (
_camera)
    {
        
_camera->drop();
        
_camera NULL;
    }

    if (
_refractionMap)
    {
        
_refractionMap->drop();
        
_refractionMap NULL;
    }

    if (
_reflectionMap)
    {
        
_reflectionMap->drop();
        
_reflectionMap NULL;
    }

    if (
_waterSceneNode)
    {
        
_waterSceneNode->drop();
        
_waterSceneNode NULL;
    }

    if (
_waterMesh)
    {
        
_waterMesh->drop();
        
_waterMesh NULL;
    }
}

// frame
void RealisticWaterSceneNode::OnRegisterSceneNode()
{
    
ISceneNode::OnRegisterSceneNode();

    if (
IsVisible)
    {
        
_sceneManager->registerNodeForRendering(this);
    }
}

void RealisticWaterSceneNode::OnAnimate(u32 timeMs)
{
    
ISceneNode::OnAnimate(timeMs);

    
_time timeMs;

    
//fixes glitches with incomplete refraction
    
const f32 CLIP_PLANE_OFFSET_Y 5.0f// 5.0f;

    
if (IsVisible)
    {
        
setVisible(false); //hide the water

        //refraction
        
_videoDriver->setRenderTarget(_refractionMaptruetrue); //render to refraction

        //refraction clipping plane
        
core::plane3d<f32refractionClipPlane(0RelativeTranslation.CLIP_PLANE_OFFSET_Y00, -10); //refraction clip plane
        
_videoDriver->setClipPlane(0refractionClipPlanetrue);

        
_sceneManager->drawAll(); //draw the scene

        //reflection
        
_videoDriver->setRenderTarget(_reflectionMaptruetrue); //render to reflection

        //get current camera
        
scene::ICameraSceneNodecurrentCamera _sceneManager->getActiveCamera();

        
//set FOV anf far value from current camera
        // _camera->setFarValue(currentCamera->getFarValue());
        // _camera->setFOV(currentCamera->getFOV());
        
        
_camera->setNearValue(500.0f);
        
_camera->setFarValue(15000.0f);     /// Must be bigger than water
        
_camera->setFOV(10*core::DEGTORAD); /// Playing with FOV and Z distance

        
core::vector3df position currentCamera->getAbsolutePosition();
        
position.= -position.RelativeTranslation.Y//position of the water
        
_camera->setPosition(position);

        
core::vector3df target currentCamera->getTarget();

        
//invert Y position of current camera
        
target.= -target.RelativeTranslation.Y;
        
_camera->setTarget(target);

        
//set the reflection camera
        
_sceneManager->setActiveCamera(_camera);

        
//reflection clipping plane
        
core::plane3d<f32reflectionClipPlane(0RelativeTranslation.CLIP_PLANE_OFFSET_Y0010);
        
_videoDriver->setClipPlane(0reflectionClipPlanetrue);

        
_sceneManager->drawAll(); //draw the scene

        //disable clip plane
        
_videoDriver->enableClipPlane(0false);

        
//set back old render target
        
_videoDriver->setRenderTarget(0falsetrue);

        
//set back the active camera
        
_sceneManager->setActiveCamera(currentCamera);

        
setVisible(true); //show it again
    
}
}

void RealisticWaterSceneNode::render()
{
    
/*core::array<video::IRenderTarget> renderTargets;
    //renderTargets.push_back();
    renderTargets.push_back(_refractionMap);

    _videoDriver->setRenderTarget(renderTargets, true, true);*/
    //_videoDriver->draw2DImage(_reflectionMap,core::position2d<s32>(0,0));
}

// returns the axis aligned bounding box of terrain
const core::aabbox3d<f32>& RealisticWaterSceneNode::getBoundingBox() const
{
    return 
_waterSceneNode->getBoundingBox();
}

void RealisticWaterSceneNode::OnSetConstants(video::IMaterialRendererServicesservicess32 userData)
{
    
video::IVideoDriverdriver services->getVideoDriver();

    
core::matrix4 projection driver->getTransform(video::ETS_PROJECTION);
    
core::matrix4 view driver->getTransform(video::ETS_VIEW);
    
core::matrix4 world driver->getTransform(video::ETS_WORLD);

    
core::matrix4 cameraView _camera->getViewMatrix();

    
// vertex shader constants
    // services->setVertexShaderConstant("View", view.pointer(), 16);

    
core::matrix4 worldViewProj projection;
    
worldViewProj *= view;
    
worldViewProj *= world;

    
core::matrix4 worldReflectionViewProj projection;
    
worldReflectionViewProj *= cameraView;
    
worldReflectionViewProj *= world;

    
f32 waveLength 0.1f;
    
f32 time _time 100000.0f;
    
core::vector3df cameraPosition _sceneManager->getActiveCamera()->getPosition();

    
bool fogEnabled getMaterial(0).getFlag(video::EMF_FOG_ENABLE);
    
irr::video::SColor color;
    
irr::video::E_FOG_TYPE fogType;
    
f32 start;
    
f32 end;
    
f32 density;
    
bool pixelFog;
    
bool rangeFog;
    
driver->getFog(colorfogTypestartenddensitypixelFograngeFog);

#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR == 9)
    
services->setVertexShaderConstant(services->getVertexShaderConstantID("WorldViewProj"), worldViewProj.pointer(), 16);
    
services->setVertexShaderConstant(services->getVertexShaderConstantID("WorldReflectionViewProj"), worldReflectionViewProj.pointer(), 16);
    
services->setVertexShaderConstant(services->getVertexShaderConstantID("WaveLength"), &waveLength1);
    
services->setVertexShaderConstant(services->getVertexShaderConstantID("Time"), &time1);
    
services->setVertexShaderConstant(services->getVertexShaderConstantID("WindForce"), &_windForce1);
    
services->setVertexShaderConstant(services->getVertexShaderConstantID("WindDirection"), &_windDirection.X2);
    
services->setPixelShaderConstant(services->getVertexShaderConstantID("CameraPosition"), &cameraPosition.X3);
    
services->setPixelShaderConstant(services->getVertexShaderConstantID("WaveHeight"), &_waveHeight1);
    
services->setPixelShaderConstant(services->getVertexShaderConstantID("WaterColor"), &_waterColor.r4);
    
services->setPixelShaderConstant(services->getVertexShaderConstantID("ColorBlendFactor"), &_colorBlendFactor1);
#else
    
services->setVertexShaderConstant("WorldViewProj"worldViewProj.pointer(), 16);
    
services->setVertexShaderConstant("WorldReflectionViewProj"worldReflectionViewProj.pointer(), 16);
    
services->setVertexShaderConstant("WaveLength", &waveLength1);
    
services->setVertexShaderConstant("Time", &time1);
    
services->setVertexShaderConstant("WindForce", &_windForce1);
    
services->setVertexShaderConstant("WindDirection", &_windDirection.X2);
    
services->setPixelShaderConstant("CameraPosition", &cameraPosition.X3);
    
services->setPixelShaderConstant("WaveHeight", &_waveHeight1);
    
services->setPixelShaderConstant("WaterColor", &_waterColor.r4);
    
services->setPixelShaderConstant("ColorBlendFactor", &_colorBlendFactor1);
#endif

    //texture constants for GLSL
    
if (driver->getDriverType() == video::EDT_OPENGL)
    {
        
int var0 0;
        
int var1 1;
        
int var2 2;

#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR == 9)
        
services->setPixelShaderConstant(services->getVertexShaderConstantID("WaterBump"), &var01);
        
services->setPixelShaderConstant(services->getVertexShaderConstantID("RefractionMap"), &var11);
        
services->setPixelShaderConstant(services->getVertexShaderConstantID("ReflectionMap"), &var21);

        
services->setPixelShaderConstant(services->getVertexShaderConstantID("FogEnabled"), (int*)&fogEnabled1);
        
services->setPixelShaderConstant(services->getVertexShaderConstantID("FogMode"), (int*)&fogType1);
#else
        
services->setPixelShaderConstant("WaterBump", &var01);
        
services->setPixelShaderConstant("RefractionMap", &var11);
        
services->setPixelShaderConstant("ReflectionMap", &var21);

        
services->setPixelShaderConstant("FogEnabled", (int*)&fogEnabled1);
        
services->setPixelShaderConstant("FogMode", (int*)&fogType1);
#endif
    
}
}

void RealisticWaterSceneNode::setWindForce(const f32 windForce)
{
    
_windForce windForce;
}

void RealisticWaterSceneNode::setWindDirection(const core::vector2dfwindDirection)
{
    
_windDirection windDirection;
    
_windDirection.normalize();
}

void RealisticWaterSceneNode::setWaveHeight(const f32 waveHeight)
{
    
_waveHeight waveHeight;
}

void RealisticWaterSceneNode::setWaterColor(const video::SColorfwaterColor)
{
    
_waterColor waterColor;
}

void RealisticWaterSceneNode::setColorBlendFactor(const f32 colorBlendFactor)
{
    
_colorBlendFactor colorBlendFactor;
}



And there how it used in the game itself:

/// NODE -> WATER: (Sea)
    /// TO-DO: THIS ONE CAUSES MEMORY LEACKS ON RELOAD !!!!!!! ...
    
if(!waterNode){
    
waterNode = new RealisticWaterSceneNode(smgr1000010000"water"irr::core::dimension2du(512512), nodeLevel, -1);
    
/// waterNode->setParent(nodeLevel); /// Attach to parent: Level
    
waterNode->setPosition(vector3df(2500,0,0));
    
waterNode->setRotation(vector3df(0,0,0));
    
waterNode->setWindForce(10.0f);
    
waterNode->setWindDirection(irr::core::vector2df(5.f, -5.f));
    
waterNode->setWaveHeight(0.3f);
    
waterNode->setWaterColor(video::SColor(0,50,50,50)); /// Black
    
waterNode->setColorBlendFactor(0.15);

    
/// Materials:
    
waterNode->setMaterialFlag(video::EMF_LIGHTINGtrue);          // Node is affected by LIGHT?
    
waterNode->setMaterialFlag(video::EMF_FOG_ENABLEtrue);        /// Node is affected by FOG? - (Its the only node with the fog enabled)
    
waterNode->setMaterialFlag(video::EMF_BACK_FACE_CULLINGtrue); // Render both sides !!! Affects water reflex !!!
    
waterNode->setMaterialFlag(video::EMF_NORMALIZE_NORMALStrue);
    
/// waterNode->setMaterialFlag(video::EMF_ANISOTROPIC_FILTER, true); // Increase view distance quality (similar to sharpness)
    
waterNode->setMaterialType(video::EMT_SOLID);
    };



Any ideas/help very welcome , thanks !

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Need help with shader optimisation
Just can't stay away
Just can't stay away


See User information
@kas1e

Some random notes regarding fragment shader:

1) use the cheapest fogmode, then remove branches and fog mode comparision.

2) upvector does't depend on inputs, it could be defined as const vec3 outside the function.

3) there is one confusing thing, this fogFactor which gets redefined inside branches. Should "float" part (redeclaration) be removed?

Regarding C++:

1) is there a way to reduce details (vertices) somehow? For example, when water node is created by new.

Go to top
Re: Need help with shader optimisation
Home away from home
Home away from home


See User information
@Capehill
Quote:

1) use the cheapest fogmode, then remove branches and fog mode comparision.


Something like this ?:

if (FogEnabled!=0)
    {
        
float z gl_FragCoord.gl_FragCoord.w;

        
fogFactor = (gl_Fog.end z) / (gl_Fog.end gl_Fog.start); // Linear
    
}



Quote:

2) upvector does't depend on inputs, it could be defined as const vec3 outside the function.


Interesting, how much speed drop shaders usually have, when inside of main we do vec3 something , which can be done outside ? I will test of course, just intersting theoriticaly it is micro optimisation, or something like "do as much as possible outside of main()"


Quote:

3) there is one confusing thing, this fogFactor which gets redefined inside branches. Should "float" part (redeclaration) be removed?


I think if i will go linear fogmode, and use it as i show at top, those floats gone too.

Quote:

1) is there a way to reduce details (vertices) somehow? For example, when water node is created by new.


Can't say for now, but only know that this "realistic water effect" is from this github :

https://github.com/elnormous/RealisticWaterSceneNode


And there is discussion about:

https://irrlicht.sourceforge.io/forum/viewtopic.php?t=23453

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Need help with shader optimisation
Just can't stay away
Just can't stay away


See User information
@kas1e

Fragment shader:

These might be rewritten using mix:

vec4 combinedColor = refractiveColor * fresnelTerm + reflectiveColor * (1.0 - fresnelTerm);

vec4 finalColor = ColorBlendFactor * WaterColor + (1.0 - ColorBlendFactor) * combinedColor;

=>

vec4 combinedColor = mix(reflectiveColor, refractiveColor, fresnelTerm);

vec4 finalColor = mix(combinedColor, WaterColor, ColorBlendFactor);


Reference: https://www.khronos.org/opengl/wiki/GLSL_Optimizations (Linear interpolation)

Go to top
Re: Need help with shader optimisation
Home away from home
Home away from home


See User information
@Capehill
Thanks! So for now that what i do is removed fog and apply the stuff you point out:

uniform vec3        CameraPosition;  // Position of main position
uniform float        WaveHeight;

uniform vec4        WaterColor;
uniform float        ColorBlendFactor;

uniform sampler2D    WaterBump//coverage
uniform sampler2D    RefractionMap//coverage
uniform sampler2D    ReflectionMap//coverage

varying vec2 bumpMapTexCoord;
varying vec3 refractionMapTexCoord;
varying vec3 reflectionMapTexCoord;
varying vec3 position3D;


const 
vec3 upVector vec3(0.01.00.0);

void main()
{
    
//bump color
    
vec4 bumpColor texture2D(WaterBumpbumpMapTexCoord);
    
vec2 perturbation WaveHeight * (bumpColor.rg 0.5);
    
    
//refraction
    
vec2 ProjectedRefractionTexCoords clamp(refractionMapTexCoord.xy refractionMapTexCoord.perturbation0.01.0);
    
//calculate final refraction color
    
vec4 refractiveColor texture2D(RefractionMapProjectedRefractionTexCoords );
    
    
//reflection
    
vec2 ProjectedReflectionTexCoords clamp(reflectionMapTexCoord.xy reflectionMapTexCoord.perturbation0.01.0);
    
//calculate final reflection color
    
vec4 reflectiveColor texture2D(ReflectionMapProjectedReflectionTexCoords );

    
//fresnel
    
vec3 eyeVector normalize(CameraPosition position3D);
    
    
//fresnel can not be lower than 0
    
float fresnelTerm maxdot(eyeVectorupVector), 0.0 );
            
    
vec4 combinedColor mix(reflectiveColorrefractiveColorfresnelTerm);

    
vec4 finalColor mix(combinedColorWaterColorColorBlendFactor);
    
    
gl_FragColor finalColor;
}


Sadly i can't test for a few days on amigaos, but i do test win32 version that it still works.

Through can't see there if it improve anything, FPS the same more or less on win32, and not depends on the shader (while on amigaos4 it very depends, with shader 12 fps in game, without 42).

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Need help with shader optimisation
Home away from home
Home away from home


See User information
@Capehill
Do you know any good article about general shaders optimisation ? I mean some basic rules like "you should't do this and this as it made shader be slow", or "never do that and that, or shader will be slow" ?

All i know for now, is little bits from there and there. I know that for example our opengles2 have glslangvalidator being disabled in terms of shader optimisation, because, it cause issues with Nova. What mean that we need to optimize all our shaders ourselfs.

I do find firstly some offline shader optimizator which for now inbuild inside of Unity, but till 2016 it was standalone: https://github.com/aras-p/glsl-optimizer

See there blog post about with numbers and stuff: https://aras-p.info/blog/2010/09/29/glsl-optimizer/

So i may try to pass this shader over it, maybe it will optimize a little bit more..

Another idea maybe just use glslanvalidator and pass shader through it with optimisation enabled

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Need help with shader optimisation
Home away from home
Home away from home


See User information
@Capehill
I build glsl-optimizer from link above, and take a look what kind of shader is made for me after i throw in it original fragment shader, there is optimized output:

uniform vec3 CameraPosition;
uniform float WaveHeight;
uniform vec4 WaterColor;
uniform float ColorBlendFactor;
uniform sampler2D WaterBump;
uniform sampler2D RefractionMap;
uniform sampler2D ReflectionMap;
uniform int FogEnabled;
uniform int FogMode;
varying vec2 bumpMapTexCoord;
varying vec3 refractionMapTexCoord;
varying vec3 reflectionMapTexCoord;
varying vec3 position3D;
void main ()
{
  
float fogFactor_1;
  
vec2 tmpvar_2;
  
tmpvar_2 = (WaveHeight * (texture2D (WaterBumpbumpMapTexCoord).xy 0.5));
  
vec4 tmpvar_3;
  
tmpvar_3 texture2D (RefractionMapclamp (((refractionMapTexCoord.xy refractionMapTexCoord.z) + tmpvar_2), 0.01.0));
  
vec4 tmpvar_4;
  
tmpvar_4 texture2D (ReflectionMapclamp (((reflectionMapTexCoord.xy reflectionMapTexCoord.z) + tmpvar_2), 0.01.0));
  
float tmpvar_5;
  
tmpvar_5 max (normalize((CameraPosition position3D)).y0.0);
  
fogFactor_1 1.0;
  if ((
FogEnabled != 0)) {
    
float tmpvar_6;
    
tmpvar_6 = (gl_FragCoord.gl_FragCoord.w);
    if (((
FogMode != 1) && (FogMode == 0))) {
      
fogFactor_1 = ((gl_Fog.end tmpvar_6) / (gl_Fog.end gl_Fog.start));
    };
  };
  
gl_FragColor mix (gl_Fog.color, ((ColorBlendFactor WaterColor) + (
    (
1.0 ColorBlendFactor)
   * 
    ((
tmpvar_3 tmpvar_5) + (tmpvar_4 * (1.0 tmpvar_5)))
  )), 
fogFactor_1);
}


Quite "optimized" :) There and "mix" and things combined and more compacted, and instead few calls all put in one call, etc,etc. I tested on windows version, and it still works as original. Will check after few days how it will be on amigaos .. But probabaly that for real "optimized" enough version optimizator did.

Also the fact that this thing inbuild in Unity kind of tell that it should be indeed good enough.


EDIT: After thinking a bit more about, i think on Windows10 i will see no differences at all with any kind of shader optimisation, because it's sure some kind of good enough GLSL optimizator inbuild inside of windows drivers already, so when i run game with non-optimized shader, it still produce for me optimized by windows drivers shader.

So this need to be tested only on amigaos4, because only there it will make sense, as we do not have inbuild shaders optimization.

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Need help with shader optimisation
Just can't stay away
Just can't stay away


See User information
@kas1e

I only know that Khronos' page that I linked. Shader looks simple, no loops, no branches. If all those calculations must be done on the fragment level and cannot be moved to the vertex shader, then I cannot say what could be optimized. Have you tried lowest float precision?

Shader does however 3 texture lookups and there are FBOs involved so it can be tricky to diagnose exactly what takes time. If I understand correctly, engine must render scene to a texture which is then sampled by the shader so that reflections can be rendered on the water.

Quote:

glslangvalidator being disabled in terms of shader optimisation, because, it cause issues with Nova


Really? Is there some ticket?

Go to top
Re: Need help with shader optimisation
Home away from home
Home away from home


See User information
@Capehill
Quote:

Really? Is there some ticket?


No, no tickets, it just we year ago with Daniel tested his ogles2.library with glslangvalidator enabled optimisation level 1, level2 and level3 (mean not usuall -Ox gcc optimisation, but inbuild shaders-generated code optimization): in all levels we have more issues with Nova in compare with no optimisation at all. All tests i did were on bunch of shadertoy shaders.

But i think it's not bug per se. I.e. O2 (or O3) optimisation of course enabled when all this builded, what i mean shaders optimizator code . And for us it probably good to have it disabled, as we can made shaders as we want them to be and not rely on internal shaders optimizators.

In end of all, ff there were before shader optimizator code enabled in ogles, why we then need to thinkg about shader fixes at all, as everything will be done inside of this optimisator :)


Edited by kas1e on 2022/9/9 19:07:40
Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Need help with shader optimisation
Home away from home
Home away from home


See User information
@Capehill
Ported that glsl-optimizer from Unity on amigaos4 natively :) one more tool :)

Btw, see what written in that glsl-optimizer readme:

Quote:

A C++ library that takes GLSL shaders, does some GPU-independent optimizations on them and outputs GLSL or Metal source back. Optimizations are function inlining, dead code removal, copy propagation, constant folding, constant propagation, arithmetic optimizations and so on.

Apparently quite a few mobile platforms are pretty bad at optimizing shaders; and unfortunately they also lack offline shader compilers. So using a GLSL optimizer offline before can make the shader run much faster on a platform like that. See performance numbers in this blog post.

Even for drivers that have decent shader optimization, GLSL optimizer could be useful to just strip away dead code, make shaders smaller and do uniform/input reflection offline.

Almost all actual code is Mesa 3D's GLSL compiler; all this library does is spits out optimized GLSL or Metal back, and adds GLES type precision handling to the optimizer.

This GLSL optimizer is made for Unity's purposes and is built-in starting with Unity 3.0.


Sounds good

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Need help with shader optimisation
Home away from home
Home away from home


See User information
@Capehill
Tried with optimized shader now :

uniform vec3 CameraPosition;
uniform float WaveHeight;
uniform vec4 WaterColor;
uniform float ColorBlendFactor;
uniform sampler2D WaterBump;
uniform sampler2D RefractionMap;
uniform sampler2D ReflectionMap;
uniform int FogEnabled;
uniform int FogMode;
varying vec2 bumpMapTexCoord;
varying vec3 refractionMapTexCoord;
varying vec3 reflectionMapTexCoord;
varying vec3 position3D;
void main ()
{
  
float fogFactor_1;
  
vec2 tmpvar_2;
  
tmpvar_2 = (WaveHeight * (texture2D (WaterBumpbumpMapTexCoord).xy 0.5));
  
vec4 tmpvar_3;
  
tmpvar_3 texture2D (RefractionMapclamp (((refractionMapTexCoord.xy refractionMapTexCoord.z) + tmpvar_2), 0.01.0));
  
vec4 tmpvar_4;
  
tmpvar_4 texture2D (ReflectionMapclamp (((reflectionMapTexCoord.xy reflectionMapTexCoord.z) + tmpvar_2), 0.01.0));
  
float tmpvar_5;
  
tmpvar_5 max (normalize((CameraPosition position3D)).y0.0);
  
fogFactor_1 1.0;
  if ((
FogEnabled != 0)) {
    
float tmpvar_6;
    
tmpvar_6 = (gl_FragCoord.gl_FragCoord.w);
    if (((
FogMode != 1) && (FogMode == 0))) {
      
fogFactor_1 = ((gl_Fog.end tmpvar_6) / (gl_Fog.end gl_Fog.start));
    };
  };
  
gl_FragColor mix (gl_Fog.color, ((ColorBlendFactor WaterColor) + (
    (
1.0 ColorBlendFactor)
   * 
    ((
tmpvar_3 tmpvar_5) + (tmpvar_4 * (1.0 tmpvar_5)))
  )), 
fogFactor_1);
}



Sadly, it add no single FPS. Very strange. But with disabled shader in whole, it add +30 FPS.. Then i tried to remove from optimizer shader fog completely, like this:

uniform vec3 CameraPosition;
uniform float WaveHeight;
uniform vec4 WaterColor;
uniform float ColorBlendFactor;
uniform sampler2D WaterBump;
uniform sampler2D RefractionMap;
uniform sampler2D ReflectionMap;
varying vec2 bumpMapTexCoord;
varying vec3 refractionMapTexCoord;
varying vec3 reflectionMapTexCoord;
varying vec3 position3D;
void main ()
{
  
vec2 tmpvar_1;
  
tmpvar_1 = (WaveHeight * (texture2D (WaterBumpbumpMapTexCoord).xy 0.5));
  
gl_FragColor mix (mix (texture2D (ReflectionMapclamp (
    ((
reflectionMapTexCoord.xy reflectionMapTexCoord.z) + tmpvar_1)
  , 
0.01.0)), texture2D (RefractionMapclamp (
    ((
refractionMapTexCoord.xy refractionMapTexCoord.z) + tmpvar_1)
  , 
0.01.0)), max (
    
normalize((CameraPosition position3D))
  .
y0.0)), WaterColorColorBlendFactor);
}


Still the same 14 fps. Once shader disabled, then 45 FPS. Wtf ..

Through, we use GL4ES there, so it auto conver those shaders a bit too, but usually it not add/change much , but just in case, i dump that shader after gl4es conversion happens (so what we exactly send to olges2), and that what we have with that optimized shader with disabled fog:

#version 100
precision highp float;
precision highp int;
float clamp(float fint aint b) {
 return 
clamp(ffloat(a), float(b));
}
float clamp(float ffloat aint b) {
 return 
clamp(fafloat(b));
}
float clamp(float fint afloat b) {
 return 
clamp(ffloat(a), b);
}
vec2 clamp(vec2 fint aint b) {
 return 
clamp(ffloat(a), float(b));
}
vec2 clamp(vec2 ffloat aint b) {
 return 
clamp(fafloat(b));
}
vec2 clamp(vec2 fint afloat b) {
 return 
clamp(ffloat(a), b);
}
vec3 clamp(vec3 fint aint b) {
 return 
clamp(ffloat(a), float(b));
}
vec3 clamp(vec3 ffloat aint b) {
 return 
clamp(fafloat(b));
}
vec3 clamp(vec3 fint afloat b) {
 return 
clamp(ffloat(a), b);
}
vec4 clamp(vec4 fint aint b) {
 return 
clamp(ffloat(a), float(b));
}
vec4 clamp(vec4 ffloat aint b) {
 return 
clamp(fafloat(b));
}
vec4 clamp(vec4 fint afloat b) {
 return 
clamp(ffloat(a), b);
}
float max(float aint b) {
 return 
max(afloat(b));
}
float max(int afloat b) {
 return 
max(float(a), b);
}
uniform vec3 CameraPosition;
uniform float WaveHeight;
uniform vec4 WaterColor;
uniform float ColorBlendFactor;
uniform sampler2D WaterBump;
uniform sampler2D RefractionMap;
uniform sampler2D ReflectionMap;
varying vec2 bumpMapTexCoord;
varying vec3 refractionMapTexCoord;
varying vec3 reflectionMapTexCoord;
varying vec3 position3D;
void main ()
{
  
vec2 tmpvar_1;
  
tmpvar_1 = (WaveHeight * (texture2D (WaterBumpbumpMapTexCoord).xy 0.500000));
  
gl_FragColor mix (mix (texture2D (ReflectionMapclamp (
    ((
reflectionMapTexCoord.xy reflectionMapTexCoord.z) + tmpvar_1)
  , 
0.000001.00000)), texture2D (RefractionMapclamp (
    ((
refractionMapTexCoord.xy refractionMapTexCoord.z) + tmpvar_1)
  , 
0.000001.00000)), max (
    
normalize((CameraPosition position3D))
  .
y0.00000)), WaterColorColorBlendFactor);
}


Didn't looks bad enough , just about the same, only with some external functions added on top. But that can't explain "Eating" of 30 FPS, right ?


Edited by kas1e on 2022/9/18 8:17:37
Edited by kas1e on 2022/9/18 8:23:06
Edited by kas1e on 2022/9/18 8:24:44
Edited by kas1e on 2022/9/18 8:29:38
Edited by kas1e on 2022/9/18 8:30:52
Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Need help with shader optimisation
Just can't stay away
Just can't stay away


See User information
@kas1e

https://github.com/elnormous/Realistic ... master/RealisticWater.cpp

It would be interesting to know what happens if you comment out refraction (133-140) or reflection (142-169) parts.

Go to top
Re: Need help with shader optimisation
Home away from home
Home away from home


See User information
@Capehill
Commenting out just refraction part: + 8-9 fps (so instead of 14, i have 22-23). Everything looks seems like the same a little bit mirrring of the things in the water start to be alittle bit less quality, and that all. Almost same effect..

Then, commenting out just reflection part and keeping refraction , make whole effect disappear , but then, not add a lot : it just add +6 fps, so whole fps start to be just 20.

If i comment out both, then i do have just 22 fps again and nothing else. So, the best i get is to comment out refration part and have 22-23 fps. Through, when i comment out whole usage of shader, i do have 45 fps.

Question is where is another 20 fps died in the shader.. 10 we loose on refraction then (strange why as well?)

See how it looks like originally:

(click open in new tab for fullsize)
Resized Image

So that place just 14 fps.

And that how it looks like when just refration (133-140) lines commented out :

(click open in new tab for fullsize)
Resized Image

So there i have 22-23 fps, but to have it be playable we should have at least stable 30 or better 60 ..

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Need help with shader optimisation
Home away from home
Home away from home


See User information
@Capehill & @kas1e

Looks like the fps drop is the result of rendering the entire scene an additional two times. Once to generate the refraction map, and once to generate the reflection map.

Hans

http://hdrlab.org.nz/ - Amiga OS 4 projects, programming articles and more.
https://keasigmadelta.com/ - more of my work
Go to top
Re: Need help with shader optimisation
Home away from home
Home away from home


See User information
@Hans
Simple removing one "_sceneManager->drawAll(); //draw the scene" call right after refraction calcualtion happens of course add FPS, but then, this refration take no place then too probabaly..

Anyway, simple commenting out everything inside of the "OnAnimate" function, gives me 40 FPS back in game, but of course, no water effect. From where slownes come dunno .. Even 40 FPS not enough even with shader, game is simple, just good looking, but written pretty bad..

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Need help with shader optimisation
Home away from home
Home away from home


See User information
@kas1e
Quote:
Anyway, simple commenting out everything inside of the "OnAnimate" function, gives me 40 FPS back in game, but of course, no water effect. From where slownes come dunno .. Even 40 FPS not enough even with shader, game is simple, just good looking, but written pretty bad..

Some profiling would be needed to dig deeper. I still suspect that GL4ES is doing something that hurts performance on our systems.

Hans

http://hdrlab.org.nz/ - Amiga OS 4 projects, programming articles and more.
https://keasigmadelta.com/ - more of my work
Go to top
Re: Need help with shader optimisation
Home away from home
Home away from home


See User information
@Hans
We already did lot of profiling of all stuf many times as you remember, and it never point us on anything, but only on fact that gl calls happens.

So we need to go other route.

What about writing analogue of "slow for us" quake3map irrlicht test, workingdirectly over nova and/or ogles2, so we can see if it will give us 500 fps at least, or will be on the same level as it now with gl4es ?

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Need help with shader optimisation
Home away from home
Home away from home


See User information
@kas1e
The profiling that I've done is with the manually coded driver profiling code (in special driver builds), which provides limited information. That's what gave me the impression that GL4ES and/or some games are glFlush()ing too often.

I haven't used a statistical profiler (not available at the time), or gprof (which still doesn't work?) to dig deeper.

Quote:
What about writing analogue of "slow for us" quake3map irrlicht test, workingdirectly over nova and/or ogles2, so we can see if it will give us 500 fps at least, or will be on the same level as it now with gl4es ?

That could help, if someone takes the time to write the code. It'll give us some idea of whether GL4ES is indeed the main culprit.

Hans

http://hdrlab.org.nz/ - Amiga OS 4 projects, programming articles and more.
https://keasigmadelta.com/ - more of my work
Go to top
Re: Need help with shader optimisation
Home away from home
Home away from home


See User information
@Hans
Quote:

That could help, if someone takes the time to write the code. It'll give us some idea of whether GL4ES is indeed the main culprit.


Well.. in that case we on dead end. It's imho driver's author only can find what wrong :) Because anyone else who will wrote that test code, will made it bad/slow/wrong/or whatever which will show us nothing.

We were in hope that firstly DMA, then GART will help us out : but nope, nothing help, we in the same situation with speed in some cases, while, as i point out, pure CPU rendering is OK and comparable more or less sane with other x86 hardware ..

The only solution, is that driver's author will just wrote necessary test cases : for nova, for opengles2 , which we can test in all conditions, on different platforms, on win32, on linux, on amigaos4. Only then we can find what is cullpit.

We do have your SDL2+OGL book with examples which i made to work on os4 as well, so why we can't get for example this as a base and made some tests and run them on different win32 and different amigaos4 machines (under os4 and linux) ? That will not enough to show us anything ?

I mean, issue to find mean not just me or someone wrote another buggy test case, but it's need your time and full attention to this issue sadly :) Test cases, benchmarks and again test cases and test cases..

Isn't gfxbench already said us about bad raw speed for read/write and not reach the necessary theiretical limits ? Is it of the values we expect it to be ?

As for GL4ES itself : well, we do have some games which isn't GL4ES based for example, but directly use OGLES2 : for example Eldritch. It also slow when it comes to more heavy scenes. By slow i mean the same 15-20 FPS and slownes exactly looks the same as in case with other (gl4es based) games mean "when scene start to be more heavy, we drops a lot".


Edited by kas1e on 2022/9/20 9:50:33
Edited by kas1e on 2022/9/20 10:29:16
Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Need help with shader optimisation
Quite a regular
Quite a regular


See User information
@kas1e

Check these out

https://hdrlab.org.nz/benchmark/gfxben ... /AmigaOS/GraphicsCard/598

https://hdrlab.org.nz/benchmark/gfxben ... /AmigaOS/GraphicsCard/617

Quote:

Isn't gfxbench already said us about bad raw speed for read/write and not reach the necessary theiretical limits ? Is it of the values we expect it to be ?


Edited by Spectre660 on 2022/9/20 10:19:26
Edited by Spectre660 on 2022/9/20 10:20:31
Edited by Spectre660 on 2022/9/20 10:22:39
Go to top

  Register To Post
(1) 2 »

 




Currently Active Users Viewing This Thread: 1 ( 0 members and 1 Anonymous Users )




Powered by XOOPS 2.0 © 2001-2023 The XOOPS Project