4 light normalmapping for animated meshes [C++/GLSL]

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

I you are computing the tangent's and putting evrything into tangent space on a per pixel level you can use this method i just though tup,get the delta values for the uv axis's via a single non dependent texture read.

In your vertex shader utlise empty texcoords as your offset values (doing it in the vs prevents dependent tex reads) then in the pixe shader do this:

-use the current uv coords for this fragment and subtract them from the uv coords extracted from a uv map, the uv map fragment should be offset by +1*10^-6 (smallest percsion on nv cards) in each x and y dir, the result should give you dx and dy, the above can be done very quickly if tou put dx and dy in one vector.

puesdo code:
vec2 dUV = texture2D(uvmap,offset)- currentTexcoord;

a 'uv map' is simply a map showing texcoord values.

Here is some code to generate a uv map map lol, just plug it in render monkey with the model and print screen the result.

vertex shader

Code: Select all

varying vec2  tcoord;


void main(void)
{
   tcoord=gl_MultiTexCoord0.xy;
   
   vec2 screenpos=((gl_MultiTexCoord0.xy-0.5)*2);
   gl_Position = vec4( screenpos, 0.0, 1.0 );
 
    
}
pixel shader

Code: Select all

varying vec2  tcoord;


void main(void)
{
   gl_FragColor = vec4(tcoord,0,1);
 
    
}
"Irrlicht is obese"

If you want modern rendering techniques learn how to make them or go to the engine next door =p
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

well you can actually do all the derivation precomputed in the uv texture map
"Irrlicht is obese"

If you want modern rendering techniques learn how to make them or go to the engine next door =p
jingquan
Posts: 222
Joined: Sun Aug 20, 2006 4:10 am
Contact:

Post by jingquan »

Recently, I've been trying to convert this light shader: http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=21186 to C# and finally managed to run it.

Here's a screenshot and there seems to be some major bug in it. It's suppose to be a normalmapped brick wall with 2 lights.

Image

And here's the source:

Code: Select all

using System;
using System.Text;
using IrrlichtNETCP;
using IrrlichtNETCP.Inheritable;
namespace LightShader
{
    public class lightshader
    {
        static string vertBumpShader = "uniform vec3 fvLightPosition1;" + "uniform vec3 fvLightPosition2;" + "uniform vec3 fvLightPosition3;" + "uniform vec3 fvLightPosition4;" + "" + "uniform float fLightStrength1;" + "uniform float fLightStrength2;" + "uniform float fLightStrength3;" + "uniform float fLightStrength4;" + "" + "uniform mat4 matWorldInverse;" + "" + "varying vec2 Texcoord;" + "varying vec3 ViewDirection;" + "varying vec3 LightDirection1;" + "varying vec3 LightDirection2;" + "varying vec3 LightDirection3;" + "varying vec3 LightDirection4;" + "varying vec4 LightDistMultiplier;" + "" + "float getLengthSQR (vec3 vec)" + "{" + "return(vec.x*vec.x+vec.y*vec.y+vec.z*vec.z);" + "}" + "" + "void main( void )" + "{" + "" + " mat4 LightTransform= gl_ModelViewMatrix;" + " LightTransform=LightTransform*matWorldInverse;" + "" + " gl_Position = ftransform();" + " Texcoord = gl_MultiTexCoord0.xy;" + "" + " vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex;" + " vec4 fvLightPos1 = LightTransform * vec4(fvLightPosition1,1.0);" + " vec4 fvLightPos2 = LightTransform * vec4(fvLightPosition2,1.0);" + " vec4 fvLightPos3 = LightTransform * vec4(fvLightPosition3,1.0);" + " vec4 fvLightPos4 = LightTransform * vec4(fvLightPosition4,1.0);" + "" + " vec3 fvViewDirection = - fvObjectPosition.xyz;" + "" + " vec3 fvLightDirection1 = (fvLightPos1.xyz - fvObjectPosition.xyz);" + " vec3 fvLightDirection2 = (fvLightPos2.xyz - fvObjectPosition.xyz);" + " vec3 fvLightDirection3 = (fvLightPos3.xyz - fvObjectPosition.xyz);" + " vec3 fvLightDirection4 = (fvLightPos4.xyz - fvObjectPosition.xyz);" + "" + " LightDistMultiplier[0]=1.0/(getLengthSQR (fvLightDirection1)/(fLightStrength1*10000.0));" + " LightDistMultiplier[1]=1.0/(getLengthSQR (fvLightDirection2)/(fLightStrength2*10000.0));" + " LightDistMultiplier[2]=1.0/(getLengthSQR (fvLightDirection3)/(fLightStrength3*10000.0));" + " LightDistMultiplier[3]=1.0/(getLengthSQR (fvLightDirection4)/(fLightStrength4*10000.0));" + "" + " vec3 fvNormal = gl_NormalMatrix * gl_Normal;" + "" + " vec3 fvTangent = -vec3(abs(gl_Normal.y) + abs(gl_Normal.z), abs(gl_Normal.x), 0);" + " vec3 fvBinormal =cross(fvTangent,gl_Normal); " + " fvTangent=gl_NormalMatrix*cross(fvBinormal,gl_Normal);" + " fvBinormal=gl_NormalMatrix*fvBinormal;" + "" + "" + " ViewDirection.x = dot( fvTangent, fvViewDirection );" + " ViewDirection.y = dot( fvBinormal, fvViewDirection );" + " ViewDirection.z = dot( fvNormal, fvViewDirection );" + "" + " LightDirection1.x = dot( fvTangent, fvLightDirection1.xyz );" + " LightDirection1.y = dot( fvBinormal, fvLightDirection1.xyz );" + " LightDirection1.z = dot( fvNormal, fvLightDirection1.xyz );" + "" + " LightDirection2.x = dot( fvTangent, fvLightDirection2.xyz );" + " LightDirection2.y = dot( fvBinormal, fvLightDirection2.xyz );" + " LightDirection2.z = dot( fvNormal, fvLightDirection2.xyz );" + "" + " LightDirection3.x = dot( fvTangent, fvLightDirection3.xyz );" + " LightDirection3.y = dot( fvBinormal, fvLightDirection3.xyz );" + " LightDirection3.z = dot( fvNormal, fvLightDirection3.xyz );" + "" + " LightDirection4.x = dot( fvTangent, fvLightDirection4.xyz );" + " LightDirection4.y = dot( fvBinormal, fvLightDirection4.xyz );" + " LightDirection4.z = dot( fvNormal, fvLightDirection4.xyz );" + "" + "}";
        static string fragBumpShader = "uniform vec4 fvAmbient;" + "uniform vec4 fvLight1Color;" + "uniform vec4 fvLight2Color;" + "uniform vec4 fvLight3Color;" + "uniform vec4 fvLight4Color;" + "uniform float fSpecularPower;" + "uniform float fSpecularStrength;" + "uniform float fBumpStrength;" + "uniform sampler2D baseMap;" + "uniform sampler2D bumpMap;" + "varying vec2 Texcoord;" + "varying vec3 ViewDirection;" + "varying vec3 LightDirection1;" + "varying vec3 LightDirection2;" + "varying vec3 LightDirection3;" + "varying vec3 LightDirection4;" + "varying vec4 LightDistMultiplier;" + "void main( void )" + "{" + " vec3 fvLightDirection1 = normalize( LightDirection1 );" + " vec3 fvLightDirection2 = normalize( LightDirection2 );" + " vec3 fvLightDirection3 = normalize( LightDirection3 );" + " vec3 fvLightDirection4 = normalize( LightDirection4 );" + " vec3 fvNormal = texture2D( bumpMap, Texcoord ).yxz;" + " fvNormal.xy*=2.0;" + " fvNormal.xy-=1.0;" + " fvNormal=(vec3(0.0,0.0,1.0)-fvNormal)*fBumpStrength+fvNormal;" + " fvNormal=normalize(fvNormal);" + " float fNDotL1 = max(dot(fvNormal, fvLightDirection1),0.0)-0.1; " + " float fNDotL2 = max(dot(fvNormal, fvLightDirection2),0.0)-0.1; " + " float fNDotL3 = max(dot(fvNormal, fvLightDirection3),0.0)-0.1; " + " float fNDotL4 = max(dot(fvNormal, fvLightDirection4),0.0)-0.1; " + " vec3 fvReflection1 = normalize( ( ( 2.0 * fvNormal ) ) - fvLightDirection1 ); " + " vec3 fvReflection2 = normalize( ( ( 2.0 * fvNormal ) ) - fvLightDirection2 ); " + " vec3 fvReflection3 = normalize( ( ( 2.0 * fvNormal ) ) - fvLightDirection3 ); " + " vec3 fvReflection4 = normalize( ( ( 2.0 * fvNormal ) ) - fvLightDirection4 ); " + " vec3 fvViewDirection = normalize( ViewDirection );" + " float fRDotV1 = max( 0.0, dot( fvReflection1, fvViewDirection ) );" + " float fRDotV2 = max( 0.0, dot( fvReflection2, fvViewDirection ) );" + " float fRDotV3 = max( 0.0, dot( fvReflection3, fvViewDirection ) );" + " float fRDotV4 = max( 0.0, dot( fvReflection4, fvViewDirection ) );" + " vec4 fvBaseColor = texture2D( baseMap, Texcoord );" + " vec4 fvTotalAmbient = fvAmbient * fvBaseColor; " + " vec4 fvTotalDiffuse = fvLight1Color * fNDotL1* fvBaseColor*LightDistMultiplier[0]; " + " vec4 fvTotalSpecular = fNDotL1*fvLight1Color * ( pow( fRDotV1, fSpecularPower ) )*LightDistMultiplier[0];" + " fvTotalDiffuse += fvLight2Color * fNDotL2* fvBaseColor*LightDistMultiplier[1]; " + " fvTotalSpecular += fNDotL2*fvLight2Color * ( pow( fRDotV2, fSpecularPower ) )*LightDistMultiplier[1]; " + " fvTotalDiffuse += fvLight3Color * fNDotL3* fvBaseColor*LightDistMultiplier[2]; " + " fvTotalSpecular += fNDotL3*fvLight3Color * ( pow( fRDotV3, fSpecularPower ) )*LightDistMultiplier[2]; " + " fvTotalDiffuse += fvLight4Color * fNDotL4* fvBaseColor*LightDistMultiplier[3]; " + " fvTotalSpecular += fNDotL4*fvLight4Color * ( pow( fRDotV4, fSpecularPower ) )*LightDistMultiplier[3]; " + " vec4 color=( fvTotalAmbient + fvTotalDiffuse+ (fvTotalSpecular*fSpecularStrength));" + " if(color.r>1.0){color.gb+=color.r-1.0;}" + " if(color.g>1.0){color.rb+=color.g-1.0;}" + " if(color.b>1.0){color.rg+=color.b-1.0;}" + " gl_FragColor = color;" + "}";
        public class Shader_Bump_callback
        {
            public static float[] fLightStrength = new float[4];
            public static Vector3D[] fvLightPosition = new Vector3D[4];
            public static Colorf[] fvLightColor = new Colorf[4];
            public static Colorf fvAmbient;
            public static float fSpecularPower;
            public static float fSpecularStrength;
            public static float fBumpStrength;

            public static void OnShaderSet(MaterialRendererServices services, int userData)
            {
                int var0 = 0;
                services.SetPixelShaderConstant("baseMap", (float)var0);
                int var1 = 1;
                services.SetPixelShaderConstant("bumpMap", (float)var1);
                Matrix4 invWorld = services.VideoDriver.GetTransform(TransformationState.World);
                invWorld.MakeInverse();
                services.SetPixelShaderConstant("matWorldInverse", invWorld.ToShader());
                services.SetPixelShaderConstant("fLightStrength1", fLightStrength[0]);
                services.SetPixelShaderConstant("fLightStrength2", fLightStrength[1]);
                services.SetPixelShaderConstant("fLightStrength3", fLightStrength[2]);
                services.SetPixelShaderConstant("fLightStrength4", fLightStrength[3]);
                services.SetPixelShaderConstant("fvLightPosition1", fvLightPosition[0].ToShader());
                services.SetPixelShaderConstant("fvLightPosition2", fvLightPosition[1].ToShader());
                services.SetPixelShaderConstant("fvLightPosition3", fvLightPosition[2].ToShader());
                services.SetPixelShaderConstant("fvLightPosition4", fvLightPosition[3].ToShader());
                services.SetPixelShaderConstant("fvAmbient", fvAmbient.ToShader());
                services.SetPixelShaderConstant("fvLight1Color", fvLightColor[0].ToShader());
                services.SetPixelShaderConstant("fvLight2Color", fvLightColor[1].ToShader());
                services.SetPixelShaderConstant("fvLight3Color", fvLightColor[2].ToShader());
                services.SetPixelShaderConstant("fvLight4Color", fvLightColor[3].ToShader());
                services.SetPixelShaderConstant("fSpecularPower", fSpecularPower);
                services.SetPixelShaderConstant("fSpecularStrength", fSpecularStrength);
                services.SetPixelShaderConstant("fBumpStrength", fBumpStrength);
            }
        }
        public static VideoDriver Driver;
        public static SceneManager Scene;

        public static void Main()
        {
            IrrlichtDevice device = new IrrlichtDevice(DriverType.OpenGL, new Dimension2D(1024, 768), 32, false, true, true, true);
            device.OnEvent += new OnEventDelegate(device_OnEvent);
            Driver = device.VideoDriver;
            Scene = device.SceneManager;
            GPUProgrammingServices gpu = Driver.GPUProgrammingServices;
            Shader_Bump_callback.fBumpStrength = 4;
            Shader_Bump_callback.fSpecularStrength = 0.9F;
            Shader_Bump_callback.fSpecularPower = 20;
            Shader_Bump_callback.fvAmbient = new Colorf(255, 2, 2, 2);
            Shader_Bump_callback.fLightStrength[0] = 1;
            Shader_Bump_callback.fvLightColor[0] = new Colorf(255, 100, 52, 31);
            Shader_Bump_callback.fvLightPosition[0] = new Vector3D(100, -10, 0);
            Shader_Bump_callback.fLightStrength[1] = 1;
            Shader_Bump_callback.fvLightColor[1] = new Colorf(255, 31, 55, 100);
            Shader_Bump_callback.fvLightPosition[1] = new Vector3D(-100, 10, 0);
            Material Mater;
            Mater = new Material();
            Mater.MaterialType = ((MaterialType)(gpu.AddHighLevelShaderMaterial(vertBumpShader, "main", VertexShaderType._1_1, fragBumpShader, "main", PixelShaderType._1_1, Shader_Bump_callback.OnShaderSet, MaterialType.Solid, 0)));
            CameraSceneNode fpsCamera = Scene.AddCameraSceneNodeFPS(null, 150, 250, false);
            fpsCamera.Position = new Vector3D(-90, 90, -90);
            device.CursorControl.Visible = false;
            AnimatedMesh mesh = Scene.GetMesh("alice_vg.3ds");
            SceneNode test = Scene.AddAnimatedMeshSceneNode(mesh);
            test.Position = new Vector3D(0, 0, 0);
            test.SetMaterialFlag(MaterialFlag.Lighting, false);
            Material mat = test.GetMaterial(0);
            mat.Texture1 = Driver.GetTexture("alice_d.png");
            mat.Texture2 = Driver.GetTexture("alice_n.png");
            mat.MaterialType = Mater.MaterialType;
            int lastFPS = -1;
            while (device.Run())
            {
                if (device.WindowActive)
                {
                    Driver.BeginScene(true, true, new Color(0, 0, 0, 0));
                    Driver.SetRenderTarget(null, true, true, new Color(0, 100, 100, 100));
                    Scene.DrawAll();
                    Driver.EndScene();
                    int fps = Driver.FPS;
                    if (!((lastFPS == fps)))
                    {
                        device.WindowCaption = "Shader Demo [" + fps + "]";
                        lastFPS = fps;
                    }
                }
            }
            device.Dispose();
        }

        static bool device_OnEvent(Event ev)
        {
            if (ev.KeyPressedDown && ev.KeyCode == KeyCode.Escape)
            {
                System.Environment.Exit(0);
            }
            return false;
        }
    }
}
I would really appericate if anyone could tell me what I had done wrong.
Virion
Competition winner
Posts: 2148
Joined: Mon Dec 18, 2006 5:04 am

Post by Virion »

jingquan i got the same problem with you too.
mrcdrc
Posts: 7
Joined: Sat Mar 31, 2007 10:26 am

Post by mrcdrc »

I guess it's the first line in here...

Code: Select all

            Material mat = test.GetMaterial(0);
            mat.Texture1 = Driver.GetTexture("alice_d.png");
            mat.Texture2 = Driver.GetTexture("alice_n.png");
            mat.MaterialType = Mater.MaterialType; 
You work on local copy of the Material, isn't it? I'm just guessing 'cause i don't know C#, so correct me if i'm wrong.

Anyways, you may try the following instead:

Code: Select all

            test.GetMaterial(0).Texture1 = Driver.GetTexture("alice_d.png");
            test.GetMaterial(0).Texture2 = Driver.GetTexture("alice_n.png"); 
            test.GetMaterial(0).MaterialType = Mater.MaterialType;
Or simply add

Code: Select all

            test.SetMaterial(mat);
after Material definition (i guess it's called like that in Irrlicht.NET).


bye
mrc
jingquan
Posts: 222
Joined: Sun Aug 20, 2006 4:10 am
Contact:

Post by jingquan »

Thanks for your help but it still isn't working...

There's two lines in the console that reads:

Code: Select all

HLSL vertex shader compilation failed:
syntax error: unexpected token 'fvLightPosition1'
BTW, I left this C++ line out as I don't know what it does:

Code: Select all

Override material type
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

This is a glsl shader, it wont run in directx.
"Irrlicht is obese"

If you want modern rendering techniques learn how to make them or go to the engine next door =p
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

btw i can add the tangent generator to irrlicht's parallax/bumpmap shader if you want. It will only have 2 active lights but it will work with animated chracters.
"Irrlicht is obese"

If you want modern rendering techniques learn how to make them or go to the engine next door =p
jingquan
Posts: 222
Joined: Sun Aug 20, 2006 4:10 am
Contact:

Post by jingquan »

As I suspected too, how do I set it to run in OpenGL?
TheGameMaker
Posts: 275
Joined: Fri May 12, 2006 6:37 pm
Location: Germany

Post by TheGameMaker »

@omaremad yeah.. that would be great!!
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

OK its done for Ogl bc thats what i can test now ( i dont have the dx lib)

Code: Select all


"MUL TempBinormal.xyz, -InNormal.zxyw, c[0].xyyw;\n"\
"MUL TempTangent.xyz, -InNormal.zxyw, c[0].yxyw;\n"\
"MAD TempTangent.xyz, InNormal.yzxw, c[0].xyyw, TempTangent;\n"\
"MAD TempBinormal.xyz, InNormal.yzxw, c[0].yyxw, TempBinormal;\n"\
"ADD Temp.xyz, TempTangent, -TempBinormal;\n"\
"DP3 TempTangent.x, TempTangent, TempTangent;\n"\
"MAD TempTangent.xyz, TempTangent.x, Temp, TempBinormal;\n"\
"MUL TempBinormal.xyz, TempTangent.zxyw, InNormal.yzxw;\n"\
"MAD TempBinormal.xyz, TempTangent.yzxw, InNormal.zxyw, -TempBinormal;\n"\
The code will not make sense since i used some unrelated temporary registers instead of making new ones which are clearly named (this is for compatiblity).

Insert this in the .cpp file(inside the irrlicht source) of your material of choice (like COpenGLNormalMapRenderer.cpp)

look for the following code.

Code: Select all

"# transform normal \n"\
	"DP3 TempNormal.x, InNormal.x, program.local[0];\n"\
	"DP3 TempNormal.y, InNormal.y, program.local[1]; \n"\
	"DP3 TempNormal.z, InNormal.z, program.local[2];\n"\
	"\n"\

PASTE CODE HERE

	"# transform tangent \n"\
	"DP3 TempTangent.x, InTangent.x, program.local[0];\n"\
	"DP3 TempTangent.y, InTangent.y, program.local[1]; \n"\
	"DP3 TempTangent.z, InTangent.z, program.local[2];\n"\
	"\n"\
then

paste this code

Code: Select all

"# transform tangent \n"\
	"DP3 TempTangent.x, TempTangent.x, program.local[0];\n"\
	"DP3 TempTangent.y, TempTangent.y, program.local[1]; \n"\
	"DP3 TempTangent.z, TempTangent.z, program.local[2];\n"\
	"\n"\
	"# transform binormal \n"\
	"DP3 TempBinormal.x, TempBinormal.x, program.local[0];\n"\
	"DP3 TempBinormal.y, TempBinormal.y, program.local[1]; \n"\
	"DP3 TempBinormal.z, TempBinormal.z, program.local[2];\n"\
	"\n"\
instead of the segments already there.

In version 1.3 the already exsisting flicker bug doesnt go away using this code.
"Irrlicht is obese"

If you want modern rendering techniques learn how to make them or go to the engine next door =p
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

btw i forgot to declare c

Code: Select all

"PARAM c[1] = { { 1, 0 } };\n"\
put that before the first block of inserted code.
"Irrlicht is obese"

If you want modern rendering techniques learn how to make them or go to the engine next door =p
jingquan
Posts: 222
Joined: Sun Aug 20, 2006 4:10 am
Contact:

Post by jingquan »

So, how do I set it to read as glsl? Is there more steps than to insert: new IrrlichtDevice(DriverType.OpenGL,....
LLDD
Posts: 43
Joined: Fri May 11, 2007 9:50 am

Post by LLDD »

This shader does not seem to work with my Radeon 9600. Everything seems fine but I get the mesh like it was in wireframe mode. Anyone knows what the problem could be?

Example:
Image

In game:
Image
________
LOVE QUOTES FORUM
Last edited by LLDD on Sun Feb 20, 2011 2:11 am, edited 1 time in total.
TheGameMaker
Posts: 275
Joined: Fri May 12, 2006 6:37 pm
Location: Germany

Post by TheGameMaker »

@jingquan:
yeah.. thats right.. just change the startup param for the driver from DX to OGL(just have a look into the tutorials.. there are examples in which you can choose between DX&OGL at runtime..)

@LLDD:
uhmm its not Radeons fault, since I own a 9800.
Its not the shaderversions fault since 9600 supports 2.0 as well.
You´re using OGL as driver.. so thats OK as well.
have you just copy`n`pasted my code, or have you changed something??
(maybe the Textures... got some strabge looking problems with wrong Texturesetup..)
Post Reply