GOSUKE FACTORY - STALKER

S.T.A.L.K.E.R. の記録

2020/08/08 - 
その他
 UIDetect はとても便利なシェーダーですが、適用できるマスクが3つまでと少ない。そこで、もっと適用できるマスクを増やして使えるように改造をしてみました。10個以上使えるようにすると不具合が起きてしまい、それを修正する事ができなかったので、適用できるマスクは9個までです。改造するのはUIDetect.fxの方で、変更内容は以下の通り。

38行目あたりにある下記の個所を
#if (UIDetect_USE_RGB_MASK == 1)
    texture texUIDetectMask <source="UIDetectMaskRGB.png";>
    { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format=RGBA8; };
    sampler UIDetectMask { Texture = texUIDetectMask; };
#endif

以下の様に変更する。
#if (UIDetect_USE_RGB_MASK == 1)
    texture texUIDetectMask_1 <source="UIDetectMaskRGB.png";>
    { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format=RGBA8; };
    sampler UIDetectMask_1 { Texture = texUIDetectMask_1; };

    texture texUIDetectMask_2 <source="UIDetectMaskRGB_2.png";>
    { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format=RGBA8; };
    sampler UIDetectMask_2 { Texture = texUIDetectMask_2; };

    texture texUIDetectMask_3 <source="UIDetectMaskRGB_3.png";>
    { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format=RGBA8; };
    sampler UIDetectMask_3 { Texture = texUIDetectMask_3; };

#endif


98行目あたりにある下記の個所を
    #if (UIDetect_USE_RGB_MASK == 1)
        float3 uiMaskRGB = 1 - tex2D(UIDetectMask, texcoord).rgb;
        float3 uiMask = 0;

        if      (ui > .39) uiMask = 1;            //UI-Nr >3 -> apply no mask
        else if (ui > .29) uiMask = uiMaskRGB.b;  //UI-Nr  3 -> apply masklayer blue
        else if (ui > .19) uiMask = uiMaskRGB.g;  //UI-Nr  2 -> apply masklayer green
        else if (ui > .09) uiMask = uiMaskRGB.r;  //UI-Nr  1 -> apply masklayer red
        color = lerp(color, colorOrig, uiMask);
    #else

以下の様に変更する。
    #if (UIDetect_USE_RGB_MASK == 1)

        float3 uiMaskRGB;	

             if (ui > .69) uiMaskRGB = 1 - tex2D(UIDetectMask_3, texcoord).rgb;
        else if (ui > .39) uiMaskRGB = 1 - tex2D(UIDetectMask_2, texcoord).rgb;
        else if (ui > .09) uiMaskRGB = 1 - tex2D(UIDetectMask_1, texcoord).rgb;

        float3 uiMask = 0;

			 if  (ui > .99) uiMask = 1;            //UI-Nr >9 -> apply no mask
        else if (ui > .89) uiMask = uiMaskRGB.b;  //UI-Nr  9 -> apply masklayer blue
        else if (ui > .79) uiMask = uiMaskRGB.g;  //UI-Nr  8 -> apply masklayer green
        else if (ui > .69) uiMask = uiMaskRGB.r;  //UI-Nr  7 -> apply masklayer red

        else if (ui > .59) uiMask = uiMaskRGB.b;  //UI-Nr  6 -> apply masklayer blue
        else if (ui > .49) uiMask = uiMaskRGB.g;  //UI-Nr  5 -> apply masklayer green
        else if (ui > .39) uiMask = uiMaskRGB.r;  //UI-Nr  4 -> apply masklayer red

        else if (ui > .29) uiMask = uiMaskRGB.b;  //UI-Nr  3 -> apply masklayer blue
        else if (ui > .19) uiMask = uiMaskRGB.g;  //UI-Nr  2 -> apply masklayer green
        else if (ui > .09) uiMask = uiMaskRGB.r;  //UI-Nr  1 -> apply masklayer red


        
        color = lerp(color, colorOrig, uiMask);
      
    #else


全文
変更前
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// UIDetect by brussell
// v. 2.0
// License: CC BY 4.0
//
// UIDetect is configured via the file UIDectect.fxh. Please look
// there for a full description and usage of this shader.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

#include "ReShadeUI.fxh"

uniform float fPixelPosX < __UNIFORM_SLIDER_FLOAT1
    ui_label = "Pixel X-Position";
    ui_category = "Show Pixel";
    ui_min = 0; ui_max = BUFFER_WIDTH;
    ui_step = 1;
> = 100;

uniform float fPixelPosY < __UNIFORM_SLIDER_FLOAT1
    ui_label = "Pixel Y-Position";
    ui_category = "Show Pixel";
    ui_min = 0; ui_max = BUFFER_HEIGHT;
    ui_step = 1;
> = 100;

#include "ReShade.fxh"
#include "UIDetect.fxh"

#define epsilon 0.00001

//textures and samplers
texture texColorOrig { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; };
sampler ColorOrig { Texture = texColorOrig; };

texture texUIDetect { Width = 1; Height = 1; Format = R8; };
sampler UIDetect { Texture = texUIDetect; };

#if (UIDetect_USE_RGB_MASK == 1)
    texture texUIDetectMask <source="UIDetectMaskRGB.png";>
    { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format=RGBA8; };
    sampler UIDetectMask { Texture = texUIDetectMask; };
#endif

//pixel shaders
float3 PS_ShowPixel(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target
{
    float2 pixelCoord = float2(fPixelPosX, fPixelPosY) * BUFFER_PIXEL_SIZE;
    float3 pixelColor = tex2Dlod(ReShade::BackBuffer, float4(pixelCoord, 0, 0)).xyz;
    return pixelColor;
}

float PS_UIDetect(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target
{
    float3 pixelColor, uiPixelColor;
    float2 pixelCoord;
    float diff;
    float ui = 1;
    bool uiDetected = false;
    bool uiNext = false;

    for (int i=0; i < PIXELNUMBER; i++)
    {
        [branch]
        if (UIPixelCoord_UINr[i].z - ui < epsilon){
            if (uiNext == false){
                pixelCoord = UIPixelCoord_UINr[i].xy * BUFFER_PIXEL_SIZE;
                pixelColor = round(tex2Dlod(ReShade::BackBuffer, float4(pixelCoord, 0, 0)).rgb * 255);
                uiPixelColor = UIPixelRGB[i].rgb;
                diff = abs(dot(pixelColor - uiPixelColor, 0.333));
                if (diff < epsilon) {
                    uiDetected = true;
                }else{
                    uiDetected = false;
                    uiNext = true;
                }
            }
        }else{
            if (uiDetected == true){ return ui * 0.1; }
            ui += 1;
            uiNext = false;
            i -= 1;
        }
    }
    return uiDetected * ui * 0.1;
}

float4 PS_StoreColor(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target
{
    return tex2D(ReShade::BackBuffer, texcoord);
}

float4 PS_RestoreColor(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target
{
    float ui = tex2D(UIDetect, float2(0,0)).x;
    float4 colorOrig = tex2D(ColorOrig, texcoord);
    float4 color = tex2D(ReShade::BackBuffer, texcoord);
    
    #if (UIDetect_USE_RGB_MASK == 1)
        float3 uiMaskRGB = 1 - tex2D(UIDetectMask, texcoord).rgb;
        float3 uiMask = 0;

        if      (ui > .39) uiMask = 1;            //UI-Nr >3 -> apply no mask
        else if (ui > .29) uiMask = uiMaskRGB.b;  //UI-Nr  3 -> apply masklayer blue
        else if (ui > .19) uiMask = uiMaskRGB.g;  //UI-Nr  2 -> apply masklayer green
        else if (ui > .09) uiMask = uiMaskRGB.r;  //UI-Nr  1 -> apply masklayer red
        color = lerp(color, colorOrig, uiMask);
    #else
        color = ui > epsilon ? colorOrig : color;
    #endif
    return color;
}

//techniques
technique UIDetect_ShowPixel
{
    pass {
        VertexShader = PostProcessVS;
        PixelShader = PS_ShowPixel;
    }
}

technique UIDetect
{
    pass {
        VertexShader = PostProcessVS;
        PixelShader = PS_UIDetect;
        RenderTarget = texUIDetect;
    }
}

technique UIDetect_Before
{
    pass {
        VertexShader = PostProcessVS;
        PixelShader = PS_StoreColor;
        RenderTarget = texColorOrig;
    }
}

technique UIDetect_After
{
    pass {
        VertexShader = PostProcessVS;
        PixelShader = PS_RestoreColor;
    }
}

変更後
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// UIDetect by brussell
// v. 2.0
// License: CC BY 4.0
//
// UIDetect is configured via the file UIDectect.fxh. Please look
// there for a full description and usage of this shader.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

#include "ReShadeUI.fxh"

uniform float fPixelPosX < __UNIFORM_SLIDER_FLOAT1
    ui_label = "Pixel X-Position";
    ui_category = "Show Pixel";
    ui_min = 0; ui_max = BUFFER_WIDTH;
    ui_step = 1;
> = 100;

uniform float fPixelPosY < __UNIFORM_SLIDER_FLOAT1
    ui_label = "Pixel Y-Position";
    ui_category = "Show Pixel";
    ui_min = 0; ui_max = BUFFER_HEIGHT;
    ui_step = 1;
> = 100;

#include "ReShade.fxh"
#include "UIDetect.fxh"

#define epsilon 0.00001

//textures and samplers
texture texColorOrig { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; };
sampler ColorOrig { Texture = texColorOrig; };

texture texUIDetect { Width = 1; Height = 1; Format = R8; };
sampler UIDetect { Texture = texUIDetect; };

#if (UIDetect_USE_RGB_MASK == 1)
    texture texUIDetectMask_1 <source="UIDetectMaskRGB.png";>
    { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format=RGBA8; };
    sampler UIDetectMask_1 { Texture = texUIDetectMask_1; };

    texture texUIDetectMask_2 <source="UIDetectMaskRGB_2.png";>
    { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format=RGBA8; };
    sampler UIDetectMask_2 { Texture = texUIDetectMask_2; };

    texture texUIDetectMask_3 <source="UIDetectMaskRGB_3.png";>
    { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format=RGBA8; };
    sampler UIDetectMask_3 { Texture = texUIDetectMask_3; };

#endif

//pixel shaders
float3 PS_ShowPixel(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target
{
    float2 pixelCoord = float2(fPixelPosX, fPixelPosY) * BUFFER_PIXEL_SIZE;
    float3 pixelColor = tex2Dlod(ReShade::BackBuffer, float4(pixelCoord, 0, 0)).xyz;
    return pixelColor;
}

float PS_UIDetect(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target
{
    float3 pixelColor, uiPixelColor;
    float2 pixelCoord;
    float diff;
    float ui = 1;
    bool uiDetected = false;
    bool uiNext = false;

    for (int i=0; i < PIXELNUMBER; i++)
    {
        [branch]
        if (UIPixelCoord_UINr[i].z - ui < epsilon){
            if (uiNext == false){
                pixelCoord = UIPixelCoord_UINr[i].xy * BUFFER_PIXEL_SIZE;
                pixelColor = round(tex2Dlod(ReShade::BackBuffer, float4(pixelCoord, 0, 0)).rgb * 255);
                uiPixelColor = UIPixelRGB[i].rgb;
                diff = abs(dot(pixelColor - uiPixelColor, 0.333));
                if (diff < epsilon) {
                    uiDetected = true;
                }else{
                    uiDetected = false;
                    uiNext = true;
                }
            }
        }else{
            if (uiDetected == true){ return ui * 0.1; }
            ui += 1;
            uiNext = false;
            i -= 1;
        }
    }
    return uiDetected * ui * 0.1;
}

float4 PS_StoreColor(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target
{
    return tex2D(ReShade::BackBuffer, texcoord);
}

float4 PS_RestoreColor(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target
{
    float ui = tex2D(UIDetect, float2(0,0)).x;
    float4 colorOrig = tex2D(ColorOrig, texcoord);
    float4 color = tex2D(ReShade::BackBuffer, texcoord);
    
    #if (UIDetect_USE_RGB_MASK == 1)

        float3 uiMaskRGB;	

             if (ui > .69) uiMaskRGB = 1 - tex2D(UIDetectMask_3, texcoord).rgb;
        else if (ui > .39) uiMaskRGB = 1 - tex2D(UIDetectMask_2, texcoord).rgb;
        else if (ui > .09) uiMaskRGB = 1 - tex2D(UIDetectMask_1, texcoord).rgb;

        float3 uiMask = 0;

             if (ui > .99) uiMask = 1;            //UI-Nr >9 -> apply no mask
        else if (ui > .89) uiMask = uiMaskRGB.b;  //UI-Nr  9 -> apply masklayer blue
        else if (ui > .79) uiMask = uiMaskRGB.g;  //UI-Nr  8 -> apply masklayer green
        else if (ui > .69) uiMask = uiMaskRGB.r;  //UI-Nr  7 -> apply masklayer red

        else if (ui > .59) uiMask = uiMaskRGB.b;  //UI-Nr  6 -> apply masklayer blue
        else if (ui > .49) uiMask = uiMaskRGB.g;  //UI-Nr  5 -> apply masklayer green
        else if (ui > .39) uiMask = uiMaskRGB.r;  //UI-Nr  4 -> apply masklayer red

        else if (ui > .29) uiMask = uiMaskRGB.b;  //UI-Nr  3 -> apply masklayer blue
        else if (ui > .19) uiMask = uiMaskRGB.g;  //UI-Nr  2 -> apply masklayer green
        else if (ui > .09) uiMask = uiMaskRGB.r;  //UI-Nr  1 -> apply masklayer red


        
        color = lerp(color, colorOrig, uiMask);
      
    #else
        color = ui > epsilon ? colorOrig : color;
    #endif
    return color;
}

//techniques
technique UIDetect_ShowPixel
{
    pass {
        VertexShader = PostProcessVS;
        PixelShader = PS_ShowPixel;
    }
}

technique UIDetect
{
    pass {
        VertexShader = PostProcessVS;
        PixelShader = PS_UIDetect;
        RenderTarget = texUIDetect;
    }
}

technique UIDetect_Before
{
    pass {
        VertexShader = PostProcessVS;
        PixelShader = PS_StoreColor;
        RenderTarget = texColorOrig;
    }
}

technique UIDetect_After
{
    pass {
        VertexShader = PostProcessVS;
        PixelShader = PS_RestoreColor;
    }
}






 9個では足りなく、もっと適用できるマスクが欲しかったりマスクを重ねたい場合は、UIDetect.fx, UIDetect.fxhを複製して使用します。複製した方のUIDetect.fx#include "ReShadeUI.fxh"texColorOrigtexUIDetectが元のUIDetect.fxと被らないように適当に名前を変更してください。同様のシェーダーを重複してエフェクトをかけるのは無駄に負荷をかける気もしますが、このシェーダーは大した影響もなさそうなので、たぶん大丈夫、でしょう。


Youtube Twitter

記事(S.T.A.L.K.E.R.)
(最終更新日 2014/05/30)

作成物
Download
MOD データベース
Shadow of Chernobyl
(最終更新日 2009/05/10)

Clear Sky
(最終更新日 2009/05/10)

MOD製作の解説
Export Plugin の導入方法
(3ds Max)
オブジェクトの作り方
(3ds Max, ActorEditor)
CoPで新しい武器を追加する方法
(ActorEditor)

 当サイトはリンクフリーですが、ファイルへの直リンクは出来ればご遠慮お願い致します。バナーでリンクする場合は下にあるバナーを使用して下さい。

banner
意見、要望、感想、叱咤、激励、などなどありましたら下の意見箱または X(旧Twitter) までメッセージをどうぞ。
意見箱