1. 程式人生 > >Directx教程(26) 簡單的光照模型(5)

Directx教程(26) 簡單的光照模型(5)

nes 出了 工程文件 add con 完整 pixel itl world

原文:Directx教程(26) 簡單的光照模型(5)

    在前面的工程中,我們都是在vs中實現頂點光照計算,然後再把頂點顏色傳到ps中。本章中我們嘗試fragment光照(或者說叫ps光照),在vs中,我們把頂點在世界坐標系中的法向和位置都直接傳輸到ps中。

    // 世界坐標系中的頂點法向.
    float3 N = mul(input.normal, (float3x3)worldMatrix);
    output.worldnormal= N;
   
    //世界坐標系頂點位置

    worldPosition = mul(input.position, worldMatrix);
    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 emissive = Ke;
   
    //計算環境光
    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)