前提・実現したいこと
Direct3D11でポイントライトを実装したのですが、減衰処理ができておらず、ポイントライトがくっきり出てしまうので直したいです。
現状
理想
該当のソースコード
hlsl
1// ピクセルシェーダ 2 3// グローバル 4cbuffer global : register(b0) { 5 matrix g_mtxWVP; // ワールド×ビュー×射影行列 6 matrix g_mtxWorld; // ワールド行列 7 matrix g_mtxTexture; // テクスチャ行列 8 float4 g_vCameraPos; // 視点座標(ワールド空間) 9 float4 g_vLightDir; // 光源方向(ワールド空間) 10 float4 g_vLightAmbient; // 環境光 11 float4 g_vLightDiffuse; // 拡散光 12 float4 g_vLightSpecular; // 鏡面反射光 13 14 float4 g_vLightPos; // ライト位置 15 float g_vLightRange; // ライト範囲 16 float4 g_vLightAtt; // ライト減衰 17 float4 g_vLightColor; // ライトの色 18}; 19 20// マテリアル 21cbuffer global2 : register(b1) { 22 float4 g_Ambient; // 環境色 23 float4 g_Diffuse; // 拡散色+アルファ 24 float4 g_Specular; // 鏡面反射色+強度 25 float4 g_Emissive; // 発光色 26 float4 g_Flags; // 拡散色テクスチャ有無, 発光色テクスチャ有無, 透過テクスチャ有無 27}; 28 29Texture2D g_texture : register(t0); // テクスチャ 30Texture2D g_texEmissive : register(t1); // 発光テクスチャ 31Texture2D g_texTransparent : register(t2); // 透過テクスチャ 32Texture2D g_texSpecular : register(t3); // 鏡面反射テクスチャ 33SamplerState g_sampler : register(s0); // サンプラ 34 35// パラメータ 36struct VS_OUTPUT { 37 float4 Pos : SV_Position; 38 float2 Tex : TEXCOORD0; 39 float3 Normal : TEXCOORD1; 40 float3 PosForPS : TEXCOORD2; 41 42 float4 WorldPos : POSITION; 43}; 44 45// ピクセルシェーダ 46float4 main(VS_OUTPUT input) : SV_Target0 47{ 48 float3 Diff = g_Diffuse.rgb; 49 50 // ライトの色の設定 51 //Diff *= g_vLightColor; 52 53 float Alpha = g_Diffuse.a; 54 55 // モデルの透明度設定 56 //Alpha *= float(0.8); 57 58 if (g_Flags.x != 0.0f) { // テクスチャ有無 59 float4 TexDiff = g_texture.Sample(g_sampler, input.Tex); 60 Diff *= TexDiff.rgb; 61 Alpha *= TexDiff.a; 62 } 63 if (g_Flags.z != 0.0f) { // テクスチャ有無 64 float4 TexTran = g_texTransparent.Sample(g_sampler, input.Tex); 65 Alpha *= (TexTran.r * TexTran.g * TexTran.b * TexTran.a); 66 } 67 if (Alpha <= 0.0f) discard; // 完全透明なら描画しない 68 float3 Spec = g_Specular.rgb; 69 if (g_Flags.w != 0.0f) { // テクスチャ有無 70 float4 TexSpec = g_texSpecular.Sample(g_sampler, input.Tex); 71 Spec *= TexSpec.rgb; 72 } 73 74 float3 Emis = g_Emissive.rgb; 75 if (g_Flags.y != 0.0f) { // テクスチャ有無 76 float4 TexEmis = g_texEmissive.Sample(g_sampler, input.Tex); 77 Emis *= (TexEmis.rgb * TexEmis.a); 78 } 79 Diff += Emis; 80 81 // ここからポイントライト 82 //点光源の方向 83 float3 lightToPixelVec = g_vLightPos - input.WorldPos; 84 // 光源位置と画素位置の距離を求める 85 float d = length(lightToPixelVec); 86 87 // https://docs.microsoft.com/ja-jp/windows/uwp/graphics-concepts/mathematics-of-lighting 88 float3 L = normalize(g_vLightPos - input.WorldPos); // 光源へのベクトル 89 float3 N = normalize(input.Normal); // 法線ベクトル 90 float3 V = normalize(g_vCameraPos - input.WorldPos); 91 float3 H = normalize(L + V); // ハーフベクトル 92 Diff = g_vLightAmbient.rgb * g_Ambient.rgb + 93 g_vLightDiffuse.rgb * Diff * saturate(dot(L, N)); // 拡散色 + 環境色 94 Spec = Spec * g_vLightSpecular.rgb * 95 pow(saturate(dot(N, H)), g_Specular.a); // 鏡面反射色 96 Diff += Spec; 97 98 99 float3 finalAmbient = Diff * g_Ambient; //全体の明るさ 100 101 // ポイントライトの範囲制限 102 if (d > g_vLightRange) 103 return float4(finalAmbient, Alpha); 104 105 lightToPixelVec /= d; 106 107 float howMuchLight = dot(lightToPixelVec, N); 108 109 float3 finalColor = Diff; 110 111 //影が変化した 112 if (howMuchLight > 0.0f) 113 { 114 // ピクセルのfinalColorに光を追加する 115 finalColor += howMuchLight * Diff * g_vLightDiffuse; 116 // 光のフォールオフ係数を計算する 117 // ここがうまくいってない 118 // ここで減衰したい 119 finalColor /= g_vLightAtt.x + (g_vLightAtt.y * d) + (g_vLightAtt.z * (d * d)); 120 } 121 122 finalColor = saturate(finalColor + finalAmbient); 123 124 return float4(finalColor, Alpha); 125}
補足情報(FW/ツールのバージョンなど)
Windows10
Visual Studio 2019 Com
DirectX11
あなたの回答
tips
プレビュー