[fixed]Normal- + Specular-Map Shader shows up flat

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
Ronin
Posts: 116
Joined: Wed Mar 03, 2004 6:23 pm
Location: Germany

[fixed]Normal- + Specular-Map Shader shows up flat

Post by Ronin »

Hi,

We've implemented our own normal + specular shader and it shows up real strange:

Image

Interestingly, when the sun direction in tangent space is _not_ normalized within the pixel shader, the diffuse component shows up smoothly, the specular is still "flat". However, that can't be right.

The mesh is converted to tangents using:

Code: Select all

getMeshManipulator()->createMeshWithTangents(mesh->getMesh(0), false, false, false);
Changing any of the options of creatMesh... does not lead to a different result.

Here's the used shader code, for insight:
Vertex:

Code: Select all

float3 fvSunDir;
float3 fvEyePosition;
float4x4 matWorld;
float4x4 ModelViewProjectionMatrix;
float4x4 rotObjInv;

struct VS_INPUT 
{
   float4 Position : POSITION0;
   float2 Texcoord : TEXCOORD0;
   float3 Normal :   NORMAL0;
   float4 tangent : TEXCOORD1;
   float4 binormal : TEXCOORD2;
};

struct VS_OUTPUT 
{
   float4 Position :        POSITION0;
   float2 Texcoord :        TEXCOORD0;
   float3 ViewDirection :   TEXCOORD1;
   float3 SunTangent :	TEXCOORD2;
};

VS_OUTPUT main( VS_INPUT Input )
{
   VS_OUTPUT Output;

   Output.Position         = mul(Input.Position, ModelViewProjectionMatrix);
   Output.Texcoord         = Input.Texcoord;
   
   float3x3 TBNMatrix = float3x3(
		normalize(Input.tangent.xyz), 
		normalize(Input.binormal.xyz), 
		normalize(Input.Normal));
   Output.SunDirection     = (mul((fvSunDir), rotObjInv));
   Output.SunTangent = (mul(TBNMatrix, Output.SunDirection));
 
   float4 fvObjectPosition = mul( Input.Position, matWorld );
   Output.ViewDirection    = mul(TBNMatrix, fvEyePosition -fvObjectPosition);
  
   return( Output );
}
Pixel:

Code: Select all

float4 fvAmbient;
float4 fvSpecular;
float4 fvDiffuse;
float4 f4SunColor;
float fSunIntensity;
float fSpecularPower;
float fShininess;
sampler2D tex0;   // diffuse
sampler2D tex1;   // spec
sampler2D tex2;   // normal

struct PS_INPUT 
{
    float2 Texcoord :        TEXCOORD0;
    float3 ViewDirection :   TEXCOORD1;
    float3 SunTangent :		 TEXCOORD2;   
};

float4 main( PS_INPUT Input ) : COLOR0
{
    float3 fvViewDirection  = normalize(Input.ViewDirection);	
    float3 fvSunTangent	= normalize(Input.SunTangent);
    
    // Textures
    float4 fvBaseColor      = tex2D(tex0, Input.Texcoord);
    float4 fvSpecularColor  = tex2D(tex1, Input.Texcoord);
    float3 fvNormalMapped = normalize((2.0f * tex2D(tex2, Input.Texcoord).rgb - 1.0f));
   
    // Sun Stuff
    float fNLSun = saturate(dot(fvNormalMapped, fvSunTangent ));
    float fRDotV2 = 0;
    if(fNLSun > 0.f)
    {
        float3 half = normalize((fvSunTangent + fvViewDirection) * 0.5f);
        fRDotV2 = saturate(dot(fvNormalMapped, half));
    }
    
	float my = saturate(fShininess * 0.001 + 0.4);
	float my2 = fSpecularPower * 0.001 + 150;
	float4 spec = fvSpecular + fvSpecularColor;

    float4 fvTotalAmbient   = fvAmbient; 
    float4 fvTotalDiffuse   = fvDiffuse * saturate(fNLSun * fSunIntensity);
    float4 fvTotalSpecular  = fShininess * spec * pow(fRDotV2 * fSunIntensity, fSpecularPower);

    return(saturate(fvBaseColor * (fvTotalAmbient + fvTotalDiffuse) + fvTotalSpecular));
}
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

What type of mesh is it? Does it show up smooth when loaded with getMesh and useing standard SOLID material? Try "false, true, true" or "true, true. true" as parameters for createMeshWithTangents.
Ronin
Posts: 116
Joined: Wed Mar 03, 2004 6:23 pm
Location: Germany

Post by Ronin »

The Mesh is a plain IMesh and it shows up correct, when rendering as EMT_SOLID. Changing the parameters of createMeshWithTangents does not help.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Well, I meant the mesh file format. Did you check with lighting on to see that the normals are really correct?
Ronin
Posts: 116
Joined: Wed Mar 03, 2004 6:23 pm
Location: Germany

Post by Ronin »

We performed some tests using X and OBJ file formats, where both lead to the same problems. The normals are definitely correct, as checked with EMT_SOLID and the lighting flag set to true.
zillion42
Posts: 324
Joined: Wed Aug 29, 2007 12:32 am
Location: Hamburg, Germany

Post by zillion42 »

I know it doesn't add a flying **** but... I'm kind of curious about the outcome of this thread.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Did you check the tangent mesh with EMT_SOLID? That way we can check whether it's a bug in the tangent calculations, or a problem with the shader.
Ronin
Posts: 116
Joined: Wed Mar 03, 2004 6:23 pm
Location: Germany

Post by Ronin »

Whith EMT_SOLID the mesh normals are correct, no matter if generated with tangents or not. The error seems to be in the shader code then...
r2d2
Posts: 211
Joined: Mon Nov 24, 2003 5:22 pm

Post by r2d2 »

If normal mapping shaders show up flat it's (that's my experience) most often either a tangent problem or a problem with this term: float4 fvTotalDiffuse = fvDiffuse * saturate(fNLSun * fSunIntensity);

Try using an irrlicht light and the irrlicht normal mapping material if it still shows up flat, it's a tangent problem if it doesn't show up flat we have to further investigate your shader, at a first glance i can't see a problem in your shadercode.
R2D2's Irrlicht Mods
Messed up with my database so the page is not working at the moment -.-
CPU: Core 2 Quad Q6700RAM: 4096 mb Graphics: Radeon 4850 512mb Sound: on board InternetConnection: DSL
Viz_Fuerte
Posts: 91
Joined: Sun Oct 19, 2008 5:29 pm
Location: Valencia (Spain)
Contact:

Post by Viz_Fuerte »

I happened the same to me.

Guilt was to export the model to a different format from the editor.
I had to change the file format, where you could export the model smoothing.

Fortunately is resolved.

Proof to use, the manipulator mesh of Irrlicht (MeshManipulator), and recalculates the normals. Could work.
MasterD
Posts: 153
Joined: Sun Feb 15, 2004 4:17 pm
Location: Lübeck, Germany
Contact:

Post by MasterD »

Sorry for responding that late, but I got distracted implementing terrain texture splatting :roll:

Unfortunately I was not able to solve this problem. EMT_SOLID / EMT_NORMAL_MAP_SOLID show up flat too (when created with tangents), and smooth with EMT_SOLID (without).

I've visualized the components of the mesh in my shader:

Image

Only when all flags are off, the resulting mesh has smooth normals. If any flag is on, the normals show up flat. The generated tangent/binormal is flat all the time.

Here is the used mesh for reference:
http://www.my rear-engine.de/downloads/delta.x
(Remove the preceding "m" of the domain. I don't want to have webcrawlers getting our mesh too easily)

@Viz_Fuerte: Which mehs format did you use, that helped you and what did you use before?
YASS - Yet another Space Shooter
under Devolpment, see http://yass-engine.de
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

Since your mesh is in x format, does this patch help at all?
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
MasterD
Posts: 153
Joined: Sun Feb 15, 2004 4:17 pm
Location: Lübeck, Germany
Contact:

Post by MasterD »

Very very nice!

Never thought to look for help in the "Remaking irrlicht's fairy" thread :D

The quality is greatly improved, however there are some glitches, which may be similar to those referenced in that thread:

Image

The normals, when visualized, are smooth.

Sadly, blender does not import X - files correctly and I cannot use that program as reference or to look for double vertices. However I opened the mesh with the DirectX Viewer (DX SDK) and the shown tangents are quire similar:

Image

I haven't looked at the code in depth and just wanted to ask:
When the artist defines a given polygon(-area) as flat shaded, what does the code do? Will everything be smoothened or will the smoothing groups be preserved? (I think that's the 3Dsmacks term for that, blender does this using an "edge split" modifier)
YASS - Yet another Space Shooter
under Devolpment, see http://yass-engine.de
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

If you tell the manipulator to keep the normals, they are to be untouched. If you tell it to recalculate the normals, all normals will be smoothed if enabled. At least that's the theory.
Post Reply