【MME编写入门】后处理模板

 1 float4 ClearColor = {1,1,1,0};
 2 float ClearDepth  = 1.0;
 3 
 4 float Script : STANDARDSGLOBAL <
 5     string ScriptOutput = "color";
 6     string ScriptClass = "scene";
 7     string ScriptOrder = "postprocess";
 8 > = 0.8;
 9 
10 texture ScnMap : RENDERCOLORTARGET <
11     float2 ViewPortRatio = {1,1.0};
12 >;
13 
14 sampler ScnSamp = sampler_state {
15     texture = <ScnMap>;
16     MinFilter = LINEAR;
17     MagFilter = LINEAR;
18     MipFilter = NONE;
19 };
20 
21 texture DepthBuffer : RENDERDEPTHSTENCILTARGET <
22     float2 ViewPortRatio = {1.0,1.0};
23 >;
24 
25 float2 ViewportSize : VIEWPORTPIXELSIZE;
26 
27 static float2 ViewportOffset = (float2(0.5,0.5)/ViewportSize);
28 
29 struct VS_OUTPUT {
30     float4 Pos            : POSITION;
31     float2 Tex            : TEXCOORD0;
32 };
33 
34 VS_OUTPUT VS_DrawBuffer( float4 Pos : POSITION, float4 Tex : TEXCOORD0 ){
35     VS_OUTPUT Out;
36 
37     Out.Pos = Pos;
38     Out.Tex = Tex + ViewportOffset;
39     return Out;
40 }
41 
42 float4 PS_DrawBuffer(float2 Tex: TEXCOORD0) : COLOR
43 {
44     float4 Color = tex2D( ScnSamp, Tex );
45     return Color;
46 }
47 
48 technique PostEffect <
49     string Script =
50         "RenderColorTarget0=ScnMap;"
51         "RenderDepthStencilTarget=DepthBuffer;"
52         "ClearSetColor=ClearColor;"
53         "ClearSetDepth=ClearDepth;"
54         "Clear=Color;"
55         "Clear=Depth;"
56         "ScriptExternal=Color;"
57         "RenderColorTarget0=;"
58         "RenderDepthStencilTarget=;"
59         "Pass=DrawBuffer;"
60     ;
61 > {
62     pass DrawBuffer < string Script= "Draw=Buffer;"; > {
63         AlphaBlendEnable = FALSE;
64         VertexShader = compile vs_2_0 VS_DrawBuffer();
65         PixelShader  = compile ps_2_0 PS_DrawBuffer();
66     }

 

生成后处理用的效果文件的情况下,一定要在效果文件中声明以下变量。创建后期效果时,必须始终包含以下内容:

float Script : STANDARDSGLOBAL <
    string ScriptOutput = "color";
    string ScriptClass = "scene";
    string ScriptOrder = "postprocess";
> = 0.8; 

这声明了此效果文件是后期效果,没有它,您将无法使用 ScriptExternal 命令

为了处理后期效果,有必要准备一个特殊的纹理,该纹理将成为绘图的输出目标(渲染目标)。 

texture ScnMap : RENDERCOLORTARGET <
    float2 ViewPortRatio = {1,1.0};
>;
texture DepthBuffer : RENDERDEPTHSTENCILTARGET <
    float2 ViewPortRatio = {1.0,1.0};
>; 

带有“RENDERCOLORTARGET”的纹理参数是一种可以记录绘制结果颜色信息的纹理。 此外,带有“RENDERDEPTHSTENCILTARGET”的纹理参数被指定为深度缓冲区(Z缓冲区)。

上所述设置时,每个纹理都以与屏幕相同的大小生成。 

sampler ScnSamp = sampler_state {
    texture = <ScnMap>;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
    MipFilter = NONE;
}; 

渲染的目标屏幕的尺寸。类型是float2,单位是像素。此值为MMD的预览窗口大小或者离屏渲染的屏幕大小。即使通过Scripts的RenderColorTarget命令变更了渲染目标,此值也不会改变。此语义可以使用以下值:VIEWPORTPIXELSIZE 

为什么添加了ViewportOffset 

static float2 ViewportOffset = (float2(0.5,0.5)/ViewportSize); 

主要是处理纹理坐标偏移的情况。

纹理坐标 Tex 指向屏幕左上点 (0,0) 处和屏幕右下点 (1,1)。 

顶点着色器中,视口偏移量被添加到 Tex,但如果将输入 Tex 值按原样传递给像素着色器并用作输入纹理的坐标,则会出现以下问题。

当光栅器将顶点信息扩展为像素时,像素的顶点信息是该像素左上点的信息。 例如,如果您考虑屏幕上的左上角像素,如果未添加视口偏移,则 Tex 的值将为 (0,0)。 

这指向表示此像素的 1x1 矩形的左上点,而不是像素的中心。 

为了获得纹理每个像素的确切颜色,我们需要为 tex2D() 函数提供一个指向像素矩形中心的坐标。 根据采样器设置,如果纹理坐标不指向一个像素的中心,而是指向像素之间边界的坐标,则生成的像素颜色将是两个像素颜色的平均值。

为了避免这种情况,我们正在执行在顶点着色器中向 Tex 添加视口偏移的操作。 这会将纹理坐标的高度和宽度分别移动 0.5 个像素,并且像素着色器中的 Tex 值指向像素的中心坐标。

Out.Tex = Tex + ViewportOffset; 
  • 顶点着色器 
VS_OUTPUT VS_DrawBuffer( float4 Pos : POSITION, float4 Tex : TEXCOORD0 ){
    VS_OUTPUT Out;

    Out.Pos = Pos;
    Out.Tex = Tex + ViewportOffset;
    return Out;
} 
  • 像素着色器 
float4 PS_DrawBuffer(float2 Tex: TEXCOORD0) : COLOR
{
    float4 Color = tex2D( ScnSamp, Tex );
    return Color;
} 

在像素着色器中实现后期效果主体的处理。

比如实现灰度。常用的灰度算法 gray=(r+b+g)/3 

float4 PS_DrawBuffer(float2 Tex: TEXCOORD0) : COLOR
{
    float4 Color = tex2D( ScnSamp, Tex );
    float gray = (Color.r+Color.g+Color.b)/3;
    Color = float4(gray,gray,gray,1);
    return Color;
} 

比如实现对比度。 

Color.rgb = Color.rgb * (gray * 0.5 * Contrast + 0.5 - 0.25 * Contrast) * 2;
  • 绘制
technique PostEffect <
    string Script =
        "RenderColorTarget0=ScnMap;"
        "RenderDepthStencilTarget=DepthBuffer;"
        "ClearSetColor=ClearColor;"
        "ClearSetDepth=ClearDepth;"
        "Clear=Color;"
        "Clear=Depth;"
        "ScriptExternal=Color;"
        "RenderColorTarget0=;"
        "RenderDepthStencilTarget=;"
        "Pass=DrawBuffer;"
    ;
> 

后处理效果,technique的Script通常会执行以下步骤: 

1、使用准备好的纹理更改渲染目标 

"RenderColorTarget0=ScnMap;"
"RenderDepthStencilTarget=DepthBuffer;" 

2、变更或清除渲染目标自身的纹理。

        执行初始化操作(使用清除颜色或清除深度)。可以使用以下命令:

        Clear=Color/Depth 

"ClearSetColor=ClearColor;"//RENDERCOLORTARGET纹理
"ClearSetDepth=ClearDepth;"//RENDERDEPTHSTENCILTARGET纹理
"Clear=Color;" //清除颜色
"Clear=Depth;"//清除深度 

 3、针对当前呈现目标绘制其他对象

"ScriptExternal=Color;" 

4、将呈现目标返回到屏幕 

"RenderColorTarget0=;"
"RenderDepthStencilTarget=;" 

指定要使用的深度缓冲(Z缓冲)。

RenderDepthStencilTarget=(纹理名或空白)

通常和RenderColorTarget0一起使用。参数为通过RENDERDEPTHSTENCILTARGET语义声明了的变量名。需要重置为默认深度缓冲时,参数应为空白。 

5、绘制缓冲区 

"Pass=DrawBuffer;" 

后期效果主体是通过创建一个着色器来处理的,该着色器绘制大小与屏幕匹配的矩形多边形。 为此需要添加pass,pass部分 

pass DrawBuffer < string Script= "Draw=Buffer;"; > {
    AlphaBlendEnable = FALSE;
    VertexShader = compile vs_2_0 VS_DrawBuffer();
    PixelShader  = compile ps_2_0 PS_DrawBuffer();
} 

 

posted @ 2023-11-01 12:32  小林呓  阅读(110)  评论(0)    收藏  举报