1

three.js 3d ライブラリには、サンプラーを繰り返しモードに設定し、repeat 属性を好きな値に設定できる便利な機能があります。たとえば、(3, 5) は、このテクスチャが水平方向に 3 回、5 回繰り返されることを意味します。垂直に。しかし、現在 DirectX を使用していますが、この問題に対する適切な解決策が見つかりません。頂点の UV 座標はまだ 0 から 1 の範囲であることに注意してください。HLSL コードを変更したくありません。このためのプログラム可能なソリューションが必要なためです。どうもありがとうございました!

編集:キューブモデルが既にあると仮定します。頂点のテクスチャ座標は 0 から 1 の間です。テクスチャのサンプリングにラップ モードまたはクランプ モードを使用すると、すべて問題ありません。しかし、面の 1 つでテクスチャを繰り返したいので、最初にラップ モードに変更する必要があります。それはもう知ってる。次に、テクスチャ座標の範囲が 0 ~ 3 になるようにモデルを編集する必要があります。モデルを変更しないとどうなりますか? これまでのところ、私は 1 つの方法で出てきました: 変数をピクセル シェーダーに追加する必要があり、これはマップが何回繰り返されるかを表し、サンプリング時にこの係数を乗算して調整します。優雅な解決策ではないと思います...</p>

4

2 に答える 2

2

質問を編集したので、問題に対する別の回答があります。

私が理解したことから、あなたは次のようなUVの顔をしています:

0,1         1,1
 -------------
 |           |
 |           |
 |           |
 -------------
0,0         1,0

ただし、テクスチャを 1 回ではなく 3 回 (たとえば) 繰り返します。(元のモデルを変更せずに)

ここに複数のソリューション:

バッファを更新するときに、それを行うことができます(行う場合):

    D3D11_MAPPED_SUBRESOURCE resource;

    HRESULT hResult = D3DDeviceContext->Map(vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource);
    if(hResult != S_OK) return false;

    YourVertexFormat *ptr=(YourVertexFormat*)resource.pData;
    for(int i=0;i<vertexCount;i++)
    {
        ptr[i] = vertices[i];
        ptr[i].uv.x *= multiplyX; //in your case 3
        ptr[i].uv.y *= multiplyY; //in your case 5 
    }
    D3DDeviceContext->Unmap(vertexBuffer, 0);

ただし、とにかくバッファを更新する必要がない場合は、非常に遅いため、お勧めしません。

より高速な方法は、頂点シェーダーを使用することです。

cbuffer MatrixBuffer
{
    matrix worldMatrix;
    matrix viewMatrix;
    matrix projectionMatrix;
};

struct VertexInputType
{
    float4 position : POSITION0;
    float2 uv : TEXCOORD0;
    // ...
};

struct PixelInputType
{
    float4 position : SV_POSITION;
    float2 uv : TEXCOORD0;
    // ...
};

PixelInputType main(VertexInputType input)
{
    input.position.w = 1.0f;

    PixelInputType output;
    output.position = mul(input.position, worldMatrix);
    output.position = mul(output.position, viewMatrix);
    output.position = mul(output.position, projectionMatrix);

    This is what you basicly need:
    output.uv = input.uv * 3; // 3x3

    Or more advanced:
    output.uv = float2(input.u * 3, input.v * 5);

    // ...

    return output;
}

頂点シェーダー ソリューションをお勧めします。これは高速で、directx ではとにかく頂点シェーダーを使用するため、バッファー更新ソリューションほど高価ではありません...

問題の解決に役立つことを願っています:)

于 2013-07-20T01:20:39.470 に答える
1

基本的に、サンプラーの状態を次のように作成します。

ID3D11SamplerState* m_sampleState;
3D11_SAMPLER_DESC samplerDesc;
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.MipLODBias = 0.0f;
samplerDesc.MaxAnisotropy = 1;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
samplerDesc.BorderColor[0] = 0;
samplerDesc.BorderColor[1] = 0;
samplerDesc.BorderColor[2] = 0;
samplerDesc.BorderColor[3] = 0;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;

// Create the texture sampler state.
result = ifDEVICE->ifDX11->getD3DDevice()->CreateSamplerState(&samplerDesc, &m_sampleState);

シェーダー定数を設定するときは、次のように呼び出します。

ifDEVICE->ifDX11->getD3DDeviceContext()->PSSetSamplers(0, 1, &m_sampleState);

次に、ピクセル シェーダーを次のように記述できます。

Texture2D Texture;
SamplerState SampleType;

...

float4 main(PixelInputType input) : SV_TARGET
{
    float4 textureColor = shaderTexture.Sample(SampleType, input.uv);
    ...
}

それが役立つことを願っています...

于 2013-07-15T16:01:12.277 に答える