Directx教程(26) 簡單的光照模型(5)
在前面的工程中,我們都是在vs中實現頂點光照計算,然後再把頂點顏色傳到ps中。本章中我們嘗試fragment光照(或者說叫ps光照),在vs中,我們把頂點在世界坐標系中的法向和位置都直接傳輸到ps中。
// 世界坐標系中的頂點法向.
float3 N = mul(input.normal, (float3x3)worldMatrix);
output.worldnormal= N;
//世界坐標系頂點位置
output.worldposition = worldPosition;
vs光照和ps光照的區別到底是什麽呢?
其實很簡單,對於vs光照來說,我們在vs中對每個頂點計算出了顏色,然後gpu的固定管線,會在ps之前,根據頂點顏色值,實施雙線性差值,計算得出每個pixel的顏色。而對於ps光照,則是會差值每個頂點位置和法向,從而每個pixel都有一個自己相對應的位置和法向,而光照的計算則是在ps中完成。
所以,使用ps光照,它的顏色過度會更柔和,沒有vs光照那樣的粗糙感。
現在我們的ps函數如下:
float4 LightPixelShader(PixelInputType input) : SV_TARGET
{
float3 P = input.worldposition.xyz;
float3 N = normalize(input.worldnormal);
//自發射顏色
//計算環境光
float4 ambient = Ka * globalAmbient;
//計算漫反射光
//用LightDirection就是純平行光
//光源位置減頂點位置,是不考慮衰減的點光源
float3 L = normalize(lightPosition.xyz - P);
float diffuseLight = max(dot(N, L), 0);
float4 diffuse = Kd * lightColor * diffuseLight;
//計算高光
float3 V = normalize(cameraPosition.xyz - P);
float3 H = normalize(L + V);
float specularLight = pow(max(dot(N, H), 0), shininess);
if ( diffuseLight <= 0)
specularLight = 0;
float4 specular = Ks * lightColor * specularLight;
float4 finalcolor = emissive + ambient + diffuse + specular;
return finalcolor;
}
另外lightShaderClass中,我們還要把以前設置的vs材質光照常量緩沖,改成設置ps光照常量常量緩沖。
// 設置光照材質常量緩沖.
deviceContext->PSSetConstantBuffers(bufferNumber, 1, &m_lightmaterialBuffer);
其它的代碼幾乎不用改變,程序執行後的效果如下:
完整的代碼請參考:
工程文件myTutorialD3D11_19
代碼下載:
http://files.cnblogs.com/mikewolf2002/myTutorialD3D11.zip
Directx教程(26) 簡單的光照模型(5)