I tried to make this http://apoorvaj.io/exploring-bump-mappi ... .html#toc8 tutorial work with Irrlicht and so far I'm not sure what is the variable
Code: Select all
uniform mat4 norm_mtx;// in bump.vert
I'm guessing it's the inverse transpose of the world matrix supposedly called the normal matrix, I'm also new to this stuff. I'm almost positive the two other
variables are correct
Code: Select all
uniform mat4 model_mtx;//ETS_WORLD
uniform mat4 proj_mtx;//ETS_PROJECTION
Code: Select all
cubenode->setMaterialType((video::E_MATERIAL_TYPE) bump_map_shader);
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 bump_map_effect_shader : public video::IShaderConstantSetCallBack
{
public:
virtual void OnSetConstants(video::IMaterialRendererServices* services,
s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
core::matrix4 worldMatrix = driver->getTransform( video::ETS_WORLD);
services->setPixelShaderConstant("model_mtx", worldMatrix.pointer(), 16);
core::matrix4 worldInverseTransposeMatrix = worldMatrix;
worldInverseTransposeMatrix.makeInverse();
//worldInverseTransposeMatrix = worldInverseTransposeMatrix.getTransposed();
services->setPixelShaderConstant("norm_mtx", worldInverseTransposeMatrix.pointer(), 16);
core::matrix4 proj = driver->getTransform(video::ETS_PROJECTION);
services->setPixelShaderConstant("proj_mtx", proj.pointer(), 16);
s32 TextureLayerID = 0;
services->setVertexShaderConstant("tex_norm", &TextureLayerID, 1);
TextureLayerID = 1;
services->setVertexShaderConstant("tex_diffuse", &TextureLayerID, 1);
TextureLayerID = 2;
services->setVertexShaderConstant("tex_depth", &TextureLayerID, 1);
int type = 3;
services->setVertexShaderConstant("type", &type, 1);
int show_tex = 1;
services->setVertexShaderConstant("show_tex", &show_tex, 1);
float depth_scale = 2;
services->setVertexShaderConstant("depth_scale", &depth_scale, 1);
float num_layers = 3;
services->setVertexShaderConstant("num_layers", &num_layers, 1);
}
};
int main()
{
video::E_DRIVER_TYPE driverType;
// 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();
io::path vsFileName;
io::path psFileName;
driverType = video::EDT_OPENGL;
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
s32 bump_map_shader = 0;
if (gpu)
{
const video::E_GPU_SHADING_LANGUAGE shadingLanguage =
video::EGSL_DEFAULT;
//bump mapping
psFileName = "bump.frag";
vsFileName = "bump.vert";
bump_map_effect_shader* bump_map_effect_shader_callback = new bump_map_effect_shader();
bump_map_shader = gpu->addHighLevelShaderMaterialFromFiles(
vsFileName, "vertexMain", video::EVST_VS_1_1,
psFileName, "pixelMain", video::EPST_PS_1_1,
bump_map_effect_shader_callback, video::EMT_TRANSPARENT_ADD_COLOR, 0 , shadingLanguage);
bump_map_effect_shader_callback->drop();
}
irr::scene::ISceneNode* node = NULL;
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, 1.0f, 1.0f, 1.0f), 150.0f);
//light_node->setVisible( true);
irr::video::SLight & slight = light_node->getLightData();
slight.Type = irr::video::ELT_DIRECTIONAL;
slight.AmbientColor = irr::video::SColorf(0.4f,0.24f,0.5f,1.0f);
slight.SpecularColor = irr::video::SColorf(0.2f,1.0f,0.2f,1.0f);
slight.DiffuseColor = irr::video::SColorf(0.2f,0.2f,1.0f,1.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->addCubeSceneNode( 50);
cubenode->setPosition( core::vector3df( 0, 0, 0));
cubenode->setMaterialTexture( 0, driver->getTexture("normal.png"));
cubenode->setMaterialTexture( 1, driver->getTexture("diffuse.png"));
cubenode->setMaterialTexture( 2, driver->getTexture("depth.png"));
cubenode->setMaterialFlag( video::EMF_BLEND_OPERATION, true);
cubenode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
cubenode->setMaterialFlag( video::EMF_LIGHTING, true);
cubenode->setMaterialType((video::E_MATERIAL_TYPE) bump_map_shader);
scene::ICameraSceneNode* cam = smgr->addCameraSceneNode();
cam->setPosition(core::vector3df( 70, 70,-70));
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,255,255,255));
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;
}
Code: Select all
//precision highp float;
//#version 130
attribute vec3 vert_pos;
attribute vec3 vert_tang;
attribute vec3 vert_bitang;
attribute vec2 vert_uv;
uniform mat4 model_mtx;//ETS_WORLD
uniform mat4 norm_mtx;//worldInverseTransposeMatrix???
uniform mat4 proj_mtx;//ETS_PROJECTION
varying vec2 frag_uv;
varying vec3 ts_light_pos; // Tangent space values
varying vec3 ts_view_pos; //
varying vec3 ts_frag_pos; //
mat3 transpose(in mat3 inMatrix)
{
vec3 i0 = inMatrix[0];
vec3 i1 = inMatrix[1];
vec3 i2 = inMatrix[2];
mat3 outMatrix = mat3(
vec3(i0.x, i1.x, i2.x),
vec3(i0.y, i1.y, i2.y),
vec3(i0.z, i1.z, i2.z)
);
return outMatrix;
}
mat3 m3( mat4 m )
{
mat3 result;
result[0][0] = m[0][0];
result[0][1] = m[0][1];
result[0][2] = m[0][2];
result[1][0] = m[1][0];
result[1][1] = m[1][1];
result[1][2] = m[1][2];
result[2][0] = m[2][0];
result[2][1] = m[2][1];
result[2][2] = m[2][2];
return result;
}
void main(void)
{
gl_Position = proj_mtx * vec4(vert_pos, 1.0);
ts_frag_pos = vec3(model_mtx * vec4(vert_pos, 1.0));
vec3 vert_norm = cross(vert_bitang, vert_tang);
vec3 t = normalize(m3(norm_mtx) * vert_tang);
vec3 b = normalize(m3(norm_mtx) * vert_bitang);
vec3 n = normalize(m3(norm_mtx) * vert_norm);
mat3 tbn = transpose(mat3(t, b, n));
vec3 light_pos = vec3(1, 2, 0);
ts_light_pos = tbn * light_pos;
// Our camera is always at the origin
ts_view_pos = tbn * vec3(0, 0, 0);
ts_frag_pos = tbn * ts_frag_pos;
frag_uv = vert_uv;
}
bump.frag
Code: Select all
//precision highp float;
//#version 130
uniform sampler2D tex_norm;
uniform sampler2D tex_diffuse;
uniform sampler2D tex_depth;
/*
The type is controlled by the radio buttons below the canvas.
0 = No bump mapping
1 = Normal mapping
2 = Parallax mapping
3 = Steep parallax mapping
4 = Parallax occlusion mapping
*/
uniform int type;
uniform int show_tex;
uniform float depth_scale;
uniform float num_layers;
varying vec2 frag_uv;
varying vec3 ts_light_pos;
varying vec3 ts_view_pos;
varying vec3 ts_frag_pos;
vec2 parallax_uv(vec2 uv, vec3 view_dir)
{
if (type == 2)
{
// Parallax mapping
float depth = texture2D(tex_depth, uv).r;
vec2 p = view_dir.xy * (depth * depth_scale) / view_dir.z;
return uv - p;
}
else
{
float layer_depth = 1.0 / num_layers;
float cur_layer_depth = 0.0;
vec2 delta_uv = view_dir.xy * depth_scale / (view_dir.z * num_layers);
vec2 cur_uv = uv;
float depth_from_tex = texture2D(tex_depth, cur_uv).r;
for (int i = 0; i < 32; i++)
{
cur_layer_depth += layer_depth;
cur_uv -= delta_uv;
depth_from_tex = texture2D(tex_depth, cur_uv).r;
if (depth_from_tex < cur_layer_depth)
i = 32;
}
if (type == 3)
{
// Steep parallax mapping
return cur_uv;
}
else
{
// Parallax occlusion mapping
vec2 prev_uv = cur_uv + delta_uv;
float next = depth_from_tex - cur_layer_depth;
float prev = texture2D(tex_depth, prev_uv).r - cur_layer_depth
+ layer_depth;
float weight = next / (next - prev);
return mix(cur_uv, prev_uv, weight);
}
}
}
void main(void)
{
vec3 light_dir = normalize(ts_light_pos - ts_frag_pos);
vec3 view_dir = normalize(ts_view_pos - ts_frag_pos);
// Only perturb the texture coordinates if a parallax technique is selected
//(condition) ? (if_true) : (if_false)
vec2 uv = (type < 2) ? frag_uv : parallax_uv( frag_uv, view_dir);
vec3 albedo = texture2D(tex_diffuse, uv).rgb;
if (show_tex == 0)
{
albedo = vec3(1,1,1);
}
vec3 ambient = 0.3 * albedo;
if (type == 0)
{
// No bump mapping
vec3 norm = vec3(0,0,1);
float diffuse = max(dot(light_dir, norm), 0.0);
gl_FragColor = vec4(diffuse * albedo + ambient, 1.0);
}
else
{
// Normal mapping
vec3 norm = normalize(texture2D(tex_norm, uv).rgb * 2.0 - 1.0);
float diffuse = max(dot(light_dir, norm), 0.0);
gl_FragColor = vec4(diffuse * albedo + ambient, 1.0);
}
}
diffuse.png
normal.png
All images at
https://imgur.com/a/ZbZtl