博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
DX11 preprocessor && Dynamic shader linkage
阅读量:6982 次
发布时间:2019-06-27

本文共 6718 字,大约阅读时间需要 22 分钟。

(参照例子DXSDK sample:DynamicShaderLinkage11)

一、preprocessor

实现shader静态分支的经典方法,代码示例如下

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

  1. #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 );    ...
     

二、Dynamic Shader Linkage

在shader实现OO框架,当场景渲染时,动态指定父类指针实际子类实例。

shader中

//--------------------------------------------------------------------------------------    // Interfaces    //--------------------------------------------------------------------------------------    interface iBaseMaterial {       float3 GetAmbientColor(float2 vTexcoord);       float3 GetDiffuseColor(float2 vTexcoord);       int GetSpecularPower();    };    //--------------------------------------------------------------------------------------    // Classes    //--------------------------------------------------------------------------------------    class cBaseMaterial : iBaseMaterial {       float3    m_vColor;           int      m_iSpecPower;             float3 GetAmbientColor(float2 vTexcoord) { return m_vColor;   }       float3 GetDiffuseColor(float2 vTexcoord) { return (float3)m_vColor;   }       int GetSpecularPower() { return m_iSpecPower;   }    };    class cPlasticMaterial : cBaseMaterial { };    class cPlasticTexturedMaterial : cPlasticMaterial { ... };    class cPlasticLightingOnlyMaterial : cBaseMaterial { ... }         cbuffer cbPerPrimitive : register( b1 ) {       cPlasticMaterial              g_plasticMaterial;       cPlasticTexturedMaterial      g_plasticTexturedMaterial;       ...    };    ...    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 );       ...       float3 Lighting = saturate( Ambient + Diffuse + Specular );       return float4(Lighting,1.0f);    }

 

 

App中:

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

// 初始化阶段, 相当于初始化shader中各interface子类实例        ID3D11ClassLinkage*         g_pPSClassLinkage= NULL;          struct CB_PS_PER_PRIMITIVE {            D3DXVECTOR4   m_vObjectColorPlastic;                // Plastic -.w is Specular Power            D3DXVECTOR4   m_vObjectColorPlasticTextured;        // Plastic -.w is Specular Power            ...        };        // Material Dynamic Permutation        enum E_MATERIAL_TYPES {           MATERIAL_PLASTIC,           ...           MATERIAL_ROUGH,           ...           MATERIAL_TYPE_COUNT        };        char*  g_pMaterialClassNames[ MATERIAL_TYPE_COUNT ] = {           "g_plasticMaterial",             // cPlasticMaterial                        "g_plasticTexturedMaterial",     // cPlasticTexturedMaterial                ...         };        E_MATERIAL_TYPES            g_iMaterial = MATERIAL_PLASTIC_TEXTURED;        ID3D11ClassInstance*        g_pMaterialClasses[ MATERIAL_TYPE_COUNT ] = { NULL };        UINT                        g_iMaterialOffset         = 0;        ID3D11ClassInstance**       g_dynamicLinkageArray     = NULL;        V_RETURN( pd3dDevice->CreateClassLinkage( &g_pPSClassLinkage ) );        ...        V_RETURN( pd3dDevice->CreatePixelShader( pPixelShaderBuffer->GetBufferPointer(),                                                        pPixelShaderBuffer->GetBufferSize(), g_pPSClassLinkage, &g_pPixelShader ) );        ...        // use shader reflection to get data locations for the interface array        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 );        if (g_dynamicLinkageArray == NULL)          return E_FAIL;        ...        ID3D11ShaderReflectionVariable* pMaterialVar = pReflector->GetVariableByName("g_abstractMaterial");        int g_iMaterialOffset = pMaterialVar->GetInterfaceSlot(0);        ...        // 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中各ClassInstance           }             ...                 // FrameRender阶段        switch( g_iMaterial )   { // 与界面控件绑定,指定interface指针实际子类实例            case MATERIAL_PLASTIC:            case MATERIAL_PLASTIC_TEXTURED: {                          ...                    g_dynamicLinkageArray[g_iMaterialOffset] = g_pMaterialClasses[ g_iMaterial ] ;                 }            case MATERIAL_ROUGH:            case MATERIAL_ROUGH_TEXTURED: {                    ...                    g_dynamicLinkageArray[g_iMaterialOffset] = g_pMaterialClasses[ g_iMaterial ] ;                }        }        ...        // PS Per Prim。初始化各实例中的成员变量,每个实例成员变量大小为Float4,即shader中的 (float3 m_vColor; int m_iSpecPower)        int iSpecPower = 128;        V( pd3dImmediateContext->Map( g_pcbPSPerPrim, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) );        CB_PS_PER_PRIMITIVE* pPSPerPrim = ( CB_PS_PER_PRIMITIVE* )MappedResource.pData;        ...        pPSPerPrim->m_vObjectColorPlasticTextured     = D3DXVECTOR4( 1, 0, 0.5, 0 );  // Shiny Plastic with Textures        memcpy( &(pPSPerPrim->m_vObjectColorPlasticTextured.w), &iSpecPower, sizeof(int));        ...        iSpecPower = 6;        pPSPerPrim->m_vObjectColorRoughTextured       = D3DXVECTOR4( 0, .5, 1, 0 );     // Rough Material with Textures        memcpy( &(pPSPerPrim->m_vObjectColorRoughTextured.w), &iSpecPower, sizeof(int));        ...        pd3dImmediateContext->Unmap( g_pcbPSPerPrim, 0 );        pd3dImmediateContext->PSSetConstantBuffers( g_iCBPSPerPrimBind, 1, &g_pcbPSPerPrim );

转载于:https://www.cnblogs.com/ActionFG/archive/2012/09/09/2677471.html

你可能感兴趣的文章
《CCNA ICND2(200-101)认证考试指南(第4版)》——第1章定义生成树协议
查看>>
什么样的 RPC 才是好用的 RPC
查看>>
《Adobe Premiere Pro CC经典教程》——14.6 特殊颜色效果
查看>>
Debian 项目不再提供 CD 格式的 ISO 镜像
查看>>
《设计团队协作权威指南》—第1章1.3节甘为螺丝钉
查看>>
android 屏幕保持唤醒 不锁屏 android.permission.WAKE_LOCK
查看>>
《Unity 3D 游戏开发技术详解与典型案例》——1.3节第一个Unity 3D程序
查看>>
Airbnb数据科学团队进化论:如何由内而外实现数据驱动
查看>>
如何用机器学习预测超售,避免美联航“暴力赶客”悲剧
查看>>
css细节(实习第1天)
查看>>
腾讯Android自动化测试实战3.1.4 Robotium的控件获取、操作及断言
查看>>
《C语言点滴》一1.5 内功修炼
查看>>
浅析 Linux 初始化 init 系统: UpStart
查看>>
《PHP和MySQL Web开发从新手到高手(第5版)》一1.7 万事俱备,摩拳擦掌
查看>>
linux 怎么完全卸载mysql数据库
查看>>
Dart的HTTP请求和响应(1)
查看>>
寻找最大的K个数,Top K问题的堆实现
查看>>
自动发布工具应该具备的11个标准特征
查看>>
页面设计四大基本原则
查看>>
2016及以后的自动化测试趋势 -《测试技术六月刊》
查看>>