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.
LLDD
Posts: 43
Joined: Fri May 11, 2007 9:50 am

Post by LLDD »

TheGameMaker wrote:@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..)
I only changed the background color to white to see the model. I downloaded the same textures you were using on the example. And the console doesn't show any problem. I'll try to test it on another machine. Thanks for the help.

*EDIT* Found the problem, sorry to bother you. I updated the driver and got it working. It works great:
Image
________
Yamaha rd500lc specifications
Last edited by LLDD on Sun Feb 20, 2011 2:11 am, edited 1 time in total.
jingquan
Posts: 222
Joined: Sun Aug 20, 2006 4:10 am
Contact:

Post by jingquan »

Yeah, the error is exactly what I got when I run it, and it's been set to opengl. Yes, you're right, it won't work with direct3d.
LLDD
Posts: 43
Joined: Fri May 11, 2007 9:50 am

Post by LLDD »

How difficult would it be to addapt the shader to use an specular map (my knowledge of shaders is really limited)?
________
Thinkmill
Last edited by LLDD on Sun Feb 20, 2011 2:12 am, edited 1 time in total.
TheGameMaker
Posts: 275
Joined: Fri May 12, 2006 6:37 pm
Location: Germany

Post by TheGameMaker »

Would be work at al... already did this for myself..
but I don´t have the code on this machine.. so I´ll make it for you.
you can use for example the alphachannel of color&normalmap for spec Power&strength, or use a third map with all params in it..(for example bumpstrength)
lets suppose we use a third tex:
the third tex use
R: Bumpscale
G: Spec Strength
B: Spec Power
we just had to change the pixelshader like this:
(not tested.. but the way it should work is correct)

Code: Select all

const stringc 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;"
"uniform sampler2D strengthMap;"

"varying vec2 Texcoord;"
"varying vec3 ViewDirection;"
"varying vec3 LightDirection1;"
"varying vec3 LightDirection2;"
"varying vec3 LightDirection3;"
"varying vec3 LightDirection4;"
"varying vec4 LightDistMultiplier;"

"void main( void )"
"{"
"   vec4 s=texture2D(strengthMap,Texcoord);   
"   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*s.r+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]; "
"float spec=fSpecularPower *s.b;
"   vec4  fvTotalSpecular  = fNDotL1*fvLight1Color * ( pow( fRDotV1, spec ) )*LightDistMultiplier[0];"
   
"         fvTotalDiffuse   += fvLight2Color * fNDotL2* fvBaseColor*LightDistMultiplier[1]; "
"         fvTotalSpecular  += fNDotL2*fvLight2Color * ( pow( fRDotV2, spec ) )*LightDistMultiplier[1];  "
   
"         fvTotalDiffuse   += fvLight3Color * fNDotL3* fvBaseColor*LightDistMultiplier[2]; "
"         fvTotalSpecular  += fNDotL3*fvLight3Color * ( pow( fRDotV3, spec ) )*LightDistMultiplier[2];  "
         
"         fvTotalDiffuse   += fvLight4Color * fNDotL4* fvBaseColor*LightDistMultiplier[3]; "
"         fvTotalSpecular  += fNDotL4*fvLight4Color * ( pow( fRDotV4, spec ) )*LightDistMultiplier[3]; "
   
"   vec4 color=( fvTotalAmbient + fvTotalDiffuse+ (fvTotalSpecular*fSpecularStrength*s.g));"
"   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;"

"}"
; 
and of course we have to add those third tex to the Objekt.
change the callback like this:

Code: Select all

class Shader_Bump_callback: public video::IShaderConstantSetCallBack
{
public:
    float fLightStrength[4]; //you know I=1/r²?? i changed it to I=1/(r²/fLightStrength) for better results
    vector3df fvLightPosition[4]; //the light positions
    SColorf fvLightColor[4];
    SColorf fvAmbient;     
    float fSpecularPower;   // S=pow(fDiffuseIntensity,fSpecularPower)*fSpecularStrength;
    float fSpecularStrength;// will result in less glossing surfaces
    float fBumpStrength;    //strength of the bumpmapping.. higher values will result in more "bumpy" surfaces
   
  virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
  {

    int var0=0;
    services->setPixelShaderConstant("baseMap", (float*)(&var0), 1); 
    int var1=1;
    services->setPixelShaderConstant("bumpMap", (float*)(&var1), 1); 
    int var2=2;
    services->setPixelShaderConstant("strengthMap", (float*)(&var2), 1); 
   
    core::matrix4 invWorld = services->getVideoDriver()->getTransform(video::ETS_WORLD);
    invWorld.makeInverse();
    services->setPixelShaderConstant("matWorldInverse", (float*)(&invWorld), 16);
   
    services->setPixelShaderConstant("fLightStrength1", (float*)(&fLightStrength[0]), 1);
    services->setPixelShaderConstant("fLightStrength2", (float*)(&fLightStrength[1]), 1);
    services->setPixelShaderConstant("fLightStrength3", (float*)(&fLightStrength[2]), 1);
    services->setPixelShaderConstant("fLightStrength4", (float*)(&fLightStrength[3]), 1);
   
    services->setPixelShaderConstant("fvLightPosition1", (float*)(&fvLightPosition[0]), 3);
    services->setPixelShaderConstant("fvLightPosition2", (float*)(&fvLightPosition[1]), 3);
    services->setPixelShaderConstant("fvLightPosition3", (float*)(&fvLightPosition[2]), 3);
    services->setPixelShaderConstant("fvLightPosition4", (float*)(&fvLightPosition[3]), 3);
   
    services->setPixelShaderConstant("fvAmbient", (float*)(&fvAmbient), 4);
    services->setPixelShaderConstant("fvLight1Color", (float*)(&fvLightColor[0]), 4);
    services->setPixelShaderConstant("fvLight2Color", (float*)(&fvLightColor[1]), 4);
    services->setPixelShaderConstant("fvLight3Color", (float*)(&fvLightColor[2]), 4);
    services->setPixelShaderConstant("fvLight4Color", (float*)(&fvLightColor[3]), 4);

    services->setPixelShaderConstant("fSpecularPower", (float*)(&fSpecularPower), 1);
    services->setPixelShaderConstant("fSpecularStrength", (float*)(&fSpecularStrength), 1);
    services->setPixelShaderConstant("fBumpStrength", (float*)(&fBumpStrength), 1);


   }
}; 
greetz TGM
LLDD
Posts: 43
Joined: Fri May 11, 2007 9:50 am

Post by LLDD »

It seems to work properly, thanks! You are a monster ;)

Not shaded:
Image

Old shader (all the model is very specular):
Image

New Shader (The metallic parts are much more specular than the rest!):
Image
________
Cg125
Last edited by LLDD on Sun Feb 20, 2011 2:12 am, edited 1 time in total.
TheGameMaker
Posts: 275
Joined: Fri May 12, 2006 6:37 pm
Location: Germany

Post by TheGameMaker »

I´m happy you like it^^
jingquan
Posts: 222
Joined: Sun Aug 20, 2006 4:10 am
Contact:

Post by jingquan »

Great shader.

One problem, I can't fully get this shader to work on a material. eg, I have a room mesh with 2 material assigned to it as the walls and floor. As I only want the floor to be passed throught this shader for the normalmap, I did:

Code: Select all

WorldNode.GetMaterial(1).Texture2 = driver.GetTexture("office/pwall_n.png");
WorldNode.GetMaterial(1).MaterialType = Mater.MaterialType;
However I only see the diffuse texture and the shader, no bumpy floor.

It only works when I did this:

Code: Select all

            WorldNode.SetMaterialTexture(1, driver.GetTexture("office/pwall_n.png"));
            WorldNode.SetMaterialType(Mater.MaterialType);
I've done some research on this and I'm not sure whether do I need a custom material renderer or something similar. Any help?
qez111
Posts: 54
Joined: Mon Apr 28, 2008 9:44 pm

Using multiple normal maps

Post by qez111 »

This one works great, but it only applies just the first normal map that gets applied to an object. But how do I apply more than one normal map? What code changes would be required to support multiple normal maps, for different material slots of the same mesh.

For example, If i have a node in which I want to apply normal maps to all 3 materials, I tried to do this, but the same normal map (which was applied to the first material) is shown on all objects in the scene to which mtlToonShader material is applied.

Code: Select all

node.GetMaterial(1).Texture2 = driver.GetTexture("test_nm1.png"); 
node.GetMaterial(1).MaterialType = (video::E_MATERIAL_TYPE)mtlToonShader;
node.GetMaterial(2).Texture2 = driver.GetTexture("test_nm2.png"); 
node.GetMaterial(2).MaterialType = (video::E_MATERIAL_TYPE)mtlToonShader;
node.GetMaterial(3).Texture2 = driver.GetTexture("test_nm3.png"); 
node.GetMaterial(3).MaterialType = (video::E_MATERIAL_TYPE)mtlToonShader;

However, the above code doesn't seem to work as expected. Only the following code seems to work, but applies Fieldstonebumpdot3.tga normal map to all materials, which is not what I want. to all materials

Code: Select all

node->setMaterialTexture( 0, driver->getTexture("Fieldstone.tga") ); 
      node->setMaterialTexture( 1, driver->getTexture("Fieldstonebumpdot3.tga") ); 
      node->setMaterialType((video::E_MATERIAL_TYPE)mtlToonShader); // Override material type 
My problem is also somewhat similar to what jingquan might have faced as he has explained by him in the earlier post.
Any tips on how to overcome this problem?

Thanks.
Last edited by qez111 on Mon Feb 09, 2009 7:56 pm, edited 1 time in total.
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

yaeh.. thats right... if you want the shader to work with multiple lights(non-hardcoded number) you would have to use a loop instead of a hardcoded lightcalculation for each light.. this would be a bigger change...
Loop is not really an option. When shader is compiled, each loop is executed but unused ones are drooped. So having 1 light in scene will be as expensive as having 8.

Only way is to compile shader code itself on run time ...adding appropriate code for every light.
qez111
Posts: 54
Joined: Mon Apr 28, 2008 9:44 pm

Post by qez111 »

I don't know if your reply was for my question (or i may not have understood), but what i was looking for is not about using multiple lights, but my question was how to use multiple normal maps for the same model.
sudi
Posts: 1686
Joined: Fri Aug 26, 2005 8:38 pm

Post by sudi »

what do u mean? two normalmaps for the triangle or just several normalmaps like several colormaps for the model?
if u mean the second thats done in your modeling programm.
if u mean the first i don't know what u are trying to do.
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
qez111
Posts: 54
Joined: Mon Apr 28, 2008 9:44 pm

Post by qez111 »

What i mean is using more than one normal map for the same model.
For eg. in my character, the face has a normal map, and rest of the body has its another normal map. Other accessories such as cap, protection gear etc have their own normal map textures. That is, there is more than one texture used for the entire model.
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

A mesh is made of many mesh buffers, each mesh buffer has one material
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
detvog
Posts: 19
Joined: Sun Mar 02, 2008 8:49 am

Lights

Post by detvog »

How many lights can i make in the shader ? More as 8 ?

Sorry for my stupid question, but i'am a newbie with shaders.








Sorry for my bad english...
shadowslair
Posts: 758
Joined: Mon Mar 31, 2008 3:32 pm
Location: Bulgaria

Post by shadowslair »

Well, you have:
- four light position vectors
- four light direction vectors
- the topic title is: "4 light normalmapping for animated meshes [C++/GLSL]"
- the very first post starts with:
"Hi, some new thingy for you. This time I finaly got managed to create a better Normalmapping!!

-4Lights
(...)"
I`m a shader noob too, but all this makes me guess... 4 lights?! :roll:
"Although we walk on the ground and step in the mud... our dreams and endeavors reach the immense skies..."
Post Reply