シェーダ(点光源の場合)
前回《435》は 下記 (a) の効果を、前々回《434》は 下記 (b) の効果を、それぞれ使って陰影処理をしました。
今回は、 (a) , (b) 両方の効果を使った陰影処理です。
(a) 点光源からの光は、光源から離れるにつれて広い面積に拡散するので、明るさは減少します。
(b) ある面に光が当たるとき、光が面に垂直に当たるときが最も明るく、斜めに当たる場合は明るさが減少します。
点光源の座標 (0.0, 0.2, 0.7)
左側面と上面には光が当たりませんが、真っ黒にならないように 全体に 0.2 の割合の光を与えています。
![add_e081.png](https://fanblogs.jp/cplusplus/file/add_e081.png)
点光源の座標 (0.0, 0.2, 0.8)
光源を少し手前に引きましたが、まだ左側面には光が当たりません。
![add_e082.png](https://fanblogs.jp/cplusplus/file/add_e082.png)
点光源の座標 (0.0, 0.2, 0.9)
左側面にも光が当たるようになりました。右側面より暗いのは (b) の効果によるものです。
![add_e083.png](https://fanblogs.jp/cplusplus/file/add_e083.png)
点光源の座標 (0.0, 0.2, 1.0)
光源をさらに手前に引きます。(b) の効果による明るさの差が少なくなりました。
![add_e084.png](https://fanblogs.jp/cplusplus/file/add_e084.png)
点光源の座標 (0.0, 0.2, 1.1)
光源をさらに手前に引きます。
![add_e085.png](https://fanblogs.jp/cplusplus/file/add_e085.png)
点光源の座標 (0.0, 0.2, 1.2)
光源をさらに手前に引きます。
![add_e086.png](https://fanblogs.jp/cplusplus/file/add_e086.png)
点光源の座標 (0.0, 0.2, 1.4)
光源をさらに手前に引きます。(a) の効果で全体がかなり暗くなってきています。
![add_e087.png](https://fanblogs.jp/cplusplus/file/add_e087.png)
点光源の座標 (0.0, 0.2, 1.8)
全体がさらに暗くなりました。
![add_e088.png](https://fanblogs.jp/cplusplus/file/add_e088.png)
点光源の座標 (0.0, 0.2, 2.5)
全体がさらに暗くなりました。
![add_e089.png](https://fanblogs.jp/cplusplus/file/add_e089.png)
以下は、SamplePixelShader.hlsl です。
// ピクセルシェーダを通じて渡されるピクセルごとのデータ
struct PixelShaderInput
{
float4 pos : SV_POSITION;
float3 pos_ : POSITION;
float3 nrm : NORMAL;
};
// (補間済み)色データのパススルー関数
float4 main(PixelShaderInput input) : SV_TARGET
{
// light処理をしたピクセルの色成分を返します。
float3 light = float3(0.0, 0.2, 2.5); // 点光源の位置
float3 lightDirection = input.pos_ - light; // 光の方向ベクトル
float len = length(lightDirection); // 光の方向ベクトルを正規化(大きさを 1 にします)
// (b) の効果
// 正規化した法線ベクトル と 正規化した光の方向ベクトル のなす角から、
// その点の明るさの程度(0 〜 1)を算出。
float lightMagnitude = saturate(dot(input.nrm, -normalize(lightDirection)));
// (a) の効果
// 物理的には、k は距離の2乗に反比例するべきですが、
// ここでは出力画像が自分のイメージに合うように 式を変形しています。
float k = saturate(1.0f / (1.0f + 0.5f * len + 1.5 * len * len));
// k と lightMagnitude の両方の効果を使用しています。
// 光が当たらない部分にも 0.2 の割合の光を与えて真っ黒にならないようにしています。
// 立方体の色は、RGB が 255*1.0, 255*0.5, 255*0.6 です。
return float4(1.0, 0.5, 0.6, 1.0) * (0.8 * k * lightMagnitude + 0.2f );
}