[PR]
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
プログラミング、3DCGとその他いろいろについて
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
どうもGPUでのエリア総和テーブルは上手くいかないので、問題に対処するもっとも有効で一般的な方法、すなわち現実逃避に走ることにします。
そう、そもそもなぜエリア総和テーブルをやろうとしていたのかというとAIに画像処理をやらせようとしていたからなんです!
べつにGPUでなくてもCPUで計算すればいいだけのことなので、いつまでもGPUでエリア総和テーブルをやることにこだわっているのは建設的ではありません!
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
struct VertexPositionNormalTextureTangent
{
public Vector3 Position;
public Vector3 Normal;
public Vector2 TextureCoordinate;
public Vector3 NormalMapXDirection;
public VertexPositionNormalTextureTangent(
Vector3 position,
Vector3 normal,
Vector2 textureCoordinate,
Vector3 normalMapXDirection)
{
this.Position = position;
this.Normal = normal;
this.TextureCoordinate = textureCoordinate;
this.NormalMapXDirection = normalMapXDirection;
}
public static readonly VertexElement[] VertexElements = {
new VertexElement(
0,
0,
VertexElementFormat.Vector3,
VertexElementMethod.Default,
VertexElementUsage.Position,
0),
new VertexElement(
0,
sizeof(float) * 3,
VertexElementFormat.Vector3,
VertexElementMethod.Default,
VertexElementUsage.Normal,
0),
new VertexElement(
0,
sizeof(float) * (3 + 3),
VertexElementFormat.Vector2,
VertexElementMethod.Default,
VertexElementUsage.TextureCoordinate,
0),
new VertexElement(
0,
sizeof(float) * (3 + 3 + 2),
VertexElementFormat.Vector3,
VertexElementMethod.Default,
VertexElementUsage.TextureCoordinate,
1)
};
}
public class MyGame : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
Effect effect;
//四角形の頂点です。
VertexPositionNormalTextureTangent[] rectangleVertices =
{
new VertexPositionNormalTextureTangent(
new Vector3(-1, 1, 0), Vector3.UnitZ, new Vector2(), Vector3.UnitX
),
new VertexPositionNormalTextureTangent(
new Vector3(1,1,0), Vector3.UnitZ, new Vector2(1,0), Vector3.UnitX
),
new VertexPositionNormalTextureTangent(
new Vector3(-1,-1,0), Vector3.UnitZ, new Vector2(0,1), Vector3.UnitX
),
new VertexPositionNormalTextureTangent(
new Vector3(1,1,0), Vector3.UnitZ, new Vector2(1,0), Vector3.UnitX
),
new VertexPositionNormalTextureTangent(
new Vector3(1,-1,0), Vector3.UnitZ, new Vector2(1,1), Vector3.UnitX
),
new VertexPositionNormalTextureTangent(
new Vector3(-1,-1,0), Vector3.UnitZ, new Vector2(0, 1), Vector3.UnitX
)
};
Matrix worldTransform = Matrix.Identity;
public MyGame()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void LoadContent()
{
effect = Content.Load<Effect>("BumpMapping");
effect.Parameters["View"].SetValue(
Matrix.CreateLookAt(new Vector3(0, 0, 3), new Vector3(), Vector3.Up)
);
effect.Parameters["Projection"].SetValue(
Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(90),
(float)GraphicsDevice.Viewport.Width / GraphicsDevice.Viewport.Height,
0.1f, 1000
));
effect.Parameters["Light0Direction"].SetValue(
new Vector3(-1, 0, -1)
);
effect.Parameters["NormalMap"].SetValue(
Content.Load<Texture2D>("NormalMap2")
);
GraphicsDevice.VertexDeclaration = new VertexDeclaration(
GraphicsDevice,
VertexPositionNormalTextureTangent.VertexElements
);
}
//↑↓←→キーで
//四角形を回転します。
protected override void Update(GameTime gameTime)
{
KeyboardState keyboardState = Keyboard.GetState();
if (keyboardState.IsKeyDown(Keys.Left))
{
worldTransform *= Matrix.CreateRotationY(-0.03f);
}
if(keyboardState.IsKeyDown(Keys.Right))
{
worldTransform *= Matrix.CreateRotationY(0.03f);
}
if (keyboardState.IsKeyDown(Keys.Up))
{
worldTransform *= Matrix.CreateRotationX(-0.03f);
}
if (keyboardState.IsKeyDown(Keys.Down))
{
worldTransform *= Matrix.CreateRotationX(0.03f);
}
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
effect.Parameters["World"].SetValue(worldTransform);
effect.Begin();
effect.CurrentTechnique.Passes[0].Begin();
GraphicsDevice.DrawUserPrimitives<VertexPositionNormalTextureTangent>(
PrimitiveType.TriangleList,
rectangleVertices,
0,
2
);
effect.CurrentTechnique.Passes[0].End();
effect.End();
base.Draw(gameTime);
}
static void Main()
{
using (MyGame game = new MyGame())
{
game.Run();
}
}
}
float4x4 World;
float4x4 View;
float4x4 Projection;
float3 Light0Direction;
texture NormalMap;
sampler NormalSampler = sampler_state
{
Texture = (NormalMap);
};
struct VertexShaderInput
{
float4 Position : POSITION;
float4 Normal : NORMAL;
float2 TextureCoordinate : TEXCOORD0;
float4 NormalMapXDirection : TEXCOORD1;
};
struct VertexShaderOutput
{
float4 Position : POSITION0;
float2 TextureCoordinate : TEXCOORD0;
float3 LightDirectionToPolygon : TEXCOORD1;
};
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
//Position
VertexShaderOutput output;
float4 worldPosition = mul(input.Position, World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
//TextureCoordinate
output.TextureCoordinate = input.TextureCoordinate;
//LightDirectionToPolygon
float3 zDirection = normalize(mul(input.Normal, (float3x3)World));
float3 xDirection = normalize(mul(input.NormalMapXDirection, (float3x3)World));
float3 normalizedLight0Direction = normalize(Light0Direction);
output.LightDirectionToPolygon = float3(
dot(normalizedLight0Direction, xDirection),
dot(normalizedLight0Direction, cross(zDirection, xDirection)),
dot(normalizedLight0Direction, zDirection)
);
return output;
}
float3 getNormal(float2 texCoord)
{
return normalize(2 * tex2D(NormalSampler, texCoord) - 1);
}
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
float4 diffuse = dot(
getNormal(input.TextureCoordinate),
-input.LightDirectionToPolygon
);
return diffuse;
}
technique Technique1
{
pass Pass1
{
VertexShader = compile vs_1_1 VertexShaderFunction();
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}