简体   繁体   English

C ++和DirectX-设置着色器

[英]C++ & DirectX - setting shader

Does someone know a fast way to invoke shader processing via DirectX? 有人知道通过DirectX调用着色器处理的快速方法吗?

Right now I'm setting shaders using D3DXCreateEffectFromFile calls, which create shaders in runtime (once per each shader) from *.fx files. 现在,我正在使用D3DXCreateEffectFromFile调用设置着色器,该调用会在运行时从*.fx文件创建着色器(每个着色器一次)

Rendering part for every object ( every patch in my case - see further ) then means something like: 每个对象的渲染部分( 在我的情况下为每个补丁-进一步了解 )意味着:

// --------------------
// Preprocessing
effect->Begin();
effect->BeginPass(0);
effect->SetMatrix (or Vector or whatever - internal shader parameters) (...)
effect->CommitChanges();

// --------------------
// Geometry rendering

// Pass the geometry to render
// ...

// --------------------
// Postprocessing

// End 'effect' passes
effect->EndPass();
effect->End();

This is okay, but the profiler shows weird things - preprocessing (see code) takes about 60% of time (I'm rendering terrain object of 256 patches where every patch contains about 10k vertices) . 没关系,但是探查器显示的东西很奇怪- preprocessing (请参见代码)花费约60%的时间(我正在渲染256个补丁的terrain对象,其中每个补丁包含约1万个顶点)

Actual geometry rendering takes ~35% and postprocessing - 5% of total rendering time. 实际的几何渲染大约需要35%的时间,而后期处理则需要总渲染时间的5%。

This seems pretty strange to me and I guess that D3DXEffect interface may not be the best solution for this sort of things. 这对我来说似乎很奇怪,我想D3DXEffect接口可能不是这种事情的最佳解决方案。

I've got 2 questions: 我有2个问题:

1. Do I need to implement my own shader controller / wrapper (probably, low-level) and where should I start from? 1.我是否需要实现自己的着色器控制器/包装器(可能是低级的),我应该从哪里开始?

2. Would compiling shaders help to somehow improve parameter setting performance? 2.编译着色器是否有助于提高参数设置性能?

Maybe somebody knows how to solve this kind of problem / some implemented shader interface or could give some advices about how is this kind of problem solved in modern game engines. 也许有人知道如何解决此类问题/一些已实现的着色器接口,或者可以就现代游戏引擎中如何解决此类问题提供一些建议。

Thank you. 谢谢。

Actual geometry rendering takes ~35% and postprocessing - 5% of total rendering time 实际的几何渲染大约需要35%的时间,而后期处理则需要总渲染时间的5%

If you want to profile shader performance you need to use NVPerfHud or something similar. 如果要分析着色器性能,则需要使用NVPerfHud或类似方法。 Using CPU profiler and measuring ticks is not going to help you - rendering is often asynchronous. 使用CPU事件探查器和测量刻度不会对您有帮助-渲染通常是异步的。

Do I need to implement my own shader controller / wrapper (probably, low-level) 我是否需要实现自己的着色器控制器/包装器(可能是低级的)

Using your own shader wrapper isn't a bad idea - I never liked ID3DXEffect anyway. 使用您自己的着色器包装器不是一个坏主意-无论如何我从来都不喜欢ID3DXEffect。 With your own wrapper you'll have a total control of resources and program behavior. 使用您自己的包装器,您将完全控制资源和程序行为。 Whether you need it or not is for you to decide. 是否需要由您决定。 With ID3DXEffect you won't have a warranty that implementation is as fast as it could be - it could be wasting cpu cycles doing something you don't really need. 使用ID3DXEffect,您将无法保证实施速度尽可能快-这可能是在浪费CPU周期来做您实际上不需要的事情。 D3DX library contains few classes that are useful, but aren't guaranteed to be efficient (ID3DXEffect, ID3DXMesh, All animation-related and skin-related functions, etc). D3DX库包含一些有用的类,但不能保证它们是有效的(ID3DXEffect,ID3DXMesh,所有与动画有关的和与皮肤有关的功能,等等)。

and where should I start from? 我应该从哪里开始?

D3DXAssembleShader, IDirect3DDevice9::CreateVertexShader, IDirect3DDevice9::CreatePixelShader on DirectX 9, D3D10CompileShader on DirectX 10. Also download DirectX SDK and read shader documentation/tutorials. DirectX 9上的D3DXAssembleShader,IDirect3DDevice9 :: CreateVertexShader,IDirect3DDevice9 :: CreatePixelShader,DirectX 10上的D3D10CompileShader。另请下载DirectX SDK并阅读着色器文档/教程。

Would compiling shaders help to somehow improve parameter setting performance? 编译着色器有助于以某种方式提高参数设置性能吗?

Shaders are automatically compiled when you load them. 加载着色器时,它们会自动编译。 You could compiling try with different optimization settings, but don't expect miracles. 您可以使用其他优化设置进行编译,但是不要指望奇迹。

Are you using a DirectX profiler or just timing your client code? 您是在使用DirectX探查器还是只是在计时您的客户端代码? Profiling DirectX API calls using timers in the client code is generally not that effective because it's not necessarily synchronously processing your state updates/draw calls as you make them. 使用客户端代码中的计时器来分析DirectX API调用通常效果不佳,因为在您进行状态更新/绘制调用时并不一定同步处理它们。 There's a lot of optimization that goes on behind the scenes. 幕后进行了很多优化。 Here is an article about this for DX9 but I'm sure this hasn't changed for later versions: 这是有关DX9的文章,但我确定对于更高版本,它没有改变:

http://msdn.microsoft.com/en-us/library/bb172234(VS.85).aspx http://msdn.microsoft.com/zh-CN/library/bb172234(VS.85).aspx

  1. I've used effects before in DirectX and the system generally works fine. 我之前在DirectX中使用过效果,并且系统通常可以正常运行。 It provides some nice features that might be a pain to implement yourself at a lower-level, so I would stick with it for the moment. 它提供了一些不错的功能,这些功能可能会使您在较低级别上实现起来很麻烦,因此我暂时坚持使用它。

    As bshields suggested, your timing information might be inaccurate. 如前所述,您的时间信息可能不准确。 It sounds likely that the drawing actually is taking the most time, compared. 相比之下,听起来图纸实际花费的时间最多。

  2. The shader is compiled when it's loaded. 着色器在加载时进行编译。 Precompiling will save you a half-second of startup time, but so long as the shader doesn't change during runtime, you won't see any actual speed increase. 预编译将为您节省半秒的启动时间,但是只要着色器在运行时不变,您就不会看到任何实际的速度提高。 Precompiling is also kind of a pain, if you're still testing a shader. 如果仍在测试着色器,则预编译也很麻烦。 You can do it with the final copy, but unless you have a lot of shaders, you won't get much benefit while loading them. 您可以使用最终副本进行此操作,但是除非您有很多着色器,否则在加载它们时不会有太多好处。

    If you're creating the shaders every frame or every time your geometry is rendered, that's probably the issue. 如果要在每帧或每次渲染几何体时创建着色器,则可能是问题所在。 Unless the shader itself (not parameters) changes every frame, you should create the effect once and reuse that. 除非着色器本身(而不是参数)每帧更改一次,否则您应该只创建一次效果并重新使用它。

    I don't remember where SetParameter calls go, but you may want to check the docs to make sure your SetMatrix is in the right spot. 我不记得SetParameter调用的去向,但您可能需要检查文档以确保SetMatrix正确。 Setting parameters after the pass has started won't help anything, certainly not speed. 传递开始后设置参数将无济于事,当然不能提高速度。 Make sure that's set up correctly. 确保设置正确。 Also, set parameters as rarely as possible, there is some slight overhead involved. 此外,设置参数的可能性应尽可能少,这会涉及一些开销。 Per-frame sets will give you a notable slow-down, if you have too many. 如果设置过多,则每帧设置会明显降低速度。

All in all, the effects system does work fine in most cases and you shouldn't be seeing what you are. 总而言之,效果系统在大多数情况下都可以正常工作,您不应该看到自己的状态。 Make sure your profiling is correct, your shader is valid and optimized, and your calls are in the right places. 确保配置文件正确,着色器有效且已优化,并且调用位置正确。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM