新規記事の投稿を行うことで、非表示にすることが可能です。
2018年08月13日
《その436》シェーダ(点光源の場合)(3)
シェーダ(点光源の場合)(3)
前回《435》は 下記 (a) の効果を、前々回《434》は 下記 (b) の効果を、それぞれ使って陰影処理をしました。
今回は、(a),(b) 両方の効果を使った陰影処理です。
(a) 点光源からの光は、光源から離れるにつれて広い面積に拡散するので、明るさは減少します。
(b) ある面に光が当たるとき、光が面に垂直に当たるときが最も明るく、斜めに当たる場合は明るさが減少します。
点光源の座標 (0.0, 0.2, 0.7)
左側面と上面には光が当たりませんが、真っ黒にならないように 全体に 0.2 の割合の光を与えています。
点光源の座標 (0.0, 0.2, 0.8)
光源を少し手前に引きましたが、まだ左側面には光が当たりません。
点光源の座標 (0.0, 0.2, 0.9)
左側面にも光が当たるようになりました。右側面より暗いのは (b) の効果によるものです。
点光源の座標 (0.0, 0.2, 1.0)
光源をさらに手前に引きます。(b) の効果による明るさの差が少なくなりました。
点光源の座標 (0.0, 0.2, 1.1)
光源をさらに手前に引きます。
点光源の座標 (0.0, 0.2, 1.2)
光源をさらに手前に引きます。
点光源の座標 (0.0, 0.2, 1.4)
光源をさらに手前に引きます。(a) の効果で全体がかなり暗くなってきています。
点光源の座標 (0.0, 0.2, 1.8)
全体がさらに暗くなりました。
点光源の座標 (0.0, 0.2, 2.5)
全体がさらに暗くなりました。
以下は、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);
}