C# 从栅格位置计算纹理坐标
我们的游戏使用了一个“积木图集”,一个方格纹理,对应于游戏中积木的特定面。我们的目标是简化顶点数据存储,将纹理数据存储在顶点中,使其成为短裤而不是漂浮物。这是我们的顶点定义(XNA,C#): 我没有改变原始着色器的任何其他内容,该着色器显示所有内容,但您可以看到整个.fx文件 如果我能调试一下,我也许能得到它,但是。。。好吧,不管怎样,我认为这与我对着色器如何工作的有限知识有关。我想我尝试使用整数算术的效果不太好。而且,这是很多的转换,我可以相信如果值在那里的某个地方被强制为0。如果我偏离了目标,以下是我的目标:C# 从栅格位置计算纹理坐标,c#,xna,shader,hlsl,C#,Xna,Shader,Hlsl,我们的游戏使用了一个“积木图集”,一个方格纹理,对应于游戏中积木的特定面。我们的目标是简化顶点数据存储,将纹理数据存储在顶点中,使其成为短裤而不是漂浮物。这是我们的顶点定义(XNA,C#): 我没有改变原始着色器的任何其他内容,该着色器显示所有内容,但您可以看到整个.fx文件 如果我能调试一下,我也许能得到它,但是。。。好吧,不管怎样,我认为这与我对着色器如何工作的有限知识有关。我想我尝试使用整数算术的效果不太好。而且,这是很多的转换,我可以相信如果值在那里的某个地方被强制为0。如果我偏离了目标
output.TexCoords = short2((short)(((input.BlockAndDecalID.x) % (AtlasWidth)) * TexturePercent), (short)(((input.BlockAndDecalID.x) / (AtlasWidth)) * TexturePercent));
output.DecalCoords = short2((short)(((input.BlockAndDecalID.y) % (AtlasWidth)) * TexturePercent), (short)(((input.BlockAndDecalID.y) / (AtlasWidth)) * TexturePercent));
这两行包含以下部分:
(input.blockanddecadId.x)/(AtlasWidth)
(input.blockanddecadId.y)/(AtlasWidth)
这两个都是整数除法。整数除法截断所有超过小数点的部分。我假设AtlasWidth始终大于每个坐标,因此这两个分区的结果都将始终为0。如果这个假设是不正确的,我假设你在某种程度上仍然想要十进制数据
您可能需要浮点除法,即返回十进制结果的除法,因此您需要首先将至少一个(或两个)操作数强制转换为浮点,例如:
((float)input.blockanddecadId.x)/((float)AtlasWidth)
编辑:我会用;它按最大短值(32767)缩放您的值,允许使用“类似十进制”的短值(换句话说,“0.5”=16383)。当然,如果您的目的只是将tex coord数据减半,您可以通过使用HalfVector2在仍然使用浮点的情况下实现这一点。如果您仍然坚持使用Short2,您可能必须像NormalizedShort2一样对其进行缩放,然后再将其作为坐标提交。好吧,在我尝试在其中一个着色器函数中创建一个short之后,遇到了一个编译器错误,该错误指出vs_1_1不支持8/16位整数(您之前为什么不告诉我??),我将函数更改为如下所示:
float texX = ((float)((int)input.BlockAndDecalID.x % AtlasWidth) * (float)TexturePercent);
float texY = ((float)((int)input.BlockAndDecalID.x / AtlasWidth) * (float)TexturePercent);
output.TexCoords = float2(texX, texY);
float decX = ((float)((int)input.BlockAndDecalID.y % AtlasWidth) * (float)TexturePercent);
float decY = ((float)((int)input.BlockAndDecalID.y / AtlasWidth) * (float)TexturePercent);
output.DecalCoords = float2(decX, decY);
这似乎很管用。我不确定它是把东西改成整数还是前面的那个(浮动)。我想可能是浮标,这意味着斯科特肯定有什么发现。我的搭档以某种方式编写了这个着色器,以使用short2作为纹理坐标;我不知道他是怎么做到的。嘿,A型,我不知道你是否知道,但你应该去看看。你可以在那里找到更多的游戏开发资源,实际上,整数除法是你想要的结果。“x”和“y”是骗人的;这两个值都是描述网格上一个角的ID。网格是25平方宽。如果我的ID是58,那么ID/GridSize=2,这是Y值。。。在这一点上,我意识到我是一个该死的白痴。我为每个纹理方块的像素宽度定义了一个常量,但我从未使用过它!我的坐标是2,这很傻,应该是2*32。考虑到这一点,我将继续进行。谢谢你让我仔细思考。啊,是的,我想说的是,有些东西看起来有点遗漏:P我只是不完全知道你是如何设置的。这并没有解决我的问题,但我认为我现在走对了方向。好吧,在实验之后,我实际上把正方形的大小烘焙成了百分比。0.04=32/800(即1/25)。所以,这实际上没有什么帮助。不知怎的,一切都归零了。我必须仔细检查我的类型转换和运算符…好吧,再说一遍,shorts不能存储任何十进制信息。假设在上面的例子中,y值为2,然后乘以0.04,得到0.08。当你进行转换时,结果将是0。我不想在上面的线程中添加太多的评论,这就是为什么我将其添加到聊天中:)。但是我要解释的是,你可以让输出仍然是一个浮点,但是如果你愿意,输入可以是一个int。看来你就是这么做的。抱歉误解了这个问题,没问题。在进一步测试之后,我决定舍入错误会导致此方法出现问题,我不想修复,主要是将某些ID的角数减去1。刚刚恢复了最后一个小时的工作,哦,好吧,就这样。。。
output.TexCoords = short2((short)(((input.BlockAndDecalID.x) % (AtlasWidth)) * TexturePercent), (short)(((input.BlockAndDecalID.x) / (AtlasWidth)) * TexturePercent));
output.DecalCoords = short2((short)(((input.BlockAndDecalID.y) % (AtlasWidth)) * TexturePercent), (short)(((input.BlockAndDecalID.y) / (AtlasWidth)) * TexturePercent));
float texX = ((float)((int)input.BlockAndDecalID.x % AtlasWidth) * (float)TexturePercent);
float texY = ((float)((int)input.BlockAndDecalID.x / AtlasWidth) * (float)TexturePercent);
output.TexCoords = float2(texX, texY);
float decX = ((float)((int)input.BlockAndDecalID.y % AtlasWidth) * (float)TexturePercent);
float decY = ((float)((int)input.BlockAndDecalID.y / AtlasWidth) * (float)TexturePercent);
output.DecalCoords = float2(decX, decY);