Shader effect doesn't work

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
JYahyah
Posts: 2
Joined: Tue Mar 31, 2020 3:31 pm

Shader effect doesn't work

Post by JYahyah »

Hello everyone!
I'm trying to make this shader work, but I can't do it at all.
I found a shader on the internet to simulate a distortion effect, and I'm trying to apply it to a plane, but the screen just flashes, and I can't see the effect.
Is there something wrong with the code?
Some help?

water.psh

Code: Select all

 
// nvidia shader library
// http://developer.download.nvidia.com/shaderlibrary/webpages/shader_library.html
// time based displacement
 
uniform sampler2D texture0; //SceneBuffer
uniform sampler2D texture1; //NormalTex
 
uniform float ElapsedTime;
uniform float EffectStrength;
uniform float Speed;
 
void main()
{
    vec4 normalCol = 2.0*texture2D(texture1, gl_TexCoord[0].xy+ElapsedTime*Speed)-1.0;
    gl_FragColor = texture2D(texture0, gl_TexCoord[0].xy+normalCol.xy*EffectStrength);
}
 
vertex.vsh

Code: Select all

 
void main()
{
    gl_Position = gl_Vertex * 2.0 - 1.0;
    gl_TexCoord[0] = gl_Vertex;
}
 
 
main.cpp

Code: Select all

 
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
 
#include <irrlicht.h>
#include "exampleHelper.h"
 
using namespace irr;
 
class WaterCallback : public video::IShaderConstantSetCallBack
{
    public:
 
        f32 time;
        f32 strength;
        f32 speed;
 
    void OnSetConstants(video::IMaterialRendererServices* services, s32 userData) override
    {
        s32 texture0 = 0;
        services->setPixelShaderConstant("texture0", &texture0, 1);
 
        s32 texture1 = 1;
        services->setPixelShaderConstant("texture1", &texture1, 1);
 
        services->setPixelShaderConstant("ElapsedTime", &time, 1);
        services->setPixelShaderConstant("EffectStrength", &strength, 1);
        services->setPixelShaderConstant("Speed", &speed, 1);
    }
};
 
int main()
{
    IrrlichtDevice *device =
        createDevice( video::EDT_OPENGL, dimension2d<u32>(1024, 768), 32,
            false, false, false, 0);
 
    if (!device)
        return 1;
        
    IVideoDriver* driver = device->getVideoDriver();
    ISceneManager* smgr = device->getSceneManager();
    IGUIEnvironment* guienv = device->getGUIEnvironment();
    video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
 
    WaterCallback* waterCallback = new WaterLightCallback();
    waterCallback->speed = 0.05f;
    waterCallback->strength = 0.05f;
    waterCallback->time = device->getTimer()->getTime() * 0.001f; //2.f;
    
    s32 shaderMaterial = gpu->addHighLevelShaderMaterialFromFiles(
        "vertex.vsh", "main", video::EVST_VS_1_1,
        "water.psh", "main", video::EPST_PS_2_0,
        waterCallback, video::EMT_SOLID);
        
    const io::path mediaPath = getExampleMediaPath();
 
    video::ITexture* rtTexture = driver->addRenderTargetTexture(dimension2d<u32>(512, 512));
    video::ITexture* waterTexture = driver->getTexture("water.png"); // Bump mapping texture
 
    scene::IAnimatedMesh* watermesh = smgr->addHillPlaneMesh("myHill",
        core::dimension2d<f32>(20, 20),
        core::dimension2d<u32>(40, 40), 0, 0,
        core::dimension2d<f32>(0, 0),
        core::dimension2d<f32>(10, 10));
 
    scene::ISceneNode* node = smgr->addWaterSurfaceSceneNode(watermesh->getMesh(0), 3.0f, 300.0f, 30.0f);
    node->setMaterialType((video::E_MATERIAL_TYPE)shaderMaterial);
    node->setMaterialFlag(video::EMF_LIGHTING, false);
 
    node->setMaterialTexture(0, rtTexture);
    node->setMaterialTexture(1, waterTexture);
 
    scene::ISceneNode* skydome = smgr->addSkyDomeSceneNode(driver->getTexture(mediaPath + "skydome.jpg"));
 
    smgr->addCameraSceneNodeFPS();
    
    while(device->run())
    {
        driver->beginScene();
        driver->setRenderTarget(rtTexture, true, true, video::SColor(255, 255, 255, 255));
        node->setVisible(false);
        smgr->drawAll();
        driver->setRenderTarget(0, false, false, video::SColor(255, 255, 255, 255));
        node->setVisible(true);
        smgr->drawAll();
        driver->endScene();
    }
    
    device->drop();
 
    return 0;
}
 
 
Thanks
CuteAlien
Admin
Posts: 9647
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Shader effect doesn't work

Post by CuteAlien »

Is it one from here? http://developer.download.nvidia.com/sh ... brary.html
Which one?

I don't think it's supposed to run on a 3d node like this as the vertex calculations makes no sense for that case.
Pretty sure your shader is supposed to run on some plane with vertices in the 0-1 range (so after the gl_Vertex * 2.0 - 1.0 calculation it will end up in the -1 to 1 range).

And maybe (guessing here without more info) it's only supposed to run to create the rendertarget. And the next run then should be with another material which also regards for example camera calculations (your vertex shader ignores those - it has no world-view-projection matrix).

Also I note you don't update your timer - so that one would be stuck to fixed value (but ok for first test).

And you didn't compile your example before posting (you'll noticed it won't compile without a few changes if you do so).

Basically the thing you see is that the water-node (which Irrlicht is animating) has accidentally sometimes vertices going through the 0-1 range and puts those out on screen ... ignoring camera transformations.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply