http://irrlicht.sourceforge.net/forum/v ... p?t=20976# called "3 rt and 1 fire shader(HLSL)"
and I decided to convert it to glsl and so far I think I've manually translated the shaders properly but for some reason the texture loads on the billboard and looks almost like it could run but the "time" component doesn't seem to work.
Basically the flame effect doesn't run and just stays at one state.
Here's the code
main.cpp
Code: Select all
#include <irrlicht.h>
#include <iostream>
using namespace irr;
IrrlichtDevice* device = 0;
bool UseHighLevelShaders = false;
bool UseCgShaders = false;
irr::scene::ILightSceneNode* light_node = NULL;
irr::scene::ISceneNode* node = NULL;
class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
public:
virtual void OnSetConstants(video::IMaterialRendererServices* services,
s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
core::matrix4 proj = driver->getTransform(video::ETS_PROJECTION);
core::matrix4 view = driver->getTransform(video::ETS_VIEW);
core::matrix4 world = driver->getTransform(video::ETS_WORLD);
core::matrix4 worldViewProj;
worldViewProj = driver->getTransform(video::ETS_PROJECTION);
worldViewProj *= driver->getTransform(video::ETS_VIEW);
worldViewProj *= driver->getTransform(video::ETS_WORLD);
services->setVertexShaderConstant("mWorldViewProj", worldViewProj.pointer(), 16);
float time = (float)device->getTimer()->getTime();
services->setVertexShaderConstant("time", &time, 1);
s32 TextureLayerID = 0;
services->setPixelShaderConstant("fire_base", &TextureLayerID, 1);
TextureLayerID = 1;
services->setPixelShaderConstant("fire_distortion", &TextureLayerID, 1);
TextureLayerID = 2;
services->setPixelShaderConstant("fire_opacity", &TextureLayerID, 1);
}
};
int main()
{
video::E_DRIVER_TYPE driverType;
UseHighLevelShaders = true;
UseCgShaders =false;
// create device
device = createDevice(irr::video::EDT_OPENGL, core::dimension2d<u32>(640, 480));
if (device == 0)
return 1;
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
gui::IGUIEnvironment* gui = device->getGUIEnvironment();
if (UseCgShaders && !driver->queryFeature(video::EVDF_CG))
{
printf("Warning: No Cg support, disabling.\n");
UseCgShaders=false;
}
io::path vsFileName;
io::path psFileName;
driverType = video::EDT_OPENGL;
psFileName = "opengl.frag";
vsFileName = "opengl.vert";
if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) &&
!driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1))
{
device->getLogger()->log("WARNING: Pixel shaders disabled "\
"because of missing driver/hardware support.");
psFileName = "";
}
if (!driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1) &&
!driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1))
{
device->getLogger()->log("WARNING: Vertex shaders disabled "\
"because of missing driver/hardware support.");
vsFileName = "";
}
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
s32 newMaterialType1 = 0;
s32 newMaterialType2 = 0;
if (gpu)
{
MyShaderCallBack* mc = new MyShaderCallBack();
if (UseHighLevelShaders)
{
const video::E_GPU_SHADING_LANGUAGE shadingLanguage =
UseCgShaders ? video::EGSL_CG:video::EGSL_DEFAULT;
newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles(
vsFileName, "vertexMain", video::EVST_VS_1_1,
psFileName, "pixelMain", video::EPST_PS_1_1,
mc, video::EMT_SOLID, 0, shadingLanguage);
newMaterialType2 = gpu->addHighLevelShaderMaterialFromFiles(
vsFileName, "vertexMain", video::EVST_VS_1_1,
psFileName, "pixelMain", video::EPST_PS_1_1,
mc, video::EMT_TRANSPARENT_ADD_COLOR, 0 , shadingLanguage);
}
else
{
newMaterialType1 = gpu->addShaderMaterialFromFiles(vsFileName,
psFileName, mc, video::EMT_SOLID);
newMaterialType2 = gpu->addShaderMaterialFromFiles(vsFileName,
psFileName, mc, video::EMT_TRANSPARENT_ADD_COLOR);
}
mc->drop();
}
node = smgr->addEmptySceneNode( 0,-1);
node->setPosition( irr::core::vector3df( 0, 0, 0));
light_node = smgr->addLightSceneNode(0, core::vector3df( 0, 0, 0),
video::SColorf(1.0f, 0.6f, 0.7f, 1.0f), 50.0f);
irr::video::SLight & slight = light_node->getLightData();
slight.Type = irr::video::ELT_DIRECTIONAL;
slight.AmbientColor = irr::video::SColorf(1.0f,0.0f,0.0f,0.0f);
slight.SpecularColor = irr::video::SColorf(1.0f,1.0f,1.0f,0.0f);
slight.DiffuseColor = irr::video::SColorf(1.0f,1.0f,1.0f,0.0f);
node->addChild( light_node);
irr::scene::ISceneNodeAnimator* anim = 0;
anim = smgr->createRotationAnimator ( irr::core::vector3df( 0.0f, 0.6f, 0.0f));
node->addAnimator(anim);
anim->drop();
scene::ISceneNode* cubenode = smgr->addBillboardSceneNode(
0, core::dimension2d<f32>(50.0f, 50.0f));
cubenode->setMaterialTexture( 0, driver->getTexture("../../textures/b.png"));
cubenode->setMaterialTexture( 1, driver->getTexture("../../textures/a.png"));
cubenode->setMaterialTexture( 2, driver->getTexture("../../textures/flame.png"));
cubenode->setMaterialFlag(video::EMF_LIGHTING, false);
cubenode->setMaterialFlag(video::EMF_BLEND_OPERATION, true);
cubenode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
cubenode->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType2);
scene::ICameraSceneNode* cam = smgr->addCameraSceneNode();
cam->setPosition(core::vector3df(-45,45,-45));
cam->setTarget(core::vector3df(0,0,0));
device->getCursorControl()->setVisible( false);
int lastFPS = -1;
while(device->run())
if (device->isWindowActive())
{
driver->beginScene(true, true, video::SColor(255,0,0,0));
smgr->drawAll();
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw str = L"Irrlicht Engine - Vertex and pixel shader example [";
str += driver->getName();
str += "] FPS:";
str += fps;
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
}
device->drop();
return 0;
}
/*
Compile and run this, and I hope you have fun with your new little shader
writing tool :).
**/
Code: Select all
uniform sampler2D fire_base;
uniform sampler2D fire_distortion;
uniform sampler2D fire_opacity;
varying vec2 TexCoord0;
varying vec2 TexCoord1;
varying vec2 TexCoord2;
varying vec2 TexCoord3;
vec4 bx2( vec4 x)
{
return 2.0 * x - 1.0;
}
void main()
{
float distortion_amount0 = 0.092;
float distortion_amount1 = 0.092;
float distortion_amount2 = 0.092;
vec4 height_attenuation = vec4(0.3, 0.39, 0.0, 1.0);
vec4 noise0 = texture2D( fire_distortion, TexCoord1);
vec4 noise1 = texture2D( fire_distortion, TexCoord2);
vec4 noise2 = texture2D( fire_distortion, TexCoord3);
vec4 noiseSum = bx2( noise0) * distortion_amount0 +
bx2( noise1) * distortion_amount1 + bx2( noise2) * distortion_amount2;
vec2 perturbedBaseCoords;
perturbedBaseCoords.x = TexCoord0.x + noiseSum.x * (TexCoord0.y *
height_attenuation.x + height_attenuation.y);
perturbedBaseCoords.y = TexCoord0.y + noiseSum.y * (TexCoord0.y *
height_attenuation.x + height_attenuation.y);
vec4 base = texture2D( fire_base, perturbedBaseCoords);
base *= 1.5f;
vec4 opacity = texture2D( fire_opacity, perturbedBaseCoords);
gl_FragColor = base*opacity;
}
opengl.vert
Code: Select all
varying vec2 TexCoord0;
varying vec2 TexCoord1;
varying vec2 TexCoord2;
varying vec2 TexCoord3;
uniform mat4 mWorldViewProj;
float time;
void main()
{
gl_Position = mWorldViewProj * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
vec4 layer_speed = vec4( 0.2, 0.52, 0.1, 1.0);
TexCoord0 = gl_TexCoord[0].st;
TexCoord0 += 0.2;
TexCoord1.x = gl_TexCoord[0].s;
TexCoord1.y = gl_TexCoord[0].t + layer_speed.x * time/1000.0f;
TexCoord2.x = gl_TexCoord[0].s;
TexCoord2.y = gl_TexCoord[0].t + layer_speed.y * time/1000.0f;
TexCoord3.x = gl_TexCoord[0].s;
TexCoord3.y = gl_TexCoord[0].t + layer_speed.z * time/1000.0f;
}
The textures
a.png -> https://imgur.com/pMUHN0m
b.png -> https://imgur.com/dBd8Mat
flame.png -> https://imgur.com/BxEPHDc
All textures on one page.
https://imgur.com/a/T3q3N