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

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

新規登録して質問してみよう
ただいま回答率
85.53%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

DirectX

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

Q&A

1回答

1542閲覧

Direct3D11でマルチテクスチャを実装したい

futonmin

総合スコア33

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

DirectX

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

0グッド

0クリップ

投稿2022/02/06 08:45

編集2022/02/14 02:50

前提・実現したいこと

DirectX11,C/C++でマルチテクスチャを実装したいです。
ポリゴンに1枚のテクスチャを貼るところまではできています。
2枚のテクスチャをブレンドしようとすると、最初に貼ったテクスチャが上書きされてしまいます。

実現したいこと
イメージ説明

現状
イメージ説明

該当のソースコード

c++

1// 初期化 2HRESULT InitSampleShader(void) 3{ 4 ID3D11Device* pDevice = GetDevice(); 5 HRESULT hr; 6 HWND hWnd = GetMainWnd(); 7 8 9 // シェーダ初期化 10 static const D3D11_INPUT_ELEMENT_DESC layout[] = { 11 D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, 12 {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, 13 {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, 14 {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, 15 {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, 16 }; 17 hr = LoadShader("VertexShader", "PixelShader", &g_pVertexShader, &g_pInputLayout, &g_pPixelShader, layout, _countof(layout)); 18 if (FAILED(hr)) { 19 return hr; 20 } 21 22 // 定数バッファ生成 23 D3D11_BUFFER_DESC bd; 24 ZeroMemory(&bd, sizeof(bd)); 25 bd.Usage = D3D11_USAGE_DEFAULT; 26 bd.ByteWidth = sizeof(SHADER_GLOBAL); 27 bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; 28 bd.CPUAccessFlags = 0; 29 hr = pDevice->CreateBuffer(&bd, nullptr, &g_pConstantBuffer[0]); 30 if (FAILED(hr)) return hr; 31 bd.ByteWidth = sizeof(SHADER_GLOBAL2); 32 hr = pDevice->CreateBuffer(&bd, nullptr, &g_pConstantBuffer[1]); 33 if (FAILED(hr)) return hr; 34 35 // テクスチャ サンプラ生成 36 D3D11_SAMPLER_DESC sd; 37 ZeroMemory(&sd, sizeof(sd)); 38 sd.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; 39 sd.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; 40 sd.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; 41 sd.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; 42 hr = pDevice->CreateSamplerState(&sd, &g_pSamplerState); 43 if (FAILED(hr)) { 44 return hr; 45 } 46 47 // 位置回転拡大率の初期化 48 g_mesh.pos = XMFLOAT3(0.0f, 0.0f, 0.0f); 49 g_mesh.rot = XMFLOAT3(0.0f, 0.0f, 0.0f); 50 51 // マテリアルの初期設定 52 g_material.Diffuse = M_DIFFUSE; 53 g_material.Ambient = M_AMBIENT; 54 g_material.Specular = M_SPECULAR; 55 g_material.Power = 1.0f; 56 g_material.Emissive = M_EMISSIVE; 57 58 // 1枚目のテクスチャの読み込み 59 hr = CreateTextureFromFile(pDevice, 60 TEXTURE_FIELD, 61 &g_mesh.pTexture); 62 if (FAILED(hr)) 63 { 64 MessageBox(hWnd, 65 _T("地面テクスチャ読み込みエラー"), 66 _T("Error"), 67 MB_OK | MB_ICONSTOP); 68 return hr; 69 } 70 XMStoreFloat4x4(&g_mesh.mtxTexture, 71 XMMatrixIdentity()); 72 73 74 // 2枚目のテクスチャの読み込み 75 // おそらくここで上書きしてしまっている。 76 hr = CreateTextureFromFile(pDevice, 77 TEXTURE_BAMP1, 78 &g_mesh.pTexture); 79 if (FAILED(hr)) 80 { 81 MessageBox(hWnd, 82 _T("地面テクスチャ読み込みエラー"), 83 _T("Error"), 84 MB_OK | MB_ICONSTOP); 85 return hr; 86 } 87 XMStoreFloat4x4(&g_mesh.mtxTexture, 88 XMMatrixIdentity()); 89 90 // 91 92 VERTEX_3D vertexWk[NUM_VERTEX]; //作業用頂点情報 93 int indexWk[NUM_VERTEX]; //作業用インデックス 94 95 // 頂点座標の設定 96 g_mesh.nNumVertex = NUM_VERTEX; 97 vertexWk[0].vtx = XMFLOAT3(-SIZE_X, 0.0f, SIZE_Z); 98 vertexWk[1].vtx = XMFLOAT3(SIZE_X, 0.0f, SIZE_Z); 99 vertexWk[2].vtx = XMFLOAT3(-SIZE_X, 0.0f, -SIZE_Z); 100 vertexWk[3].vtx = XMFLOAT3(SIZE_X, 0.0f, -SIZE_Z); 101 102 // ディフューズの設定 103 vertexWk[0].diffuse = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f); 104 vertexWk[1].diffuse = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f); 105 vertexWk[2].diffuse = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f); 106 vertexWk[3].diffuse = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f); 107 108 // 法線ベクトルの設定 109 vertexWk[0].nor = XMFLOAT3(0.0f, 1.0f, 0.0f); 110 vertexWk[1].nor = XMFLOAT3(0.0f, 1.0f, 0.0f); 111 vertexWk[2].nor = XMFLOAT3(0.0f, 1.0f, 0.0f); 112 vertexWk[3].nor = XMFLOAT3(0.0f, 1.0f, 0.0f); 113 114 // テクスチャ座標の設定 115 vertexWk[0].tex = XMFLOAT2(0.0f, 0.0f); 116 vertexWk[1].tex = XMFLOAT2(1.0f, 0.0f); 117 vertexWk[2].tex = XMFLOAT2(0.0f, 1.0f); 118 vertexWk[3].tex = XMFLOAT2(1.0f, 1.0f); 119 120 // インデックス配列の設定 121 g_mesh.nNumIndex = NUM_VERTEX; 122 indexWk[0] = 0; 123 indexWk[1] = 1; 124 indexWk[2] = 2; 125 indexWk[3] = 3; 126 127 g_mesh.fAlpha = 1.0f; 128 for (int i = 0; i < g_mesh.nNumVertex; ++i) { 129 if (g_mesh.fAlpha > vertexWk[i].diffuse.w) { 130 g_mesh.fAlpha = vertexWk[i].diffuse.w; 131 } 132 } 133 134 D3D11_BUFFER_DESC vbd; 135 ZeroMemory(&vbd, sizeof(vbd)); 136 vbd.Usage = D3D11_USAGE_DYNAMIC; 137 vbd.ByteWidth = sizeof(VERTEX_3D) * g_mesh.nNumVertex; 138 vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER; 139 vbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 140 vbd.MiscFlags = 0; 141 D3D11_SUBRESOURCE_DATA initData; 142 ZeroMemory(&initData, sizeof(initData)); 143 initData.pSysMem = vertexWk; 144 hr = pDevice->CreateBuffer(&vbd, &initData, &g_mesh.pVertexBuffer); 145 if (FAILED(hr)) { 146 return hr; 147 } 148 149 CD3D11_BUFFER_DESC ibd(g_mesh.nNumIndex * sizeof(int), D3D11_BIND_INDEX_BUFFER); 150 ZeroMemory(&initData, sizeof(initData)); 151 initData.pSysMem = indexWk; 152 hr = pDevice->CreateBuffer(&ibd, &initData, &g_mesh.pIndexBuffer); 153 154 return hr; 155}

hlsl

1// 頂点シェーダ 2 3// グローバル 4cbuffer global : register(b0) { 5 matrix g_mWVP; 6 matrix g_mWorld; 7 matrix g_mTexture; 8}; 9 10// パラメータ 11struct VS_INPUT { 12 float3 Position : POSITION; 13 float3 Normal : NORMAL; 14 float2 TexCoord : TEXCOORD0; 15 float4 Diffuse : COLOR0; 16}; 17 18struct VS_OUTPUT { 19 float4 Position : SV_Position; 20 float3 Pos4PS : TEXCOORD0; 21 float3 Normal : TEXCOORD1; 22 float2 TexCoord : TEXCOORD2; 23 float4 Diffuse : COLOR0; 24}; 25 26VS_OUTPUT main(VS_INPUT input) 27{ 28 VS_OUTPUT output; 29 float4 P = float4(input.Position, 1.0f); 30 output.Position = mul(P, g_mWVP); 31 output.Pos4PS = mul(P, g_mWorld).xyz; 32 output.Normal = mul(float4(input.Normal, 0.0f), g_mWorld).xyz; 33 output.TexCoord = mul(float4(input.TexCoord, 0.0f, 1.0f), g_mTexture).xy; 34 output.Diffuse = input.Diffuse; 35 return output; 36}

hlsl

1// ピクセルシェーダ 2 3// グローバル 4cbuffer global : register(b1) { 5 float4 g_vEye; // 視点座標 6 // 光源 7 float4 g_vLightDir; // 光源方向 8 float4 g_vLa; // 環境光 9 float4 g_vLd; // 拡散反射光 10 float4 g_vLs; // 鏡面反射光 11 // マテリアル 12 float4 g_vKa; // アンビエント色(+テクスチャ有無) 13 float4 g_vKd; // ディフューズ色 14 float4 g_vKs; // スペキュラ色(+スペキュラ強度) 15 float4 g_vKe; // エミッシブ色 16}; 17 18// パラメータ 19struct VS_OUTPUT { 20 float4 Position : SV_Position; 21 float3 Pos4PS : TEXCOORD0; 22 float3 Normal : TEXCOORD1; 23 float2 TexCoord : TEXCOORD2; 24 float4 Diffuse : COLOR0; 25}; 26 27Texture2D g_texture[2] : register(t0); // テクスチャ // ここで2枚のテクスチャを用意 28SamplerState g_sampler : register(s0); // サンプラ 29 30float4 main(VS_OUTPUT input) : SV_Target0 31{ 32 float3 Diff = input.Diffuse.rgb * g_vKd.rgb; 33 float Alpha = input.Diffuse.a * g_vKd.a; 34 if (g_vKa.a > 0.0f) { 35 // テクスチャ有 36 float4 vTd = g_texture[0].Sample(g_sampler, input.TexCoord); 37 float4 vTd1 = g_texture[1].Sample(g_sampler, input.TexCoord); 38 39 //Diff *= vTd.rgb; 40 //Alpha *= vTd.a; 41 42 // ここでブレンドしてるつもり 43 Diff *= (vTd.rgb * vTd1.rgb * 2.0); 44 Alpha *= (vTd.a * vTd1.a * 2.0); 45 } 46 //clip(Alpha - 0.0001f); 47 if (Alpha <= 0.0f) discard; 48 49 if (g_vLightDir.x != 0.0f || g_vLightDir.y != 0.0f || g_vLightDir.z != 0.0f) { 50 // 光源有効 51 float3 L = normalize(-g_vLightDir.xyz); // 光源へのベクトル 52 float3 N = normalize(input.Normal); // 法線ベクトル 53 float3 V = normalize(g_vEye.xyz - input.Pos4PS); // 視点へのベクトル 54 float3 H = normalize(L + V); // ハーフベクトル 55 Diff = g_vLa.rgb * g_vKa.rgb + g_vLd.rgb * 56 Diff * saturate(dot(L, N)); // 拡散色 + 環境色 57 float3 Spec = g_vLs.rgb * g_vKs.rgb * 58 pow(saturate(dot(N, H)), g_vKs.a); // 鏡面反射色 59 Diff += Spec; 60 } 61 62 Diff += g_vKe.rgb; 63 64 return float4(Diff, Alpha); 65} 66

試したこと

http://dioltista.blogspot.com/2019/05/c-directx11_29.html

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

Windows10
DirectX11
Visual Studio2019 Community

文字数オーバーで描画処理のソースが載せられませんでした。
参考にした記事を見るあたり、あまり関係ないと思うのですが要望があれば別の記事を作りうpします。

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

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

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

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

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

guest

回答1

0

C++/HLSL

1コード 2struct PS_IN 3{ 4 float4 pos : SV_POSITION; 5 float2 uv : TEXCOORD0; 6}; 7 8Texture2D baseTex:register(t0);// 通常のテクスチャ 9Texture2D scarTex:register(t1);// 貼り合わせのテクスチャ 10 11SamplerState samp : register(s0);// テクスチャの繰り返し設定 12 13float4 main(PS_IN pin):SV_TARGET 14{ 15 float4 color = float4(1.0f,1.0f,1.0f,1.0f); 16 17 // 通常の貼り付け 18 color = baseTex.Sample(samp, pin.uv); 19 20 // テクスチャの重ね合わせ 21 //color=scarTex.Sample(samp,pin.uv);// 別のデータで上書き 22 //color += scarTex.Sample(samp, pin.uv);// 加算合成 23 // 正しく重ね合わせを行うためには、自前でアルファブレンドを行う 24 // アルファブレンド=dst.rgb*(1.0f - src a) + src.rgb * src.a; 25 float4 blendColor = scarTex.Sample(samp, pin.uv); 26 color.rgb = color.rgb*(1.0f - blendColor.a) + blendColor.rgb * blendColor.a; 27 28 color.a = 1.0f; 29 30 return color; 31}

このように式を立てれば実現できると思います。

投稿2022/02/13 17:50

isimasa

総合スコア291

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

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

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

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

ただいまの回答率
85.53%

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

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

質問する

関連した質問