Bagikan melalui


Atur Status Efek (Direct3D 11)

Beberapa konstanta efek hanya perlu diinisialisasi. Setelah diinisialisasi, status efek diatur ke perangkat untuk seluruh perulangan render. Variabel lain perlu diperbarui setiap kali perulangan render dipanggil. Kode dasar untuk mengatur variabel efek ditunjukkan di bawah ini, untuk setiap jenis variabel.

Efek merangkum semua status render yang diperlukan untuk melakukan rendering pass. Dalam hal API, ada tiga jenis status yang dienkapulatasi dalam efek.

Status Konstanta

Pertama, deklarasikan variabel dalam efek menggunakan jenis data HLSL.

//--------------------------------------------------------------------------------------
// Global variables
//--------------------------------------------------------------------------------------
float4 g_MaterialAmbientColor;      // Material's ambient color
float4 g_MaterialDiffuseColor;      // Material's diffuse color
int g_nNumLights;

float3 g_LightDir[3];               // Light's direction in world space
float4 g_LightDiffuse[3];           // Light's diffuse color
float4 g_LightAmbient;              // Light's ambient color

Texture2D g_MeshTexture;            // Color texture for mesh

float    g_fTime;                   // App's time in seconds
float4x4 g_mWorld;                  // World matrix for object
float4x4 g_mWorldViewProjection;    // World * View * Projection matrix

Kedua, deklarasikan variabel dalam aplikasi yang dapat diatur oleh aplikasi, dan kemudian akan memperbarui variabel efek.

           
    D3DXMATRIX  mWorldViewProjection;
    D3DXVECTOR3 vLightDir[MAX_LIGHTS];
    D3DXVECTOR4 vLightDiffuse[MAX_LIGHTS];
    D3DXMATRIX  mWorld;
    D3DXMATRIX  mView;
    D3DXMATRIX  mProj;

    // Get the projection and view matrix from the camera class
    mWorld = g_mCenterMesh * *g_Camera.GetWorldMatrix();
    mProj = *g_Camera.GetProjMatrix();
    mView = *g_Camera.GetViewMatrix();

    
OnD3D11CreateDevice()
{
  ...
    g_pLightDir = g_pEffect11->GetVariableByName( "g_LightDir" )->AsVector();
    g_pLightDiffuse = g_pEffect11->GetVariableByName( "g_LightDiffuse" )->AsVector();
    g_pmWorldViewProjection = g_pEffect11->GetVariableByName( 
        "g_mWorldViewProjection" )->AsMatrix();
    g_pmWorld = g_pEffect11->GetVariableByName( "g_mWorld" )->AsMatrix();
    g_pfTime = g_pEffect11->GetVariableByName( "g_fTime" )->AsScalar();
    g_pMaterialAmbientColor = g_pEffect11->GetVariableByName("g_MaterialAmbientColor")->AsVector();
    g_pMaterialDiffuseColor = g_pEffect11->GetVariableByName( 
        "g_MaterialDiffuseColor" )->AsVector();
    g_pnNumLights = g_pEffect11->GetVariableByName( "g_nNumLights" )->AsScalar();
}

Ketiga, gunakan metode pembaruan untuk mengatur nilai variabel dalam aplikasi dalam variabel efek.

           
OnD3D11FrameRender()
{
    ...
    g_pLightDir->SetRawValue( vLightDir, 0, sizeof(D3DXVECTOR3)*MAX_LIGHTS );
    g_pLightDiffuse->SetFloatVectorArray( (float*)vLightDiffuse, 0, MAX_LIGHTS );
    g_pmWorldViewProjection->SetMatrix( (float*)&mWorldViewProjection );
    g_pmWorld->SetMatrix( (float*)&mWorld );
    g_pfTime->SetFloat( (float)fTime );
    g_pnNumLights->SetInt( g_nNumActiveLights );
}

Dua Cara untuk Mendapatkan Status dalam Variabel Efek

Ada dua cara untuk mendapatkan status yang terkandung dalam variabel efek. Mengingat efek yang telah dimuat ke dalam memori.

Salah satu caranya adalah dengan mendapatkan status sampler dari ID3DX11EffectVariable yang telah ditransmisikan sebagai antarmuka sampler.

D3D11_SAMPLER_DESC sampler_desc;
ID3D11EffectSamplerVariable* l_pD3D11EffectVariable = NULL;
if( g_pEffect11 )
{
    l_pD3D11EffectVariable = g_pEffect11->GetVariableByName( "MeshTextureSampler" )->AsSampler();
    if( l_pD3D11EffectVariable->IsValid() )
        hr = (l_pD3D11EffectVariable->GetBackingStore( 0, 
            &sampler_desc );
}

Cara lainnya adalah dengan mendapatkan status sampler dari ID3D11SamplerState.

ID3D11SamplerState* l_ppSamplerState = NULL;
D3D11_SAMPLER_DESC sampler_desc;
ID3D11EffectSamplerVariable* l_pD3D11EffectVariable = NULL;
if( g_pEffect11 )
{
    l_pD3D11EffectVariable = g_pEffect11->GetVariableByName( "MeshTextureSampler" )->AsSampler();
    if( l_pD3D11EffectVariable->IsValid )
    {
        hr = l_pD3D11EffectVariable->GetSampler( 0, 
            &l_ppSamplerState );
        if( l_ppSamplerState )
            l_ppSamplerState->GetDesc( &sampler_desc );
    }
}

Status Shader

Status shader dinyatakan dan ditetapkan dalam teknik efek, dalam sebuah pass.

VertexShader vsRenderScene = CompileShader( vs_4_0, RenderSceneVS( 1, true, true );  
technique10 RenderSceneWithTexture1Light
{
    pass P0
    {
        SetVertexShader( vsRenderScene );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, RenderScenePS( true ) ) );
    }
}

Ini berfungsi seperti yang terjadi jika Anda tidak menggunakan efek. Ada tiga panggilan, satu untuk setiap jenis shader (vertex, geometri, dan piksel). Yang pertama, SetVertexShader, memanggil ID3D11DeviceContext::VSSetShader. CompileShader adalah fungsi efek khusus yang mengambil profil shader (vs_4_0) dan nama fungsi shader vertex (RenderVS). Dengan kata lain, masing-masing panggilan CompileShader ini mengkompilasi fungsi shader terkait dan mengembalikan penunjuk ke shader yang dikompilasi.

Perhatikan bahwa tidak semua status shader harus diatur. Pass ini tidak termasuk panggilan SetHullShader atau SetDomainShader apa pun, yang berarti bahwa lambung dan shader domain yang saat ini terikat tidak akan berubah.

Status Tekstur

Status tekstur sedikit lebih kompleks daripada mengatur variabel, karena data tekstur tidak hanya dibaca seperti variabel, itu diambil sampelnya dari tekstur. Oleh karena itu, Anda harus menentukan variabel tekstur (sama seperti variabel normal kecuali menggunakan jenis tekstur) dan Anda harus menentukan kondisi pengambilan sampel. Berikut adalah contoh deklarasi variabel tekstur dan deklarasi status pengambilan sampel yang sesuai.

Texture2D g_MeshTexture;            // Color texture for mesh

SamplerState MeshTextureSampler
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};

Berikut adalah contoh pengaturan tekstur dari aplikasi. Dalam contoh ini, tekstur disimpan dalam data jala, yang dimuat saat efek dibuat.

Langkah pertama adalah mendapatkan penunjuk ke tekstur dari efek (dari jala).

ID3D11EffectShaderResourceVariable* g_ptxDiffuse = NULL;

// Obtain variables
g_ptxDiffuse = g_pEffect11->GetVariableByName( "g_MeshTexture" )->AsShaderResource();

Langkah kedua adalah menentukan tampilan untuk mengakses tekstur. Tampilan menentukan cara umum untuk mengakses data dari sumber daya tekstur.

   
OnD3D11FrameRender()
{
  ID3D11ShaderResourceView* pDiffuseRV = NULL;

  ...
  pDiffuseRV = g_Mesh11.GetMaterial(pSubset->MaterialID)->pDiffuseRV11;
  g_ptxDiffuse->SetResource( pDiffuseRV );
  ...
}   

Dari perspektif aplikasi, tampilan akses yang tidak diurutkan ditangani mirip dengan tampilan sumber daya shader. Namun, dalam fungsi shader piksel efek dan shader komputasi, data tampilan akses yang tidak diurutkan dibaca dari/ditulis ke secara langsung. Anda tidak dapat mengambil sampel dari tampilan akses yang tidak diurutkan.

Untuk informasi selengkapnya tentang menampilkan sumber daya, lihat Sumber Daya.

Merender Efek (Direct3D 11)