0

我想捕获每一帧并根据查找表更改每个像素的位置。例如像素 (30,35) -> (40,50) 等等。

所以我所做的是通过 RenderTarget2D 捕获一帧并遍历每个像素并在新的位图数组中设置每个像素的新位置。但是由于 RenderTarget2D.GetColor 方法的影响,这降低了性能。

所以我认为Pixel Shader可能是解决方案:在Draw方法中:1.绘制一个简单的框架2.通过RenderTarget2D捕获它3.然后通过着色器绘制模型

但是在着色器内部,我需要访问刚刚捕获的 Texture2D 以及查找表以读取映射的像素位置。如何将这些变量传递给着色器?

编辑:这是 Draw() 方法中的代码,但我看不出为什么没有对模型应用任何更改

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Textures[0] = ShaderRenderTarget;
        GraphicsDevice.Textures[1] = LookupTexture;

        // Change to our offscreen render target. 
        GraphicsDevice.SetRenderTarget(ShaderRenderTarget); 
        // Render a simple scene.
        DrawAFrame(); 

        // Change back to the back buffer, and get our scene
        // as a texture. 
        GraphicsDevice.SetRenderTarget(null);

        waldramEffect.CurrentTechnique = waldramEffect.Techniques["Waldraam"];
        // Use Immediate mode and our effect to draw the scene
        // again, using our pixel shader. 
        GraphicsDevice.Clear(Color.CornflowerBlue);
        CreateViewMatrix();

        // Copy any parent transforms.
        Matrix[] transforms = new Matrix[myModel.Bones.Count];
        myModel.CopyAbsoluteBoneTransformsTo(transforms);

        // Draw the model. A model can have multiple meshes, so loop.
        foreach (ModelMesh mesh in myModel.Meshes)
        {
            // This is where the mesh orientation is set, as well 
            // as our camera and projection. 
            foreach (ModelMeshPart part in mesh.MeshParts)
            {
                part.Effect = waldramEffect;
                waldramEffect.Parameters["World"].SetValue(Matrix.CreateRotationY(modelRotation) * Matrix.CreateTranslation(modelPosition));
                waldramEffect.Parameters["View"].SetValue(lookAt);
                waldramEffect.Parameters["Projection"].SetValue(projection); 
            }
            // Draw the mesh, using the effects set above.
            mesh.Draw();
        } 
        base.Draw(gameTime);

        int i = 0;
        foreach (ModelMesh mesh in myModel.Meshes)
        {
            foreach (ModelMeshPart part in mesh.MeshParts)
            {
                part.Effect = basicEffects[i];
                i++;
            }
        }
    }
4

1 回答 1

1

将查找表变成纹理,将 X 和 Y 偏移存储在两个纹理通道中(例如:红色和绿色)。

在图形设备上设置两个纹理(XNA 中的渲染目标是纹理),如下所示:

GraphicsDevice.Textures[0] = myRenderTarget;
GraphicsDevice.Textures[1] = myLookupTable;

(请注意,如果您使用它,SpriteBatch它将在内部设置。)Texture[0]

在您的着色器中,为每个声明一个采样器:

sampler myRenderTarget: register(s0);
sampler myLookupTable: register(s1);

然后通过对查找表进行采样来调制渲染目标中的采样位置:

tex2D(myRenderTarget, inTexCoord.xy + tex2D(myLookupTable, inTexCoord.xy).xy);

请注意,我还没有测试过上面的 HLSL 代码。如果你想让你的偏移在像素坐标中工作并允许负偏移,你需要提供一些额外的数学。

于 2012-09-07T16:06:17.203 回答