[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(); } }