如何将Texture2D对象传递给XNA 4.0中的Pixel Shader?

时间:2012-09-07 15:39:28

标签: xna-4.0 pixel-shader

我想捕获每个帧并根据查找表更改每个像素的位置。因此,例如像素(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++;
            }
        }
    }

1 个答案:

答案 0 :(得分: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代码。如果你想让你的偏移在像素坐标中工作并允许负偏移,你需要提供一些额外的数学运算。