【问题标题】:How to pass a Texture2D object to Pixel Shader in XNA 4.0?如何在 XNA 4.0 中将 Texture2D 对象传递给像素着色器?
【发布时间】:2012-09-01 12:37:54
【问题描述】:

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

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

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

但在着色器内部,我需要访问刚刚捕获的 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++;
            }
        }
    }

【问题讨论】:

    标签: xna-4.0 pixel-shader


    【解决方案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 代码。如果你想让你的偏移在像素坐标中工作并允许负偏移,你需要提供一些额外的数学。

    【讨论】:

    • 感谢您的回答,我应用了代码,但似乎没有应用着色器。你能看出问题出在哪里吗? (不,我没有使用 SpriteBatch,因为您看到更新后的代码只是绘制了一个 3D 模型)
    • 我不太确定,我想不通。也许gamedev.stackexchange.com/questions/10165/…这个问题和答案中链接的博客文章可以提供帮助。
    猜你喜欢
    • 2012-09-09
    • 1970-01-01
    • 1970-01-01
    • 2013-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多