• Shader Model 5 Interfaces and Classes


    In the pixel shader, we first define base interfaces for different light and material types:

    //--------------------------------------------------------------------------------------
       // Interfaces
       //--------------------------------------------------------------------------------------
       interface iBaseLight
       {
       float3 IlluminateAmbient(float3 vNormal);
    
       float3 IlluminateDiffuse(float3 vNormal);
    
       float3 IlluminateSpecular(float3 vNormal, int specularPower );
    
       };
       
       // ...
       interface iBaseMaterial
       {
       float3 GetAmbientColor(float2 vTexcoord);
    
       float3 GetDiffuseColor(float2 vTexcoord);
    
       int GetSpecularPower();
    
       };
    
       // ...

    Next we build specialized classes based on these interfaces, adding to the functionality where needed:

    //--------------------------------------------------------------------------------------
       // Classes
       //--------------------------------------------------------------------------------------
       class cAmbientLight : iBaseLight
       {
       float3	m_vLightColor;
       bool     m_bEnable;
    
       float3 IlluminateAmbient(float3 vNormal);
    
       float3 IlluminateDiffuse(float3 vNormal);
    
       float3 IlluminateSpecular(float3 vNormal, int specularPower );
       };
    
       // ...
       class cBaseMaterial : iBaseMaterial
       {
       float3	m_vColor;
       int      m_iSpecPower;
    
       float3 GetAmbientColor(float2 vTexcoord);
    
       float3 GetDiffuseColor(float2 vTexcoord);
       
       int GetSpecularPower();
    
       };
       // ....

    Abstract Instances and The Shaders Main Function

    The pixel shaders main function uses abstract instances of the interfaces for computation. These interfaces instances are made concrete by the application code at shader bind time:

    /--------------------------------------------------------------------------------------
                  // Abstract Interface Instances for dyamic linkage / permutation
                  //--------------------------------------------------------------------------------------
                  iBaseLight     g_abstractAmbientLighting;
                  iBaseLight     g_abstractDirectLighting;
                  iBaseMaterial  g_abstractMaterial;
    
                  //--------------------------------------------------------------------------------------
                  // Pixel Shader
                  //--------------------------------------------------------------------------------------
                  float4 PSMain( PS_INPUT Input ) : SV_TARGET
                  {
                     // Compute the Ambient term
                     float3   Ambient = (float3)0.0f;
    
                     Ambient = g_abstractMaterial.GetAmbientColor( Input.vTexcoord ) * g_abstractAmbientLighting.IlluminateAmbient( Input.vNormal );
    
                     // Accumulate the Diffuse contribution
                     float3   Diffuse = (float3)0.0f;
    
                     Diffuse += g_abstractMaterial.GetDiffuseColor( Input.vTexcoord ) * g_abstractDirectLighting.IlluminateDiffuse( Input.vNormal );
    
                     // Compute the Specular contribution
                     float3   Specular = (float3)0.0f;
                     Specular += g_abstractDirectLighting.IlluminateSpecular( Input.vNormal, g_abstractMaterial.GetSpecularPower() );
    
                     // Accumulate the lighting with saturation
                     float3 Lighting = saturate( Ambient + Diffuse + Specular );
    
                     return float4(Lighting,1.0f);
                     }

    // use shader reflection to get data locations for the interface array
    ID3D11ShaderReflection* pReflector = NULL;
    //ID3D11shaderReflection是访问shader信息的一个interface; V_RETURN( D3DReflect( pPixelShaderBuffer->GetBufferPointer(), pPixelShaderBuffer->GetBufferSize(),
    //D3Dreflect函数用以create一个id3d11shaderreflection的interface; IID_ID3D11ShaderReflection, (void**) &pReflector) ); g_iNumPSInterfaces = pReflector->GetNumInterfaceSlots(); g_dynamicLinkageArray = (ID3D11ClassInstance**) malloc( sizeof(ID3D11ClassInstance*) * g_iNumPSInterfaces ); if (g_dynamicLinkageArray == NULL) return E_FAIL; ID3D11ShaderReflectionVariable* pAmbientLightingVar = pReflector->GetVariableByName("g_abstractAmbientLighting"); g_iAmbientLightingOffset = pAmbientLightingVar->GetInterfaceSlot(0); ID3D11ShaderReflectionVariable* pDirectLightingVar = pReflector->GetVariableByName("g_abstractDirectLighting"); g_iDirectLightingOffset = pDirectLightingVar->GetInterfaceSlot(0); ID3D11ShaderReflectionVariable* pMaterialVar = pReflector->GetVariableByName("g_abstractMaterial"); g_iMaterialOffset = pMaterialVar->GetInterfaceSlot(0); // ...

    Next we enumerate all possible permutations of material object that exist in the shader:

    // Material Dynamic Permutation
    enum E_MATERIAL_TYPES
    {
       MATERIAL_PLASTIC,
       MATERIAL_PLASTIC_TEXTURED,
       MATERIAL_PLASTIC_LIGHTING_ONLY,
    
       MATERIAL_ROUGH,
       MATERIAL_ROUGH_TEXTURED,
       MATERIAL_ROUGH_LIGHTING_ONLY,
    
       MATERIAL_TYPE_COUNT
    };
    char*  g_pMaterialClassNames[ MATERIAL_TYPE_COUNT ] =
    {
       "g_plasticMaterial",             // cPlasticMaterial
       "g_plasticTexturedMaterial",     // cPlasticTexturedMaterial
       "g_plasticLightingOnlyMaterial", // cPlasticLightingOnlyMaterial
       "g_roughMaterial",               // cRoughMaterial
       "g_roughTexturedMaterial",       // cRoughTexturedMaterial
       "g_roughLightingOnlyMaterial"    // cRoughLightingOnlyMaterial
    };
    E_MATERIAL_TYPES            g_iMaterial = MATERIAL_PLASTIC_TEXTURED;
    
    
    // ...
    
    // Acquire the material Class Instances for all possible material settings
    for( UINT i=0; i < MATERIAL_TYPE_COUNT; i++)
    {
       g_pPSClassLinkage->GetClassInstance( g_pMaterialClassNames[i], 0, &g_pMaterialClasses[i] );
    }

    shader中(如果显卡不支持DX11,则STATIC_PERMUTE为True):

    #if !defined( STATIC_PERMUTE ) iBaseLight g_abstractAmbientLighting; ... iBaseMaterial g_abstractMaterial; #else ... #define g_abstractAmbientLighting g_ambientLight #define g_abstractDirectLighting g_directionalLight #define g_abstractEnvironmentLighting g_environmentLight #define g_abstractMaterial g_plasticMaterial #endif

    App中(D3DX11CompileFromFile的第二个参数就是D3D10_SHADER_MACRO *pDefines,预定义列表。显然预定义改变,需重新编译):

    1.    // Compile the shader using optional defines and an include handler for header processing static const D3D_SHADER_MACRO Shader_Macros[] = { "STATIC_PERMUTE", "1", NULL, NULL }; ID3DBlob* pErrorBlob; hr = D3DX11CompileFromFile( szFileName, &Shader_Macros[0], pIncludeHandler, szEntryPoint, szShaderModel, flags, 0, NULL, ppBlobOut, &pErrorBlob, NULL ); ...

    2. // Expand compressed vectors
      tmpNormal = R10G10B10A2_UNORM_TO_R32G32B32_FLOAT( Input.vNormal );

      float3 R10G10B10A2_UNORM_TO_R32G32B32_FLOAT( in float3 vVec )
      {
      vVec *= 2.0f;
      return vVec >= 1.0f ? ( vVec - 2.0f ) : vVec;
      }

     3.场景渲染时,动态指定父类指针实际子类实例。

    shader:

     //interface

    interface iBaseMaterial

    {

    float3 GetAmbientColor(float2 vTexcoord);

    float3 GetDiffuseColor(float2 vTexcoord);

    int GetSpecularPower();

    };

    //class

    class cBaseMaterial:iBaseMaterial

    {

    float3 m_color;

    int m_specularPower;

    float3 GetAmbientColor(float2 vTexcoord){return m_color}

    float3 GetDiffuseColor(float2 vTexcoord){return m_color}

    int GetSpecularPower(){return m_specularPower}

    };

    //////////////////////////PlasticMaterial/////////////////////////////

    class cPlasticMaterial:cBaseMaterial

    {};

    class cPlasticTextureMaterial:cPlasticMaterial

    {

    float3 GetAmbientColor(float2 vTexcoord);

    float3 GetDiffuseColor(float2 vTexcoord);

    }

    class cPlasticLightingOnlyMaterial : cBaseMaterial

    {
    float3 GetAmbientColor(float2 vTexcoord)
    {
    return (float3)1.0f;
    }

    float3 GetDiffuseColor(float2 vTexcoord)
    {
    return (float3)1.0f;
    }

    };

    //////////////////////////RoughMaterial//////////////////////

    class cRoughMaterial : cBaseMaterial
    {
    int GetSpecularPower()
    {
    return m_iSpecPower;
    }
    };

    class cRoughTexturedMaterial : cRoughMaterial
    {
    float3 GetAmbientColor(float2 vTexcoord);

    float3 GetDiffuseColor(float2 vTexcoord);

    };

    class cRoughLightingOnlyMaterial : cRoughMaterial
    {
    float3 GetAmbientColor(float2 vTexcoord)
    {
    return (float3)1.0f;
    }

    float3 GetDiffuseColor(float2 vTexcoord)
    {
    return (float3)1.0f;
    }

    };

    float4 PSMain( PS_INPUT Input ) : SV_TARGET
    {
    float3 Ambient = (float3)0.0f;
    Ambient = g_abstractMaterial.GetAmbientColor( Input.vTexcoord ) * g_abstractAmbientLighting.IlluminateAmbient( Input.vNormal );

    float3 Diffuse = (float3)0.0f;

    Diffuse += g_abstractMaterial.GetDiffuseColor( Input.vTexcoord ) * g_abstractDirectLighting.IlluminateDiffuse( Input.vNormal );

    float3 Specular = (float3)0.0f;
    Specular += g_abstractDirectLighting.IlluminateSpecular( Input.vNormal, g_abstractMaterial.GetSpecularPower() );
    Specular += g_abstractEnvironmentLighting.IlluminateSpecular( Input.vNormal, g_abstractMaterial.GetSpecularPower() );

    float3 Lighting = saturate( Ambient + Diffuse + Specular );

    return float4(Lighting,1.0f);
    }

    App中:
    设置shader中声明的Interface的具体子类实例。

    // 初始化阶段, 相当于初始化shader中各interface子类实例

    ID3D11ClassLinkage* g_pPSClassLinkage= NULL;

    truct CB_PS_PER_PRIMITIVE
    { D3DXVECTOR4 m_vObjectColorPlastic; // Plastic -.w is Specular Power

    D3DXVECTOR4 m_vObjectColorPlasticTextured; // Plastic -.w is Specular Power 

    D3DXVECTOR4 m_vObjectColorPlasticLightingOnly; // Plastic - Lighting Only

    D3DXVECTOR4 m_vObjectColorRough; // Rough Material -.w is Specular Power
    D3DXVECTOR4 m_vObjectColorRoughTextured; // Rough Material -.w is Specular Power
    D3DXVECTOR4 m_vObjectColorRoughLightingOnly; // Rough Material -.w is Specular Power

    };

    enum E_MATERIAL_TYPES
    {
    MATERIAL_PLASTIC,
    MATERIAL_PLASTIC_TEXTURED,
    MATERIAL_PLASTIC_LIGHTING_ONLY,

    MATERIAL_ROUGH,
    MATERIAL_ROUGH_TEXTURED,
    MATERIAL_ROUGH_LIGHTING_ONLY,

    MATERIAL_TYPE_COUNT
    };

    char* g_pMaterialClassNames[ MATERIAL_TYPE_COUNT ] =
    {
    "g_plasticMaterial", // cPlasticMaterial
    "g_plasticTexturedMaterial", // cPlasticTexturedMaterial
    "g_plasticLightingOnlyMaterial", // cPlasticLightingOnlyMaterial
    "g_roughMaterial", // cRoughMaterial
    "g_roughTexturedMaterial", // cRoughTexturedMaterial
    "g_roughLightingOnlyMaterial" // cRoughLightingOnlyMaterial
    };

    // use shader reflection to get data locations for the interface array

    //shader中的metadata可以被reflection调用
    ID3D11ShaderReflection* pReflector = NULL;
    V_RETURN( D3DReflect( pPixelShaderBuffer
    ->GetBufferPointer(), pPixelShaderBuffer->GetBufferSize(), IID_ID3D11ShaderReflection, (void**) &pReflector) );
    g_iNumPSInterfaces
    = pReflector->GetNumInterfaceSlots();
    // shader中所有的interface指针构成的列表
    g_dynamicLinkageArray = (ID3D11ClassInstance**) malloc( sizeof(ID3D11ClassInstance*) * g_iNumPSInterfaces );
    ID3D11ShaderReflectionVariable* pMaterialVar = pReflector->GetVariableByName("g_abstractMaterial");
    int g_iMaterialOffset = pMaterialVar->GetInterfaceSlot(0);
    for( UINT i=0; i < MATERIAL_TYPE_COUNT; i++) { g_pPSClassLinkage->GetClassInstance( g_pMaterialClassNames[i], 0, &g_pMaterialClasses[i] ); //声明shader中各ClassInstance 


  • 相关阅读:
    iOS 跳转app
    Mac下安装Redis图解教程
    高性能图文混排框架,构架顺滑的iOS应用-b
    iOS的layoutSubviews和drawRect方法何时调用
    类似nike+、香蕉打卡的转场动画效果-b
    开源YYKit-b
    轻仿QQ音乐之音频歌词播放、锁屏歌词-b
    数据库事务的四大特性
    拦截器的实现
    ognl表达式
  • 原文地址:https://www.cnblogs.com/RenderLife/p/2720334.html
Copyright © 2020-2023  润新知