DX11 preprocessor Dynamic shader linkage

news/2024/7/5 7:07:11

(参照例子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 processingstatic 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 termfloat3   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 PowerD3DXVECTOR4   m_vObjectColorPlasticTextured;        // Plastic -.w is Specular Power
            ...};// Material Dynamic Permutationenum 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 arrayID3D11ShaderReflection* 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 settingsfor( 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 Texturesmemcpy( &(pPSPerPrim->m_vObjectColorPlasticTextured.w), &iSpecPower, sizeof(int));...iSpecPower = 6;pPSPerPrim->m_vObjectColorRoughTextured       = D3DXVECTOR4( 0, .5, 1, 0 );     // Rough Material with Texturesmemcpy( &(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


http://lihuaxi.xjx100.cn/news/268205.html

相关文章

海思编码的理解

海思编码的流程&#xff1a; VI -> Vpss -> Vencode 这里的Vpss和Vencode绑定&#xff0c;首先Vpss创建VpssGrp组&#xff08;这里的Vpss是有一个&#xff0c;但是芯片不同Grp数量是不同的&#xff09;&#xff0c;VpssGrp组下还有通道号VpssChn。这些通道号就可以和Venc…

我发现了个Python黑魔法,执行任意代码都会自动念上一段「平安经」

来源 | Python编程时光最近的"平安经"可谓是引起了不小的风波啊。作为一个正儿八经的程序员&#xff0c;最害怕的就是自己的代码上线出现各种各样的 BUG。为此&#xff0c;明哥今天分享一个 Python 的黑魔法&#xff0c;教你如何在你执行任意 Python 代码前&#xff…

crontab定时任务

Linux配置定时任务&#xff0c;大家都知道使用crontab这个系统功能&#xff0c;但有时候我们需要区分用户执行&#xff0c;下面就直接说一下2种方法的区别&#xff1a; 方法1&#xff1a; 使用命令 crontab -e 然后直接编辑定时脚本。 这样执行以后&#xff0c;属于用户自定…

Linux之复制、移动文件及目录命令

Linux之复制、移动文件及目录命令 1. 复制、移动文件及目录命令的使用 命令说明cp拷贝文件、拷贝目录mv移动文件、移动目录、重命名 cp命令效果图: 说明: 拷贝目录需要加上-r选项&#xff0c;-r表示递归拷贝目录及其内容 mv命令移动文件效果图 mv命令移动目录效果图 mv命令重…

海思系列芯片属性

Hi3531DV100 &#xff1a; 属性&#xff1a;芯片有 5 个 BT.1120 接口 Hi3536 2. 属性 &#xff1a;芯片有 1 个 BT.1120 接口&#xff0c;这个 BT.1120 接口对应一个 VI 设备。VI 设备可用 于时序采集&#xff0c;也可用于级联接收 VO 发来的数据

css海浪动画代码,不行一行代码,纯css实现海浪动态效果!

直入主题&#xff1a;首先画一个简单的盒子:利用::before与::after画两个圆角值(radius)不同的不规则圆形:父元素设置overflow: hidden最后加上animation动画让两个不规则圆形旋转起来即可代码htmlscss// 简单的盒子.wave {position: relative;width: 150px;height: 150px;back…

告别无止境的增删改查:Java代码生成器

对于一个比较大的业务系统&#xff0c;我们总是无止境的增加&#xff0c;删除&#xff0c;修改&#xff0c;粘贴&#xff0c;复制&#xff0c;想想总让人产生一种抗拒的心里。那有什么办法可以在正常的开发进度下自动生成一些类&#xff0c;配置文件&#xff0c;或者接口呢&…

谷歌提出「卷积+注意力」新模型,超越ResNet最强变体!

点击上方“视学算法”&#xff0c;选择加"星标"或“置顶”重磅干货&#xff0c;第一时间送达丰色 发自 凹非寺量子位 报道 | 公众号 QbitAITransformer跨界计算机视觉虽然已取得了一些不错的成绩&#xff0c;但大部分情况下&#xff0c;它还是落后于最先进的卷积网络…