シェーダ(点光源の場合) (1)
点光源とは、発光部の大きさが点とみなせるほど小さく、かつ被照射面との距離が比較的近い 光源のことです。今回のプログラムでは、光源を実際に点として考えます。
(b) ある面に光が当たるとき、光が面に垂直に当たるときが最も明るく、斜めに当たる場合は明るさが減少します。
(a)の効果は、光源と面との距離を用いることで、比較的 簡単に処理することができます。
(b)の効果は、光の向きと面の法線の向きを考えることで、処理することができます。
今回は、(b) の効果のみを扱います。
(a) の効果については、次回に見てみます。
今回も、これまでと同じ立方体を使います。
あらためて、立方体の各頂点の座標を確認しておきます。原点が立方体の中心になっています。
![add_e061.png](https://fanblogs.jp/cplusplus/file/add_e061.png)
次に、いくつかの出力結果を示しておきます。
点光源の座標が (0.0, 0.8, 0.0) のときの様子です(真上からの照射です)。
光が当たらない面は真っ黒になっています。
![add_e062.png](https://fanblogs.jp/cplusplus/file/add_e062.png)
![add_e063.png](https://fanblogs.jp/cplusplus/file/add_e063.png)
点光源の座標が (0.0, 1.5, 2.0) のときの様子です(手前やや上からの照射です)。
![add_e064.png](https://fanblogs.jp/cplusplus/file/add_e064.png)
![add_e065.png](https://fanblogs.jp/cplusplus/file/add_e065.png)
点光源の座標が (0.0, 0.0, 1.0) のときの様子です(正面からの照射です)。
![add_e066.png](https://fanblogs.jp/cplusplus/file/add_e066.png)
![add_e067.png](https://fanblogs.jp/cplusplus/file/add_e067.png)
点光源の座標が (0.6, 0.7, 0.7) のときの様子です(手前右上からの照射です)。
![add_e068.png](https://fanblogs.jp/cplusplus/file/add_e068.png)
![add_e069.png](https://fanblogs.jp/cplusplus/file/add_e069.png)
以下は、SampleVertexShader.hlsl のコードです。
// ジオメトリを作成するために 3つの基本的な列優先のマトリックスを保存する定数バッファ
cbuffer ModelViewProjectionConstantBuffer : register(b0)
{
matrix model;
matrix view;
matrix projection;
};
// 頂点シェーダへの入力として使用する頂点ごとのデータ
struct VertexShaderInput
{
float3 pos : POSITION;
float3 nrm : NORMAL;
};
// ピクセルシェーダを通じて渡されるピクセルごとのデータ
struct PixelShaderInput
{
float4 pos : SV_POSITION; // レンダリングパイプラインで加工済みの点座標
float3 pos_ : POSITION; // 未処理のままの点座標
float3 nrm : NORMAL;
};
// GPU で頂点処理を行うための簡単なシェーダ
PixelShaderInput main(VertexShaderInput input)
{
PixelShaderInput output;
float4 pos_ = float4(input.pos, 1.0f);
pos_ = mul(pos_, model);
output.pos_ = pos_.xyz;
float4 pos = float4(input.pos, 1.0f);
pos = mul(pos, model);
pos = mul(pos, view);
pos = mul(pos, projection);
output.pos = pos;
float4 nrm = float4(normalize(input.nrm), 0.0f);
nrm = mul(nrm, model);
output.nrm = normalize(nrm.xyz);
return output;
}
以下は、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.6, 0.7, 0.7); // 点光源の位置
float3 lightDirection = input.pos_ - light; // 光の方向ベクトル
float len = length(lightDirection); // 光の方向ベクトルを正規化(大きさを 1 にします)
// 正規化した法線ベクトル と 正規化した光の方向ベクトル のなす角から、その点の明るさの程度(0 〜 1)を算出。
float lightMagnitude = saturate(dot(input.nrm, -normalize(lightDirection)));
return float4(0,1,0,0) * lightMagnitude; // 緑色(R,G,B が 0,1,0)に明るさの程度を乗じます。
}