游戏开发论坛

 找回密码
 立即注册
搜索
查看: 4623|回复: 10

请教一下各位大大关于Shader的RenderToTarget的问题

[复制链接]

4

主题

14

帖子

14

积分

新手上路

Rank: 1

积分
14
发表于 2009-3-11 22:24:00 | 显示全部楼层 |阅读模式
我看到很多Post-Screen的程序都是使用了RenderToTarget,我也使用过这种方法
但是我觉得这样有点麻烦,主要是如果要用的话,就需要在程序中反复的调用RenderToTarget,而且要在cpp文件中设置很多的参数,这样使得cpp文件改动起来挺麻烦的,我目前觉得使用FX Composer 2.5开发shader比较舒服,能不能把RenderToTarget都放在Shader中实现了.这样我使用FX Composer 2.5开发的程序可以直接在DirectX程序中使用.
谢谢了 :-)

19

主题

638

帖子

638

积分

高级会员

Rank: 4

积分
638
发表于 2009-3-11 22:43:00 | 显示全部楼层

Re:请教一下各位大大关于Shader的RenderToTarget的问题

不可能

4

主题

14

帖子

14

积分

新手上路

Rank: 1

积分
14
 楼主| 发表于 2009-3-11 22:51:00 | 显示全部楼层

Re: 请教一下各位大大关于Shader的RenderToTarget的问题

请教一下,为什么不可能呢,还有就是版本的问题,DXSAS在SDK只是寥寥提了几句,没有一个具体的例子.如果FX Composer的程序可以直接拿来用的话,Shader的开发周期就真正减少了很多了

4

主题

14

帖子

14

积分

新手上路

Rank: 1

积分
14
 楼主| 发表于 2009-3-11 22:57:00 | 显示全部楼层

Re: 请教一下各位大大关于Shader的RenderToTarget的问题

在Nvida的文档中有这个例子:
// Relative filter weights indexed by distance (in texels) from "home" texel
//   (WT_0 is the "home" or center of the filter, WT_4 is four texels away)
// Try changing these around for different filter patterns....
#define WT_0 1.0
#define WT_1 0.8
#define WT_2 0.6
#define WT_3 0.4
#define WT_4 0.2
// these ones are based on the above....
#define WT_NORMALIZE (WT_0+2.0*(WT_1+WT_2+WT_3+WT_4))
#define KW_0 (WT_0/WT_NORMALIZE)
#define KW_1 (WT_1/WT_NORMALIZE)
#define KW_2 (WT_2/WT_NORMALIZE)
#define KW_3 (WT_3/WT_NORMALIZE)
#define KW_4 (WT_4/WT_NORMALIZE)


float Script : STANDARDSGLOBAL <
    string UIWidget = "none";
    string ScriptClass = "scene";
    string ScriptOrder = "postprocess";
    string ScriptOutput = "color";
    string Script = "Technique=BloomExtract;"
                    "Technique=BloomCombine;";
> = 0.8;

float4 ClearColor
<
    string UIWidget = "color";
    string UIName = "Clear (Bg) Color";
> = {0,0,0,1.0};

float2 ViewportSize : VIEWPORTPIXELSIZE
<
    string UIName="Screen Size";
    string UIWidget="None";
>;

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

texture g_texBase : RENDERCOLORTARGET
<
    float2 ViewPortRatio = {1.0,1.0};
    int MipLevels = 1;
    string Format = "X8R8G8B8";
    string UIWidget = "None";
>;

texture g_texBloomH : RENDERCOLORTARGET
<
    float2 ViewPortRatio = {1.0,1.0};
    int MipLevels = 1;
    string Format = "X8R8G8B8";
    string UIWidget = "None";
>;

texture g_texBloomHV : RENDERCOLORTARGET
<
    float2 ViewPortRatio = {1.0,1.0};
    int MipLevels = 1;
    string Format = "X8R8G8B8";
    string UIWidget = "None";
>;

texture DepthBuffer : RENDERDEPTHSTENCILTARGET
<
    float2 ViewPortRatio = {1.0,1.0};
    string Format = "D24S8";
    string UIWidget = "None";
>;

float BloomThreshold = 0.9;
float BloomIntensity = 3.0;
float BaseIntensity = 1.0;
float BloomSaturation = 0.5;
float BaseSaturation = 1.0;
float g_bloomSpan <
    string UIName = "Bloom Step Size (Texels)";
    string UIWidget = "slider";
    float UIMin = 0.2f;
    float UIMax = 8.0f;
    float UIStep = 0.5f;
> = 2.5f;

sampler g_sampBase =
sampler_state
{
    Texture = <g_texBase>;
    MipFilter = LINEAR;
    MagFilter = LINEAR;
    MipFilter = LINEAR;
};

sampler g_sampBloomH =
sampler_state
{
    Texture = <g_texBloomH>;
    AddressU  = CLAMP;
    AddressV = CLAMP;
    MipFilter = POINT;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};

sampler g_sampBloomHV =
sampler_state
{
    Texture = <g_texBloomHV>;
    AddressU  = CLAMP;
    AddressV = CLAMP;
    MipFilter = POINT;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};

void ScreenQuadVS( float3 Position : POSITION
        , float2 UV    : TEXCOORD0
        , out float4 OUT_Position : POSITION
        , out float2 OUT_UV : TEXCOORD0 )
{
    OUT_Position = float4(Position, 1);
    OUT_UV = UV;
}

// nine texcoords, to sample nine in-line texels
struct NineTexelVertex
{
    float4 Position   : POSITION;
    float2 UV    : TEXCOORD0;
    float4 UV1   : TEXCOORD1; // xy AND zw used as UV coords
    float4 UV2   : TEXCOORD2; // xy AND zw used as UV coords
    float4 UV3   : TEXCOORD3; // xy AND zw used as UV coords
    float4 UV4   : TEXCOORD4; // xy AND zw used as UV coords
};

// vertex shader to align blur samples vertically
NineTexelVertex vert9BlurVS(
        float3 Position : POSITION,
        float2 UV : TEXCOORD0
) {
    NineTexelVertex OUT = (NineTexelVertex)0;
    OUT.Position = float4(Position, 1);
    float TexelIncrement = g_bloomSpan/ViewportSize.y;
    float2 Coord = float2(UV.xy + ViewportOffset);
    OUT.UV = Coord;
    OUT.UV1 = float4(Coord.x, Coord.y + TexelIncrement,
             Coord.x, Coord.y - TexelIncrement);
    OUT.UV2 = float4(Coord.x, Coord.y + TexelIncrement*2,
             Coord.x, Coord.y - TexelIncrement*2);
    OUT.UV3 = float4(Coord.x, Coord.y + TexelIncrement*3,
             Coord.x, Coord.y - TexelIncrement*3);
    OUT.UV4 = float4(Coord.x, Coord.y + TexelIncrement*4,
             Coord.x, Coord.y - TexelIncrement*4);
    return OUT;
}

// vertex shader to align blur samples horizontally
NineTexelVertex horiz9BlurVS(
        float3 Position : POSITION,
        float2 UV : TEXCOORD0
) {
    NineTexelVertex OUT = (NineTexelVertex)0;
    OUT.Position = float4(Position, 1);
    float TexelIncrement = g_bloomSpan/ViewportSize.x;
    float2 Coord = float2(UV.xy + ViewportOffset);
    OUT.UV = Coord;
    OUT.UV1 = float4(Coord.x + TexelIncrement, Coord.y,
             Coord.x - TexelIncrement, Coord.y);
    OUT.UV2 = float4(Coord.x + TexelIncrement*2, Coord.y,
             Coord.x - TexelIncrement*2, Coord.y);
    OUT.UV3 = float4(Coord.x + TexelIncrement*3, Coord.y,
             Coord.x - TexelIncrement*3, Coord.y);
    OUT.UV4 = float4(Coord.x + TexelIncrement*4, Coord.y,
             Coord.x - TexelIncrement*4, Coord.y);
    return OUT;
}

float4 blur9PS(NineTexelVertex IN,
        uniform sampler2D SrcSamp) : COLOR
{   
    float4 OutCol = tex2D(SrcSamp, IN.UV4.zw) * KW_4;
    OutCol += tex2D(SrcSamp, IN.UV3.zw)  * KW_2;
    OutCol += tex2D(SrcSamp, IN.UV1.zw) * KW_1;
    OutCol += tex2D(SrcSamp, IN.UV) * KW_0;
    OutCol += tex2D(SrcSamp, IN.UV1.xy) * KW_1;
    OutCol += tex2D(SrcSamp, IN.UV2.xy) * KW_2;
    OutCol += tex2D(SrcSamp, IN.UV3.xy) * KW_3;
    OutCol += tex2D(SrcSamp, IN.UV4.xy) * KW_4;
    return OutCol;
}

// Helper for modifying the saturation of a color.
float4 AdjustSaturation(float4 color, float saturation)
{
    // The constants 0.3, 0.59, and 0.11 are chosen because the
    // human eye is more sensitive to green light, and less to blue.
    float grey = dot(color, float3(0.3, 0.59, 0.11));

    return lerp(grey, color, saturation);
}

float4 BloomExtract_PS(float2 texCoord : TEXCOORD0) : COLOR0
{
    // ======== ORIG ============
    // Look up the original image color.
    // float4 c = tex2D(g_sampBase, texCoord);
    // Adjust it to keep only values brighter than the specified threshold.
    // return saturate((c - BloomThreshold) / (1 - BloomThreshold));
    // ==========================
   
    // DeepFar 05 24 :   
    // For now we are using Floating Point Texture
    // there is no need to saturate the color
    // we just need to ensure no negative number here
    return float4( max( tex2D(g_sampBase, texCoord).xyz - BloomThreshold, 0), 1.0f );
}

float4 BloomCombine_PS(float2 texCoord : TEXCOORD0) : COLOR0
{
    // ============== ORIG ======================
    // Look up the bloom and original base image colors.
    float4 bloom = tex2D(g_sampBloomHV, texCoord);
    float4 base = tex2D(g_sampBase, texCoord);
   
    // Adjust color saturation and intensity.
    bloom = AdjustSaturation(bloom, BloomSaturation) * BloomIntensity;
    base = AdjustSaturation(base, BaseSaturation) * BaseIntensity;
   
    // Darken down the base image in areas where there is a lot of bloom,
    // to prevent things looking excessively burned-out.
    // base *= (1 - saturate(bloom));
   
    // Combine the two images.
    return base + bloom;
   
    // ==========================================
}


technique BloomExtract
<
    string Script =
    "RenderColorTarget0=g_texBase;"
    //"RenderDepthStencilTarget0=DepthBuffer;"
        "ClearSetColor=ClearColor;"
        "ClearSetDepth=ClearDepth;"
        "Clear=Color;"
        "Clear=Depth;"
        "ScriptExternal=color;"
    &quotass=Extract;"
    "Pass=BlurH;"
    "Pass=BlurV;";
>
{
    pass Extract
    <
        string Script =
        "RenderColorTarget0=g_texBloomHV;"
        "RenderDepthStencilTarget0=DepthBuffer;"
        "ClearSetColor=ClearColor;"
        "ClearSetDepth=ClearDepth;"
        "Clear=Color;"
        "Clear=Depth;"
        "Draw=Buffer;";
    >
    {
        VertexShader = compile vs_2_0 ScreenQuadVS();
        cullmode = none;
        ZEnable = false;
        ZWriteEnable = false;
        AlphaBlendEnable = false;
        PixelShader = compile ps_2_0 BloomExtract_PS();
    }
   
       pass BlurH
       <
        string Script =
        "RenderColorTarget0=g_texBloomH;"
        "RenderDepthStencilTarget0=DepthBuffer;"
        "Draw=Buffer;";
    >
    {
        VertexShader = compile vs_2_0 horiz9BlurVS();
        cullmode = none;
        ZEnable = false;
        ZWriteEnable = false;
        AlphaBlendEnable = false;
        PixelShader = compile ps_2_0 blur9PS(g_sampBloomHV);
    }
    pass BlurV
    <
        string Script =
        "RenderColorTarget0=g_texBloomHV;"
        "RenderDepthStencilTarget0=DepthBuffer;"
        "Draw=Buffer;";
    >
    {
        VertexShader = compile vs_2_0 vert9BlurVS();
        cullmode = none;
        ZEnable = false;
        ZWriteEnable = false;
        AlphaBlendEnable = false;
        PixelShader = compile ps_2_0 blur9PS(g_sampBloomH);
    }
}

technique BloomCombine
<
    string Script =
    "Pass=Pass0;";
>
{
    pass Pass0
    <
        string Script =
        "RenderColorTarget0=;"
        "RenderDepthStencilTarget0=;"
        "ClearSetColor=ClearColor;"
        "ClearSetDepth=ClearDepth;"
        "Clear=Color;"
        "Clear=Depth;"
        "Draw=Buffer;";
    >
    {
        cullmode = none;
        ZEnable = false;
        ZWriteEnable = false;
        AlphaBlendEnable = false;
        
        VertexShader = compile vs_2_0 ScreenQuadVS();
        PixelShader = compile ps_2_0 BloomCombine_PS();
    }
}

这样的代码如果导入DirectX的effect能否实现shader的texture和RenderTarget自己管理了?

59

主题

984

帖子

1200

积分

金牌会员

Rank: 6Rank: 6

积分
1200
发表于 2009-3-11 23:39:00 | 显示全部楼层

Re:请教一下各位大大关于Shader的RenderToTarget的问题

你说的这个叫做 stripting annotation
本来是dxsas 0.8的一部分,可惜到1.0以后,被ms从标准里删除了
不过并不影响使用,因为dxsas里的stripting annotation实际只定义了一套标准脚本的格式和语法,以便不同程序可以解析相同的脚本,如果不考虑跨程序应用,完全可以定义一套自己的脚本格式。
实际的脚本解析,dxsas是没有做的,需要你自己编写代码来处理

基本思路是用string类型的annotation来记录脚本,比如
technique R2T
{
    pass P0
    <
         string Script = "RenderColorTarget0 = RenderTargetTexture;"
                         "ClearSetColor = clearClor;"
     >
     {........}
}
你的c++程序发现annotation的名称是script时,就说明后面所更的是脚本
大部分脚本都以 xx = xx的方式出现,外加几条有限的指令,所以实现解析还是不太难
fx composer应该就是这样做的

不幸的是关于stripting annotation,可以找到的资料非常少,就连dx sdk里也几乎没有说
你可以把nvidia的dxsas标准找来看看
另外,如果你有机会看到shaderx4,那么里面有一篇叫post-processing effects scripting的文章有比较详细的讲解

good luck

59

主题

984

帖子

1200

积分

金牌会员

Rank: 6Rank: 6

积分
1200
发表于 2009-3-11 23:47:00 | 显示全部楼层

Re:请教一下各位大大关于Shader的RenderToTarget的问题

另外说一下,虽然effect可以设置渲染状态,比如
cullmode = none;
ZEnable = false;
ZWriteEnable = false;
AlphaBlendEnable = false;

但最好不要使用这个功能,原因之一就是会让你的程序很难debug,当你有大量物体时,渲染状态出错以后,你的C++代码完全无法知道是哪个物体破坏或者说修改了渲染状态

119

主题

1367

帖子

1393

积分

金牌会员

Rank: 6Rank: 6

积分
1393
发表于 2009-3-12 00:12:00 | 显示全部楼层

Re:请教一下各位大大关于Shader的RenderToTarget的问题

意思是说这些状态最好是在shader之外程序代码中设置了对吧
好像很有道理,值得采纳。

4

主题

14

帖子

14

积分

新手上路

Rank: 1

积分
14
 楼主| 发表于 2009-3-12 09:09:00 | 显示全部楼层

Re: 请教一下各位大大关于Shader的RenderToTarget的问题

非常感谢clayman兄的耐心解答,这个问题我也比较明白了,原来是各个显卡公司为了在自己的工具上能够正常运行而设计的程序,而ms并没有完全支持,我非常看好这一块,如果DirectX能够很好的支持或者扩展DXSAS,那shader的编写就会大大的方便了 [em20]

19

主题

638

帖子

638

积分

高级会员

Rank: 4

积分
638
发表于 2009-3-12 13:27:00 | 显示全部楼层

Re:请教一下各位大大关于Shader的RenderToTarget的问题

纠正:
1、NV的SAS支持是正式版发布之前的非官方版本,在微软没有定案时就发布出来了。而后来微软发布的sas 1.0和NV的不兼容。而且SAS是现行标准,没有被废弃一说。

2、SAS是为DCC(数字内容制作)应用提供的通用接口标准,是用来辅助游戏开发中的内容制作这一块的,和游戏引擎无关,不要以为可以用它来做游戏。DirectX也只是定义了SAS规范,并没有任何的新的程序上的支持。

4

主题

14

帖子

14

积分

新手上路

Rank: 1

积分
14
 楼主| 发表于 2009-3-13 08:57:00 | 显示全部楼层

Re: 请教一下各位大大关于Shader的RenderToTarget的问题

哦,谢谢这位朋友的补充,不过我还有一点问题,如果我在D3D的环境下使用了这些具有NV SAS的shader.那么会不会有什么影响,我记得XNA以前有一个飞车游戏,里面的shader都是具有nv sas的,运行起来似乎也没有什么问题
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-20 03:24

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表