Thread: Multiplying tangent and bitangent by scale matrix

  1. #1
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071

    Multiplying tangent and bitangent by scale matrix

    In my dot3 rendering, I noticed that on larger objects (such as a floor in a room), the radiation centre of my light seems to be offset from the lights position. The offset distance seems to increase the farther the light position moves from the object centre.

    I did a quick test, and it seems to me, that objects with an XYZ scale of 1 don't have this problem, but scaled objects do (the larger the object, the worse the offset issue). I'm thinking that this is because when I scale an object, the verticies are scaled, but the tangent and bitangent vectors aren't. This would mean that the light on a 20x20x20 cube, is calculated as if the cube is still 1x1x1.

    First of all, is what I think is the problem, actually the problem? And if so, how would you scale tangent and bitangent vectors?
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  2. #2
    Call me AirBronto
    Join Date
    Sep 2004
    Location
    Indianapolis, Indiana
    Posts
    195
    if your verticies scale is updated i dont think there should be a problem with the calculations.

  3. #3
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    Ok, I tried that and it didn't seem to have any effect on the lighting. Although, as far as I know, multipltying the vectors in that way would just increase the length of the vector (producing unnormalized vectors as you said); but translating the vector to the scaled verticies position would keep the vector length, right?

    And since I doubt that would do anything either, what other reasons are there for the offset of the radiation centre?
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Well that is scaling the vectors. That is essentially what the scaling matrix does.

    k 0 0 1
    0 k 0 1
    0 0 k 1
    0 0 0 1

    If you notice this, this is the same as

    Vertex.x*=k,Vertex.y*=k,Vertex.z*=k,Vertex.w*=1.0f ;

    A scaling matrix will scale the vertices or vectors. Translating the vectors prob won't help either since lighting is not computed globally, it's computed locally. Tangent space vectors should not need to be translated.

    Show me a screenshot of this displacement and perhaps I can tell what is going on.

  5. #5
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    The light position is shown by the red diamond, translated slightly to the left. As you can see, the radiation center moved way beyond it.
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  6. #6
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Ok that's definitely strange.

    I'm not sure how you are doing this so I may not be much help.

    The standard illumination setup is this:

    1. Ambient.
    2. Diffuse.
    3. Specular.

    How I do this is derived from several books. First I use vertex shaders to do all the transformation and calculations which are then sent to the pixel shaders. The pixel shaders then alter the color of the output pixel based on the code in the shader.

    First is this tangent space bump mapping or object space bump mapping? There is a difference in that in one you do transform the light vector and in the other you do not.
    More information on this can be found in

    Programming Vertex and Pixel Shaders Charles River Media, pp. 111-16, 2004.

    A book that tells you exactly how to compute the tangent vectors is

    Mathematics for 3D Game Programing and Computer Graphics - Second Edition Charles River Media, pp. 184-189, 2003.

    Following is source code from the first source mentioned for ambient, diffuse, and specular lighting as well as bump mapping.
    I do not have the ability to translate these into Cg. The only thing I can do is run these through fxc.exe and then post the disassembly here.

    The format here will be vertex shader followed by pixel shader.

    Ambient lighting
    Vertex
    Code:
    float4x4 matWorldViewProj;
    
    struct VS_OUTPUT
    {
      float 4 Pos: POSITION;
    };
    
    VS_OUTPUT VS(float4 Pos:POSITION)
    {
      VS_OUTPUT Out=(VS_OUTPUT) 0;
      Out.Pos=mul(Pos,matWorldviewProj);
      return Out;
    }
    Pixel
    Code:
    float 4 PS(): COLOR
    {
      float Aintensity=0.8f;
      float4 Acolor=float4(1.0,0.075,0.075,1.0);
      return Aintensity*Acolor;
    }
    Diffuse lighting
    Vertex
    Code:
    float4x4 matWorldViewProj;
    float4x4 matInvTransposeWorld;
    float4 vecLightDir;
    float4 vDic;
    
    struct VS_OUTPUT
    {
      float4 Pos: POSITION;
      float3 Light: TEXCOORD0;
      float3 Norm: TEXCOORD1;
    };
    
    VS_OUTPUT VS(float4 Pos: POSITION, float3 Normal: NORMAL)
    {
      VS_OUTPUT Out=(VS_OUTPUT) 0;
      Out.Pos=mul(Pos,matWorldViewProj);
    
      Out.Light=normalize(vecLightDir);
    
      Out.Norm=normalize(mul(matInvTransposeWorld,Normal));
      return Out;
    }
    Pixel
    Code:
    float4 PS(float3 Light: TEXCOORD0,float3 Norm: TEXCOORD1) : COLOR
    {
      float4 A={0.f,0.0,0.0,1.0};
    
      return A+vDic*saturate(dot(Light,Normal));
    }
    Specular (pure Phong, not Blinn)
    Vertex
    Code:
    float4x4 matWorldViewProj;
    float4x4 matWorld;
    float4 vecLightDir;
    float4 vecEye;
    float4 vDIC;
    float4 vSpecIC;
    
    struct VS_OUTPUT VS(float4 Pos: POSITION,float 4 Normal:NORMAL)
    {
      VS_OUTPUT Out= (VS_OUTPUT) 0;
    
      Out.Pos=mul(Pos,matWorldViewProj);
    
      Out.Norm=mul(Normal,matWorld);
    
      float4 PosWorld=mul(Pos,matWorld);
    
      Out.Light=vecLightDir;
      Out.View=vecEye-PosWorld;
      return Out;
    }
    Pixel
    Code:
    float4 PS(float3 Light: TEXCOORD0,float3 Norm:TEXCOORD1,float3 View:TEXCOORD2):COLOR
    {
      float4 A={0.1f,.0.0f,0.0f,1.0f};
    
      float3 Normal=normalize(Norm);
      float3 LightDir=normalize(Light);
      float3 ViewDir=normalize(View);
      
      float Diff=saturate((dot(Normal,LightDir));
    
      float3 Reflect=normalize(2*Diff*Normal*LightDir);
    
      float Specular=pow(saturate(dot(Reflect,ViewDir)),8);
    
      return A+vDIC*Diff+vSpecIC*Specular;
    }
    Bump mapping
    Vertex
    Code:
    float4x4 matWorldViewProj;
    float4x4 matWorld;
    float4 vecLightDir;
    float4 vecEye;
    
    struct VS_OUTPUT
    {
      float4 Pos: POSITION;
      float2 Tex:TEXCOORD0;
      float3 Light: TEXCOORD1;
      float3 Vew:TEXCOORD2;
    };
    
    VS_OUTPUT VS(float4 Pos:POSITION,float2 Tex:TEXCOORD0,float3 Normal:NORMAL,float3 Tangent:TANGENT)
    {
      VS_OUTPUT Out= (VS_OUTPUT) 0;
    
      Out.Pos=mul(Pos,matWorldViewProj);
    
      //Transform world space to tangent space
      float3x3 worldToTangentSpace;
      worldToTangentSpace[0]=mul(Tangent,matWorld);
      worldToTangentSpace[1]=mul(cross(Tangent,normal),matWorld);
      worldToTangentSpace[2]=mul(Normal,matWorld);
    
      Out.Tex=Tex;
    
      float4 PosWorld=mul(Pos,matWorld);
      Out.Light=mul(worldToTangentSpace,vecLightDir);
      Out.View=mul(worldToTangentSpace,vecEye*PosWorld);
    
      return Out;
    }
    Pixel
    Code:
    texture ColorMap;
    sampler ColorMapSampler=sampler_state
    {
      Texture=<ColorMap>;
      MinFilter=Linear;     
      MagFilter=Linear;   
      MipFilter=Linear;
      AddressU=Clamp;
      AddressV=Clamp;
    };
    
    texture BumpMap;
    sampler BumpMapSampler=sampler_state
    {
      Texture=<BumpMap>;
      MinFilter=Linear;
      MagFilter=Linear;
      MipFilter=Linear;
      AddressU=Clamp;
      AddressV=Clamp;
    };
    
    float4 PS(float2 Tex:TEXCOORD0,float3 Light:TEXCOORD1,float3 View:TEXCOORD2):COLOR
    {
      float4 Color=tex2D(ColorMapSampler,Tex);
    
      float3 Normal=(2*(tex2D(BumpMapSampler,Tex)))-1.0;
      float3 LightDir=normalize(Light);
      float3 ViewDir=normalize(View);
    
      float Diffuse=saturate(dot(Normal,LightDir));
    
      float3 Reflect=normalize(2*Diffuse*Normal-LightDir);
     
      float Specular=min(pow(saturate(dot(Reflect,ViewDir)),3),Color.w);
    
      return 0.2*Color+Color*Diffuse+Specular;
    }
    Perhaps the transform from world space to tangent space may help.

  7. #7
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    I'm doing all the calculations in tangent space already. I'm not using shaders at the moment(I've had alot of trouble getting it working properly with shaders). I'm using OpenGL dot3 extensions, so the lighting is should be standard(it's basicly like doing bumpmapping in fixed-function mode).

    It seems that the only way to get this working correctly, is to try and get my shader bumpmapping working correctly. However, that would mean the fallback for cards that don't support OpenGL 2.0 still wouldn't work properly....which means I need to get both working..argh.
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

Popular pages Recent additions subscribe to a feed