2016-03-03 71 views
0

我想在Ogre3D 1.9中爲我的遊戲製作Phong lightning着色器。Phong底紋與定向光造成全白色多邊形

我可以做漫反射並添加一個法線貼圖到一架飛機,但是當我添加鏡面反射部件時,所有東西都會變成明亮的白色。

planes with specular

這裏是沒有鏡面反射分量的圖像

planes without specular

奇怪的是,當我在FX Composer的把完全相同的着色器代碼,它的工作原理

Material in FX Composer

這裏是着色器代碼

float4x4 worldViewProj; 
float4x4 world; 

float4 ambientColor; 

float4x4 worldInverseTranspose; 

float shininess = 8; 

sampler textureSampler : register(s0); 

sampler bumpSampler : register(s1); 

struct VertexShaderInput 
{ 
    float4 position : POSITION0; 
    float3 normal : NORMAL; 
    float2 textureCoord : TEXCOORD0; 
    float3 tangent : TANGENT; 
}; 

struct VertexShaderOutput 
{ 
float4 position : POSITION0; 
    float3 normal : TEXCOORD0; 
    float2 textureCoord : TEXCOORD1; 
    float3 pixelPos : TEXCOORD2; 
    float3 tangent : TEXCOORD3; 
    float3 binormal : TEXCOORD4; 
}; 

VertexShaderOutput VertexShaderFunction(VertexShaderInput input) 
{ 
    VertexShaderOutput output; 

    output.position = mul (worldViewProj,input.position); 

    output.normal = normalize(mul(worldInverseTranspose, input.normal)); 
    output.tangent = normalize(mul(worldInverseTranspose,input.tangent)); 
    output.binormal = normalize(mul(worldInverseTranspose,cross(input.tangent.xyz,input.normal))); 

    output.textureCoord = input.textureCoord; 
    output.pixelPos = output.position.xyz; 

    return output; 
} 

float4 PixelShaderFunction(VertexShaderOutput input, uniform float3 cameraPos, uniform float4 diffLightPos, uniform float lightCorrection) : COLOR0 
{ 

    //normal 
    float3 bump = (tex2D(bumpSampler, input.textureCoord) - (0.5,0.5,0.5)); 
    float3 bumpNormal = normalize(input.normal + (bump.x * input.tangent + bump.y * input.binormal)); 

    //diffuse light 
    float3 diffuseLightDirection = diffLightPos.xyz; 
    float diffuseIntensity = dot(normalize(diffuseLightDirection), bumpNormal); 
    if(diffuseIntensity < lightCorrection) 
     diffuseIntensity = lightCorrection; 

    //specular 
    float3 viewVector = normalize(cameraPos - mul(input.pixelPos, world).xyz); 
    float3 light = normalize(diffuseLightDirection); 
    float3 r = normalize(2 * bumpNormal * diffuseIntensity - light); 
    float3 v = normalize(viewVector); 
    float dotProduct = dot(r,v); 
    float4 specular = max(pow(dotProduct,shininess),0); 

    //texture 
    float4 textureColor = tex2D(textureSampler, input.textureCoord); 
    //clip(textureColor.a - 0.3); 
    textureColor.a = 1; 

    return ambientColor * ambientColor.x + textureColor * diffuseIntensity + specular; 
} 

這裏是我的程序文件,因爲我相信,也許這個問題可能是參數

vertex_program vertexPlanos hlsl 
{ 
    source Planos.hlsl 
    entry_point VertexShaderFunction 
    target vs_3_0 

    default_params 
    { 
     param_named_auto worldViewProj worldviewproj_matrix 
     param_named_auto worldInverseTranspose inverse_transpose_world_matrix 
    } 
} 

fragment_program pixelPlanos hlsl 
{ 
    source Planos.hlsl 
    entry_point PixelShaderFunction 
    target ps_3_0 
    default_params 
    { 
     param_named_auto world world_matrix 
     param_named_auto cameraPos camera_position_object_space 
     param_named_auto ambientColor ambient_light_colour 
     param_named_auto diffLightPos light_position_object_space 0 
     param_named lightCorrection float 0 
    } 
} 

請之一,原諒我這個問題的長度,但我對這個工作周並找不到原因。

回答

0

我注意到你的代碼有一些錯誤。首先,我認爲你的笨手笨腳的正常計算是錯誤的。通常是做:

inline float3 CalculateNormal(float3 bump, float3 normal, float4 tangent) 
{ 
    //transform sample from [0,1] to [-1,1] 
    float3 n = normalize(2.0f * bump - 1.0f); 

    //create Matrix 
    float3 N = normal; //normal of surface 
    float3 T = normalize(tangent.xyz - N * dot(N, tangent.xyz)) * tangent.w; 
    float3 B = cross(N, T); //binormal can be calculated or set from vertex data 
    float3x3 TBN = float3x3(T, B, N); 

    //transform sample to world space 
    return mul(n, TBN); 
} 

然後,你必須在這裏:

float3 diffuseLightDirection = diffLightPos.xyz; 

你寫lightPos,應該是一個光向量。附加通常使用否定光矢量:

float3 diffuseLightDirection = -diffLightVec.xyz; 
float diffuseIntensity = dot(normalize(diffuseLightDirection), bumpNormal); 

優化的還有一兩件事:

normalize(diffuseLightDirection) 

在你的代碼中使用了兩次。在代碼頂部計算它,並在進一步處理^^中使用它。您

最後但並非最不重要的只是一個提示:

float4 specular = max(pow(dotProduct,shininess),0); 

是前人的精力

float4 specular = pow(max(dotProduct,0),shininess); 

,因爲要避免高光如果光從表面背後的到來。如果dotProduct的值始終爲正值,那麼您的鏡面反射項永遠也是正值。

最後,我給你給我的着色代碼照明。它計算環境,漫反射和鏡面反射的術語。

// gLightDirection is normalized 
float3 lightVec = -gLightDirection; 

// normal is the bumbed normal 
float diffuseFac = dot(lightVec, normal.xyz); 

// check if light is coming from behind 
bool isLight = diffuseFac > 0.0f; 

// use reflect function from hlsl, toEye is normalize(camPos - pixelWorldPos); 
float3 v = reflect(-lightVec, normal.xyz); 
float specFac = pow(max(dot(v, toEye), 0), specFactor); 

// startColor or texture color, matA is my ambient material 
float4 ambient = startColor * matA; 

//matD is my diffuse material, isLight is a bool, if it is false, diffuse will be evaluated to 0 
float4 diffuse = startColor * matD * diffuseFac * isLight; 

// matS is my specular material 
float4 spec = specFac * matS * isLight; 

// final color, diffuse and specular are in color of the light, but maybe reduces by some shadows 
float4 color = ambient + ((diffuse + specular) * shadowFactor * gLightColor); 

希望這會對你有所幫助。祝你好運!!!

+0

謝謝,但問題是在Ogre3d(引擎)。在編寫僅返回一個arbritary顏色的着色器時,該對象變爲透明。 –