Tôi đang cố gắng làm phần cứng, nhưng tôi gặp phải một số vấn đề hiệu năng lạ. Tốc độ khung hình trung bình là khoảng 45, nhưng nó cực kỳ khó hiểu.
- Cửa sổ
- Đồng bộ hóaWithV verticalRetrace = false
- IsFixedTimeStep = false
- PresentationInterval = PresentInterval.Immediate
Hình ảnh dưới đây cho thấy thời gian đo của tôi (với Stopwatch
). Biểu đồ trên cùng là thời gian dành cho Draw
phương thức và biểu đồ dưới cùng là thời gian từ khi kết thúc Draw
cho đến khi bắt đầuUpdate
Các gai cách nhau gần như chính xác 1 giây và luôn gấp 2,3,4 hoặc 5 lần so với thời gian thông thường. Các khung hình ngay sau khi tăng đột biến không mất thời gian. Tôi đã kiểm tra rằng nó không phải là người thu gom rác.
Tôi hiện đang cung cấp một lưới gồm 12 hình tam giác và 36 đỉnh như một danh sách tam giác (tôi biết nó không tối ưu, nhưng nó chỉ để thử nghiệm) với 1 triệu trường hợp. Nếu tôi bó các cuộc gọi rút thăm nhanh thành các phần nhỏ của 250 trường hợp thì mỗi vấn đề được giảm bớt, nhưng việc sử dụng cpu tăng đáng kể. Việc chạy ở trên là 10000 ví dụ cho mỗi cuộc gọi rút thăm, điều này dễ dàng hơn nhiều trên cpu.
Nếu tôi chạy trò chơi ở chế độ toàn màn hình thì đồ thị phía dưới gần như không tồn tại, nhưng vấn đề tương tự xảy ra trong Draw
phương thức này.
Đây là một hoạt động bên trong PIX , không có ý nghĩa gì với tôi cả. Dường như đối với một số khung hình không có kết xuất nào được thực hiện ...
Bất cứ ý tưởng, những gì có thể gây ra điều này?
EDIT : Theo yêu cầu, các phần có liên quan của mã kết xuất
A CubeBuffer
được tạo và khởi tạo, sau đó chứa đầy các hình khối. Nếu số lượng hình khối vượt quá một giới hạn nhất định, một hình mới CubeBuffer
sẽ được tạo ra, v.v. Mỗi bộ đệm rút ra tất cả các trường hợp trong một cuộc gọi.
Thông tin chỉ cần một lần là static
(đỉnh, bộ đệm chỉ mục và khai báo đỉnh; mặc dù cho đến nay nó không có sự khác biệt). Kết cấu là 512x512
Vẽ tranh()
device.Clear(Color.DarkSlateGray);
device.RasterizerState = new RasterizerState() { };
device.BlendState = new BlendState { };
device.DepthStencilState = new DepthStencilState() { DepthBufferEnable = true };
//samplerState=new SamplerState() { AddressU = TextureAddressMode.Mirror, AddressV = TextureAddressMode.Mirror, Filter = TextureFilter.Linear };
device.SamplerStates[0] = samplerState
effect.CurrentTechnique = effect.Techniques["InstancingTexColorLight"];
effect.Parameters["xView"].SetValue(cam.viewMatrix);
effect.Parameters["xProjection"].SetValue(projectionMatrix);
effect.Parameters["xWorld"].SetValue(worldMatrix);
effect.Parameters["cubeTexture"].SetValue(texAtlas);
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
pass.Apply();
foreach (var buf in CubeBuffers)
buf.Draw();
base.Draw(gameTime);
Khối lập phương
[StructLayout(LayoutKind.Sequential)]
struct InstanceInfoOpt9
{
public Matrix World;
public Vector2 Texture;
public Vector4 Light;
};
static VertexBuffer geometryBuffer = null;
static IndexBuffer geometryIndexBuffer = null;
static VertexDeclaration instanceVertexDeclaration = null;
VertexBuffer instanceBuffer = null;
InstanceInfoOpt9[] Buffer = new InstanceInfoOpt9[MaxCubeCount];
Int32 bufferCount=0
Init()
{
if (geometryBuffer == null)
{
geometryBuffer = new VertexBuffer(Device, typeof (VertexPositionTexture), 36, BufferUsage.WriteOnly);
geometryIndexBuffer = new IndexBuffer(Device, typeof (Int32), 36, BufferUsage.WriteOnly);
vertices = new[]{...}
geometryBuffer.SetData(vertices);
indices = new[]{...}
geometryIndexBuffer.SetData(indices);
var instanceStreamElements = new VertexElement[6];
instanceStreamElements[0] = new VertexElement(sizeof (float)*0, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 1);
instanceStreamElements[1] = new VertexElement(sizeof (float)*4, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 2);
instanceStreamElements[2] = new VertexElement(sizeof (float)*8, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 3);
instanceStreamElements[3] = new VertexElement(sizeof (float)*12, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 4);
instanceStreamElements[4] = new VertexElement(sizeof (float)*16, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 5);
instanceStreamElements[5] = new VertexElement(sizeof (float)*18, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 6);
instanceVertexDeclaration = new VertexDeclaration(instanceStreamElements);
}
instanceBuffer = new VertexBuffer(Device, instanceVertexDeclaration, MaxCubeCount, BufferUsage.WriteOnly);
instanceBuffer.SetData(Buffer);
bindings = new[]
{
new VertexBufferBinding(geometryBuffer),
new VertexBufferBinding(instanceBuffer, 0, 1),
};
}
AddRandomCube(Vector3 pos)
{
if(cubes.Count >= MaxCubeCount)
return null;
Vector2 tex = new Vector2(rnd.Next(0, 16), rnd.Next(0, 16))
Vector4 l= new Vector4((float)rnd.Next(), (float)rnd.Next(), (float)rnd.Next(), (float)rnd.Next());
var cube = new InstanceInfoOpt9(Matrix.CreateTranslation(pos),tex, l);
Buffer[bufferCount++] = cube;
return cube;
}
Draw()
{
Device.Indices = geometryIndexBuffer;
Device.SetVertexBuffers(bindings);
Device.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0, 36, 0, 12, bufferCount);
}
Shader
float4x4 xView;
float4x4 xProjection;
float4x4 xWorld;
texture cubeTexture;
sampler TexColorLightSampler = sampler_state
{
texture = <cubeTexture>;
mipfilter = LINEAR;
minfilter = LINEAR;
magfilter = LINEAR;
};
struct InstancingVSTexColorLightInput
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
};
struct InstancingVSTexColorLightOutput
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
float4 Light : TEXCOORD1;
};
InstancingVSTexColorLightOutput InstancingVSTexColorLight(InstancingVSTexColorLightInput input, float4x4 instanceTransform : TEXCOORD1, float2 instanceTex : TEXCOORD5, float4 instanceLight : TEXCOORD6)
{
float4x4 preViewProjection = mul (xView, xProjection);
float4x4 preWorldViewProjection = mul (xWorld, preViewProjection);
InstancingVSTexColorLightOutput output;
float4 pos = input.Position;
pos = mul(pos, transpose(instanceTransform));
pos = mul(pos, preWorldViewProjection);
output.Position = pos;
output.Light = instanceLight;
output.TexCoord = float2((input.TexCoord.x / 16.0f) + (1.0f / 16.0f * instanceTex.x),
(input.TexCoord.y / 16.0f) + (1.0f / 16.0f * instanceTex.y));
return output;
}
float4 InstancingPSTexColorLight(InstancingVSTexColorLightOutput input) : COLOR0
{
float4 color = tex2D(TexColorLightSampler, input.TexCoord);
color.r = color.r * input.Light.r;
color.g = color.g * input.Light.g;
color.b = color.b * input.Light.b;
color.a = color.a * input.Light.a;
return color;
}
technique InstancingTexColorLight
{
pass Pass0
{
VertexShader = compile vs_3_0 InstancingVSTexColorLight();
PixelShader = compile ps_3_0 InstancingPSTexColorLight();
}
}