You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MonoGame的MGFX着色器中修改纹理坐标实现灯光移动

在MonoGame中通过Effect修改纹理坐标实现灯光移动效果

问题

我想通过MonoGame的Effect类修改纹理坐标,实现灯光在屏幕上移动的效果,该怎么操作?

现有代码

C# 部分

lighting.CurrentTechnique = lighting.Techniques["LightDrawing"];

lighting.Parameters["RenderTargetTexture"].SetValue(_melttown[0].Texture);

lighting.Parameters["MaskTexture"].SetValue(_lightMask[0].Texture);

MGFX 着色器部分

float4 MainPS(float2 textureCoords : TEXCOORD0) : COLOR
{
    float4 pixelColor = tex2D(RenderTargetSampler, textureCoords);

    float4 lightColor = tex2D(MaskSampler, textureCoords);

    return pixelColor * lightColor;
}

technique LightDrawing
{
    pass P0
    {
        PixelShader = compile PS_SHADERMODEL MainPS();
    }
};

解决方法

1. 修改着色器,添加灯光偏移参数

在着色器中新增一个float2类型的参数控制灯光遮罩的偏移,采样遮罩纹理时给原坐标加上这个偏移值,就能实现灯光移动:

// 新增灯光偏移参数,用于控制遮罩位置
float2 LightOffset;

// 显式声明采样器与纹理(若之前未声明)
sampler RenderTargetSampler : register(s0);
texture RenderTargetTexture;

sampler MaskSampler : register(s1);
texture MaskTexture;

float4 MainPS(float2 textureCoords : TEXCOORD0) : COLOR
{
    float4 pixelColor = tex2D(RenderTargetSampler, textureCoords);

    // 给遮罩纹理坐标添加偏移,实现灯光移动
    float2 lightUV = textureCoords + LightOffset;
    float4 lightColor = tex2D(MaskSampler, lightUV);

    return pixelColor * lightColor;
}

technique LightDrawing
{
    pass P0
    {
        PixelShader = compile PS_SHADERMODEL MainPS();
    }
};

2. 在C#中实时更新偏移量

每一帧绘制时,计算灯光的偏移值并传递给Effect参数。示例实现一个平滑的循环移动效果:

// 在Update或Draw方法中计算灯光偏移
// 用总游戏时间计算,实现无卡顿的循环运动
Vector2 lightOffset = new Vector2(
    (float)Math.Sin(GameTime.TotalGameTime.TotalSeconds) * 0.2f,
    (float)Math.Cos(GameTime.TotalGameTime.TotalSeconds) * 0.2f
);

// 将偏移值传入Effect参数
lighting.Parameters["LightOffset"].SetValue(lightOffset);

// 原有设置代码保持不变
lighting.CurrentTechnique = lighting.Techniques["LightDrawing"];
lighting.Parameters["RenderTargetTexture"].SetValue(_melttown[0].Texture);
lighting.Parameters["MaskTexture"].SetValue(_lightMask[0].Texture);

// 绘制时记得将Effect传入SpriteBatch
// spriteBatch.Begin(effect: lighting);
// ...执行绘制逻辑...
// spriteBatch.End();

额外提示

  • 偏移值范围:纹理坐标为0-1的相对值,偏移量建议控制在-1到1之间。若采样器设为Wrap模式,灯光移出屏幕后会循环显示;设为Clamp模式则边缘会拉伸。
  • 自定义采样器模式:若要实现灯光循环显示,可给遮罩采样器添加状态:
    sampler MaskSampler = sampler_state
    {
        Texture = <MaskTexture>;
        AddressU = Wrap;
        AddressV = Wrap;
        MinFilter = Linear;
        MagFilter = Linear;
    };
    
  • 复杂移动逻辑:也可根据玩家位置、预设路径计算lightOffset,实现跟随或路径移动的灯光效果。

内容的提问来源于stack exchange,提问作者Ne1gh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 15:45:23