質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
HLSL

HLSLは、米マイクロソフト社によって開発された Direct3D APIで使われるプロプライエタリなシェーディング言語です。

DirectX

DirectX(ダイレクトエックス)は、 マイクロソフトが開発したゲーム・マルチメディア処理用のAPIの集合です。

Q&A

0回答

1179閲覧

ポイントライト実装時の影の付き方がうまくいかないので直したい(DirectX11,HLSL)

futonmin

総合スコア33

HLSL

HLSLは、米マイクロソフト社によって開発された Direct3D APIで使われるプロプライエタリなシェーディング言語です。

DirectX

DirectX(ダイレクトエックス)は、 マイクロソフトが開発したゲーム・マルチメディア処理用のAPIの集合です。

0グッド

0クリップ

投稿2022/02/14 07:12

編集2022/02/16 18:54

前提・実現したいこと

DirectX11でディレクションライトからポイントライトを実装していて、ポイントライトは実装できたが影の付き方がディレクションライトのままなので、影の付き方を直したいです。

現状
イメージ説明

ポイントライト実装のイメージ
イメージ説明

該当のソースコード

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}; 18 19// マテリアル 20cbuffer global2 : register(b1) { 21 float4 g_Ambient; // 環境色 22 float4 g_Diffuse; // 拡散色+アルファ 23 float4 g_Specular; // 鏡面反射色+強度 24 float4 g_Emissive; // 発光色 25 float4 g_Flags; // 拡散色テクスチャ有無, 発光色テクスチャ有無, 透過テクスチャ有無 26}; 27 28Texture2D g_texture : register(t0); // テクスチャ 29Texture2D g_texEmissive : register(t1); // 発光テクスチャ 30Texture2D g_texTransparent : register(t2); // 透過テクスチャ 31Texture2D g_texSpecular : register(t3); // 鏡面反射テクスチャ 32SamplerState g_sampler : register(s0); // サンプラ 33 34// パラメータ 35struct VS_OUTPUT { 36 float4 Pos : SV_Position; 37 float2 Tex : TEXCOORD0; 38 float3 Normal : TEXCOORD1; 39 float3 PosForPS : TEXCOORD2; 40 41 float4 WorldPos : POSITION; 42}; 43 44float4 main(VS_OUTPUT input) : SV_Target0 45{ 46 float3 Diff = g_Diffuse.rgb; 47 48 float Alpha = g_Diffuse.a; 49 50 // ここは関係ない処理だと思っていますが書き残しておきます。 51 if (g_Flags.x != 0.0f) { // テクスチャ有無 52 float4 TexDiff = g_texture.Sample(g_sampler, input.Tex); 53 Diff *= TexDiff.rgb; 54 Alpha *= TexDiff.a; 55 } 56 if (g_Flags.z != 0.0f) { // テクスチャ有無 57 float4 TexTran = g_texTransparent.Sample(g_sampler, input.Tex); 58 Alpha *= (TexTran.r * TexTran.g * TexTran.b * TexTran.a); 59 } 60 if (Alpha <= 0.0f) discard; // 完全透明なら描画しない 61 float3 Spec = g_Specular.rgb; 62 if (g_Flags.w != 0.0f) { // テクスチャ有無 63 float4 TexSpec = g_texSpecular.Sample(g_sampler, input.Tex); 64 Spec *= TexSpec.rgb; 65 } 66 67 // ここから 68 float3 lightToPixelVec = g_vLightPos - input.WorldPos; 69 // 光源位置と画素位置の距離を求める 70 float d = length(lightToPixelVec); 71 72 // ここがディレクションライトの処理のまま 73 if (g_vLightDir.x != 0.0f || g_vLightDir.y != 0.0f || g_vLightDir.z != 0.0f) { 74 // ポイントライトは光源ベクトルがいらないが変数Lを消すとハーフベクトルの計算に何を置き換えればいいのかわからない 75 float3 L = normalize(-g_vLightDir.xyz); // 光源へのベクトル 76 // 法線ベクトルはこのままでいいと思います。 77 float3 N = normalize(input.Normal); // 法線ベクトル 78 // 視点ベクトルの計算も変える必要があるがわからない 79 float3 V = normalize(g_vCameraPos.xyz - input.PosForPS);// 視点へのベクトル 80 // 変数Lを置き換えなければいけないが何に置き換えればいいのかわからない 81 float3 H = normalize(L + V); // ハーフベクトル 82 Diff = g_vLightAmbient.rgb * g_Ambient.rgb + 83 g_vLightDiffuse.rgb * Diff * saturate(dot(L, N)); // 拡散色 + 環境色 84 Spec = Spec * g_vLightSpecular.rgb * 85 pow(saturate(dot(N, H)), g_Specular.a); // 鏡面反射色 86 Diff += Spec; 87 } 88 89 // ここは関係ない処理だと思っていますが書き残しておきます。 90 float3 Emis = g_Emissive.rgb; 91 if (g_Flags.y != 0.0f) { // テクスチャ有無 92 float4 TexEmis = g_texEmissive.Sample(g_sampler, input.Tex); 93 Emis *= (TexEmis.rgb * TexEmis.a); 94 } 95 Diff += Emis; 96 97 // ここから 98 // ここからはポイントライトの処理ですが、ここはうまくいっていると思います。 99 float3 finalAmbient = Diff * g_Ambient; 100 if (d > g_vLightRange) 101 return float4(finalAmbient, Alpha); 102 lightToPixelVec /= d; 103 float howMuchLight = dot(lightToPixelVec, input.Normal); 104 float3 finalColor = Diff; 105 if (howMuchLight > 0.0f) 106 { 107 // ピクセルのfinalColorに光を追加する 108 finalColor += howMuchLight * Diff * g_vLightDiffuse; 109 // 光のフォールオフ係数を計算する 110 finalColor /= g_vLightAtt[0] + (g_vLightAtt[1] * d) + (g_vLightAtt[2] * (d * d)); 111 } 112 113 finalColor = saturate(finalColor + finalAmbient); 114 115 //return float4(Diff, Alpha); 116 return float4(finalColor, Alpha); 117}

試したこと

// ポイントライトの記事
https://www.braynzarsoft.net/viewtutorial/q16390-17-point-lights
// ライトの種類の記事
https://www.braynzarsoft.net/viewtutorial/q16390-simple-lighting

補足情報(FW/ツールのバージョンなど)

DirectX11
Visual Studio 2019 Community
Windows10

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問