我正在使用XNA Framework为Windows Phone 7编写一个简单的2D游戏。
基本上,用户可以拖动多个项目。我通过在RenderTarget2D
上绘制内容来动态创建纹理,然后再绘制RenderTarget2D
。我使用模板缓冲区将更大纹理的一部分绘制到渲染目标上。
代码段
util.GraphicsDevice.SetRenderTarget(result);
util.GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.Stencil | ClearOptions.DepthBuffer, Color.Transparent, 0, 0);
// The "mask"
spriteBatch.Begin(SpriteSortMode.Deferred, util.DontWriteColorsState, null, util.StencilAlways, null, alphaTestEffect);
spriteBatch.Draw(maskTexture, destination, Color.White);
spriteBatch.End();
// The actual texture
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, util.StencilKeepWhere1, null, alphaTestEffect);
spriteBatch.Draw(bigTexture, destination, source, Color.White);
spriteBatch.End();
util.GraphicsDevice.SetRenderTarget(null);
(util
只是一个帮助类的实例,我使用它不必在任何地方复制粘贴相同的代码,它包含DepthStencilState
个对象和其他一些东西。)
我想在这些纹理后面创建一个投影效果。我想在渲染目标上绘制阴影。
不幸的是,Windows Phone 7不支持自定义着色器效果,因此我无法使用互联网上的任何示例。所以我决定尝试在软件中实现它。但是我对这种事情完全缺乏经验,所以结果既缓慢又难看。
我在软件中所做的是:
然而,它非常缓慢,基本上慢得令人无法接受。
所以问题是
是否可以使用XNA中的内置效果创建阴影或阴影效果?此外,如果没有,是否有一种算法可以在软件中创建漂亮的投影?
提前感谢您的回答! :)
编辑:
我正在考虑这种阴影:
显然,这只是一个例子,我不希望它恰好是这个尺寸。 :)
答案 0 :(得分:1)
我冒昧地调整你的解决方案@Venemo,这就是我提出的一个良好的开端:
public Texture2D CreateBlurredTexture(Texture2D originalTexture, SpriteEffects effects)
{
var device = originalTexture.GraphicsDevice;
var rt = new RenderTarget2D(device, originalTexture.Width/2, originalTexture.Height/2);
var rt2 = new RenderTarget2D(device, originalTexture.Width, originalTexture.Height);
Color shadowColor = Color.Lerp(Color.Black, Color.Transparent, 0.9f);
using (var spriteBatch = new SpriteBatch(device))
{
device.SetRenderTarget(rt);
device.Clear(Color.Transparent);
spriteBatch.Begin();
spriteBatch.Draw(originalTexture, new Rectangle(0, 0, rt.Width, rt.Height), null, shadowColor, 0, Vector2.Zero, effects, 0f);
spriteBatch.Draw(originalTexture, new Rectangle(1, 1, rt.Width - 2, rt.Height - 2), null, shadowColor, 0, Vector2.Zero, effects, 0f);
spriteBatch.Draw(originalTexture, new Rectangle(2, 2, rt.Width - 4, rt.Height - 4), null, shadowColor, 0, Vector2.Zero, effects, 0f);
spriteBatch.Draw(originalTexture, new Rectangle(3, 3, rt.Width - 6, rt.Height - 6), null, shadowColor, 0, Vector2.Zero, effects, 0f);
spriteBatch.Draw(originalTexture, new Rectangle(4, 4, rt.Width - 8, rt.Height - 8), null, shadowColor, 0, Vector2.Zero, effects, 0f);
spriteBatch.End();
device.SetRenderTarget(rt2);
device.Clear(Color.Transparent);
spriteBatch.Begin();
spriteBatch.Draw(rt, new Rectangle(0, 0, rt2.Width, rt2.Height), Color.White);
spriteBatch.End();
device.SetRenderTarget(null);
}
return rt2;
}
它的作用是创建纹理的副本,并在每次绘制时增加不透明度,同时朝向中心。完成此操作后,您可以抵消它并增加其大小以创建更大的阴影效果。这应该根据你的纹理完成任务。
答案 1 :(得分:0)
绘制阴影以纯黑色绘制原始渲染目标,可能具有一定的透明度,与原始位置稍微偏移 接下来再次绘制,就像之前在阴影上渲染纹理一样。
关于编辑,为边创建纹理,为角创建纹理,然后将投影绘制为4个边和4个角。
答案 2 :(得分:0)
这是我想出来的,最终 当然有点hacky,但当我提出这个问题时,它有点像我需要的那样。
public static Texture2D CreateBlurredTexture(Texture2D originalTexture, SpriteEffects effects)
{
var device = originalTexture.GraphicsDevice;
var rt4 = new RenderTarget2D(device, originalTexture.Width / 4, originalTexture.Height / 4);
using (var rt2 = new RenderTarget2D(device, originalTexture.Width * 3 / 2, originalTexture.Height * 3 / 2))
using (var rt3 = new RenderTarget2D(device, originalTexture.Width / 2, originalTexture.Height / 2))
using (var spriteBatch = new SpriteBatch(device))
{
device.SetRenderTarget(rt2);
device.Clear(Color.Transparent);
spriteBatch.Begin();
spriteBatch.Draw(originalTexture, new Rectangle(0, 0, rt2.Width, rt2.Height), null, Color.White, 0, Vector2.Zero, effects, 0f);
spriteBatch.End();
device.SetRenderTarget(rt3);
device.Clear(Color.Transparent);
spriteBatch.Begin();
spriteBatch.Draw(rt2, new Rectangle(0, 0, rt3.Width, rt3.Height), Color.White);
spriteBatch.End();
device.SetRenderTarget(rt4);
device.Clear(Color.Transparent);
spriteBatch.Begin();
spriteBatch.Draw(rt3, new Rectangle(0, 0, rt4.Width, rt4.Height), Color.White);
spriteBatch.End();
device.SetRenderTarget(null);
}
return rt4;
}