I made my first "from scratch" shader, and worked very well. But, as I'm new in shader programming, I would be pleased if you, masters, could evaluate it for me.
This shader can project a image over another, blending them, where the first image is a mapped one and the second is a decal, with shader generated planar mapping.
I considered that how many calculus are made out of shaders, better. And I don't know how to pass and retrieve 'user data' in the callback. So I made two global variables.
This is the code:
Code: Select all
//callback:
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
//objDim and extents are globals position2df
int texture = 0;
services->setPixelShaderConstant("tex0",(float*)(&texture),1);
int texture2 = 1;
services->setPixelShaderConstant("tex1",(float*)(&texture2),1);
services->setPixelShaderConstant("extents", reinterpret_cast<irr::f32*>(&extents),2);
services->setPixelShaderConstant("objDim", reinterpret_cast<irr::f32*>(&objDim),2);
}
Code: Select all
//globals initialization (the material creation is the same as the tutorial, so, I omitted here
//the region that will receive the decal is the meshBuffer(2) of the object.
aabbox3df bbox = object->getMesh()->getMeshBuffer(2)->getBoundingBox();
objDim.Width = bbox.MaxEdge.X - bbox.MinEdge.X;
objDim.Height = bbox.MaxEdge.Z - bbox.MinEdge.Z;
extents.Width = bbox.MaxEdge.X;
extents.Height = bbox.MaxEdge.Z;
Code: Select all
//vertex shader
uniform vec2 objDim;
uniform vec2 extents;
void main()
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[1].s = (extents.x - gl_Vertex.x) / objDim.x;
gl_TexCoord[1].t = (gl_Vertex.z - extents.y) / objDim.y;
gl_Position = ftransform();
}
Code: Select all
//fragment shader
sampler2D tex0 : register(s0);
sampler2D tex1 : register(s1);
void main()
{
vec4 ColorHull = texture2D(tex0,gl_TexCoord[0].st);
vec4 ColorDecal = texture2D(tex1,gl_TexCoord[1].st);
vec4 Color = ColorDecal * ColorDecal.a/2 + ColorHull * (1-ColorDecal.a/2);
Color.a = 1.0;
gl_FragColor = Color;
}