[PR]
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
プログラミング、3DCGとその他いろいろについて
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
float4x4 World; float4x4 View; float4x4 Projection; struct VertexShaderInput { float4 Position : POSITION0; }; struct VertexShaderOutput { float4 Position : POSITION0; float DistanceFromCamera : TEXCOORD0; }; VertexShaderOutput VertexShaderFunction(VertexShaderInput input) { VertexShaderOutput output; float4 worldPosition = mul(input.Position, World); float4 viewPosition = mul(worldPosition, View); output.Position = mul(viewPosition, Projection); output.DistanceFromCamera = output.Position.z; return output; } float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 { return input.DistanceFromCamera; } technique Technique1 { pass Pass1 { VertexShader = compile vs_1_1 VertexShaderFunction(); PixelShader = compile ps_1_1 PixelShaderFunction(); } }シャドウマップを作るシェーダーです。
float4x4 World; float4x4 View; float4x4 Projection; texture ShadowMap; sampler ShadowMapSampler = sampler_state { Texture = (ShadowMap); }; float4x4 LightView; float4x4 LightProjection; struct VertexShaderInput { float4 Position : POSITION0; float4 Color : COLOR0; }; struct VertexShaderOutput { float4 Position : POSITION0; float4 PositionOnShadowMap : TEXCOORD0; float4 Color : COLOR0; }; VertexShaderOutput VertexShaderFunction(VertexShaderInput input) { VertexShaderOutput output; float4 worldPosition = mul(input.Position, World); float4 viewPosition = mul(worldPosition, View); output.Position = mul(viewPosition, Projection); output.Color = input.Color; output.PositionOnShadowMap = mul( worldPosition, mul(LightView, LightProjection) ); return output; } bool isLighted(float4 positionOnShadowMap) { float2 texCoord;
texCoord.x = (positionOnShadowMap.x / positionOnShadowMap.w + 1) / 2;
texCoord.y = (-positionOnShadowMap.y / positionOnShadowMap.w + 1) / 2;
//誤差があるはずなので、光が当たっているかどうかは //ほんの少しだけ甘く判定します。 return positionOnShadowMap.z <= tex2D(ShadowMapSampler, texCoord).x + 0.001f; } float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 { if(isLighted(input.PositionOnShadowMap)) return input.Color; else return input.Color / 3; } technique Technique1 { pass Pass1 { VertexShader = compile vs_1_1 VertexShaderFunction(); PixelShader = compile ps_2_0 PixelShaderFunction(); } }
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; public class MyGame : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; VertexPositionColor[] triangleVertices = { new VertexPositionColor(new Vector3(0, 1, 0), Color.White), new VertexPositionColor(new Vector3(1, 0, 0), Color.Red), new VertexPositionColor(new Vector3(-1, 0, 0), Color.Blue) }; Matrix[] triangles = { Matrix.Identity, Matrix.Identity }; Effect effect; Effect shadowMapCreator; RenderTarget2D shadowMap; public MyGame() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; } protected override void Initialize() { triangles[0] *= Matrix.CreateRotationX(MathHelper.ToRadians(-90)); triangles[0] *= Matrix.CreateTranslation(0, 0, 0.5f); triangles[0] *= Matrix.CreateScale(3); triangles[0] *= Matrix.CreateTranslation(0, -4, 0); triangles[1] *= Matrix.CreateRotationX(MathHelper.ToRadians(-90)); triangles[1] *= Matrix.CreateTranslation(0, 0, 0.5f); triangles[1] *= Matrix.CreateTranslation(0, -2, 0); base.Initialize(); } protected override void LoadContent() { GraphicsDevice.VertexDeclaration = new VertexDeclaration( GraphicsDevice, VertexPositionColor.VertexElements ); Matrix lightView = Matrix.CreateLookAt( new Vector3(0, 1, 0), new Vector3(), Vector3.Forward ); Matrix lightProjection = Matrix.CreateOrthographic( 8, 8, 0.1f, 30 ); shadowMapCreator = Content.Load<Effect>("ShadowMapCreator"); shadowMapCreator.Parameters["View"].SetValue(lightView); shadowMapCreator.Parameters["Projection"].SetValue(lightProjection); effect = Content.Load<Effect>("DrawUsingShadowMap"); effect.Parameters["View"].SetValue( Matrix.CreateLookAt( new Vector3(0, 1, 8), new Vector3(), Vector3.Up ) ); effect.Parameters["Projection"].SetValue( Matrix.CreatePerspectiveFieldOfView( MathHelper.ToRadians(90), GraphicsDevice.Viewport.AspectRatio, 0.1f, 100 ) ); effect.Parameters["LightView"].SetValue(lightView); effect.Parameters["LightProjection"].SetValue(lightProjection); shadowMap = new RenderTarget2D( GraphicsDevice, 512, 512, 1, SurfaceFormat.Single ); } protected override void UnloadContent() { shadowMap.Dispose(); } protected override void Draw(GameTime gameTime) { initShadowMap(); GraphicsDevice.Clear(Color.CornflowerBlue); effect.Parameters["ShadowMap"].SetValue(shadowMap.GetTexture()); foreach (Matrix triangleTransform in triangles) { effect.Parameters["World"].SetValue(triangleTransform); effect.Begin(); effect.CurrentTechnique.Passes[0].Begin(); GraphicsDevice.DrawUserPrimitives<VertexPositionColor>( PrimitiveType.TriangleList, triangleVertices, 0, 1 ); effect.CurrentTechnique.Passes[0].End(); effect.End(); } base.Draw(gameTime); } private void initShadowMap() { GraphicsDevice.SetRenderTarget(0, shadowMap); GraphicsDevice.Clear(Color.White); foreach (Matrix triangleTransform in triangles) { shadowMapCreator.Parameters["World"].SetValue(triangleTransform); shadowMapCreator.Begin(); shadowMapCreator.CurrentTechnique.Passes[0].Begin(); GraphicsDevice.DrawUserPrimitives<VertexPositionColor>( PrimitiveType.TriangleList, triangleVertices, 0, 1 ); shadowMapCreator.CurrentTechnique.Passes[0].End(); shadowMapCreator.End(); } GraphicsDevice.SetRenderTarget(0, null); } static void Main(string[] args) { using (MyGame game = new MyGame()) { game.Run(); } } }