将多个纹理传递到XNA中的像素着色器 [英] Passing multiple textures to a pixel shader in XNA

查看:87
本文介绍了将多个纹理传递到XNA中的像素着色器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,

这可能是一个不寻常的问题,但我也认为这很有趣.我正在使用一个小型图形引擎,并且已经有了一个风景对象,越来越多的对象不再符合我们的需求.

当前对象根据高度图生成网格,并根据每个顶点的高度自动分配纹理.生成网格时,还会计算出四个具有不同高度的纹理,并计算混合它们的纹理权重.

现在,我想通过为每个顶点分配一个纹理并在两个相邻顶点具有不同纹理时计算纹理权重来对此进行一些更改.同样,纹理的数量不再局限于四个.

为此,我必须将一系列纹理传递给效果.在HLSL中,存在纹理数组的数据类型,但是Effect.SetValue()方法似乎不允许我将纹理数组作为值传递.
另外,还不清楚如何在着色器本身中访问纹理数组.我的第一个想法是使用3D纹理坐标(U,V和要使用的纹理索引)

不幸的是,我找不到用于处理此问题的示例代码,但我已经看到它在某些程序中完成,例如,很好的老式Morrowind的景观对象.

Hello,

this may be an unusual question, but I also think it''s very interesting. I am working on a little graphics engine and already have a landscape object which more and more is not up to what we need anymore.

The current object generates the mesh from a height map and automatically assigns textures according to the height of each vertex. There are four textures for different heights and texture weights to blend them are calculated when the mesh is generated as well.

Now I want to change this a bit by assigning a texture to each vertex and calculating texture weights when two ajacent vertices have different textures. Also the number of textures is not limited to four anymore.

For this I would have to pass an array of textures to the effect. In HLSL there is a data type for arrays of textures, but the Effect.SetValue() method seems not to allow me to pass an array of textures as value.

Also, it''s not quite clear how to access the texture array in the shader itself. My first idea was to use 3D texture coordinates (U, V and the index of the texture to be used)

Unfortunately I could not find any example code which deals with this, but I have seen it being done in some programs, the landscape objects for good old Morrowind for example.

推荐答案

不幸的是,DirectX 9(以及XNA)不支持纹理数组.
我自己有同时处理多个纹理的代码,到目前为止,您尝试了什么?
一种方法是,在HLSL部分中只有多个统一extern纹理"声明和多个采样器,并用SetValue设置它们的通常方式,当然,您不能按索引访问它们,必须手动"选择它们.
明显的缺点是它们只能有16个(或其他固定数字,具体取决于着色器版本),并且需要特殊的代码才能访问它们.
您是否可以欺骗"并将所有纹理组合成超大纹理?这样,您就可以简单地计算出偏移量.
Texture arrays are (unfortunately) not supported in DirectX 9 (and therefore XNA)
I have code that deals with several textures at once myself, what have you tried so far?
One way to do it, just have multiple "uniform extern texture" declarations and multiple samplers in the HLSL part, set them the usual way with SetValue, and of course you can''t access them by index, you''d have to select them "manually".
The obvious downsides are that you can only have 16 (or some other fixed number, depending on the shader version) of them, and you need special code to access each of them.
Is it possible for you to "cheat" and put all textures together in a mega-texture? That way you could simply calculate an offset.


感谢您的答复.我猜一张图片说出一千多个单词,所以我已经上传了一个到这个链接:

http://yfrog.com/74shader1j [ ^ ]

还有一个,来展示更多的动画.刚开始出现粒子效果时,燃烧的建筑物和烟雾看起来不太好.

http://img409.imageshack.us/f/shader2.jpg/ [
如果我在一个4096 x 4096纹理中组合多达16 1024 x 1024纹理,会对性能产生影响吗?另外,我知道在较旧的GPU上,纹理的宽度和高度必须是2的幂.较新的版本不再具有该限制,因此这是否仍然是一个问题是一个很好的问题.

2 x 2纹理可以工作,但是最多只有四个纹理仍然会有些限制.在大多数情况下3 x 3可以,但是超级纹理的宽度和高度可能必须扩展到2的下一个幂.4 x 4可能是更好的选择,其中包含更多的纹理,并且可能不大而不是扩展的3 x 3纹理.

最后,我将不得不考虑每个顶点必须具有多少组纹理坐标和权重.最佳值为8,因为每个顶点有很多邻居,而每个邻居都有不同的纹理.我怀疑这样的着色器会有点慢.
Thanks for your reply. I guess a picture says more than a thousand words, so I have uploaded one to this link:

http://yfrog.com/74shader1j[^]

And anotherone, to show a bit more of the animation. The burning building and the smoke don''t look very good as the particle effects just had started.

http://img409.imageshack.us/f/shader2.jpg/[^]

Here can you see a test scene with some objects (they are the first I ever made with Blender and I''m not a great artist), some particle effexts after a building just got hit by some weapon and also the landscape object I want to replace.

Right now it''s created from a height map, but I''m going to change that. In the future I want to have multiple landscape patches, organized in a Quadtree (landscapes are quite planar, so an Octree is probably not needed). This will help to render only the patches which are visible in the current frame. Also, more distant patches are going to be generated with a lower polygon count as a further optimization.

The landscape patch in the scene still is too large and has too many polygons. Up to now it uses four different textures. The blending weights are calculated by height, which you can see very clearly in the screenshot.

For the new landscape patches I will need to write some kind of editor which will allow me to set the heights (fitting to ajacent patches) and ''paint'' the mesh with a selection of textures. Uniting the textures in one bitmap could also be done here.

Does it have a performance impact if I unite up to 16 1024 x 1024 textures in one 4096 x 4096 texture? Also, I know that texture widths and heights had to be powers of 2 on older GPUs. Newer ones don''t have that restriction anymore, so it''s a good question if that still is an issue or not.

2 x 2 textures would work, but a maximum of only four textures would still be a bit restrictive. 3 x 3 would be ok for most cases, but the width and height of the super texture would probably then have to be expanded to the next power of 2. 4 x 4 may be a better choice with even more textures and probably not much larger than the expanded 3 x 3 texture.

And last, I''m going to have to think about how many sets of texture coordinates and weights every vertex must have. The optimum would be 8, as every vertex has so many neighbors which all may have a different texture. I suspect such a shader will be a bit slow.


这篇关于将多个纹理传递到XNA中的像素着色器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆