Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Directx 着色器代码优化_Directx_Shader - Fatal编程技术网

Directx 着色器代码优化

Directx 着色器代码优化,directx,shader,Directx,Shader,我有这个代码片段(用于cubemap PCF过滤)。我想为着色器模型2优化它。我尝试用统一存储的置换矩阵消除分支,但它需要太多(2x24) GLSL处理得很好。目标是向后兼容 (BTW.算法是错误的,但这不是现在的问题)不是真正的优化,而是考虑测试这个。 显然,在这种情况下,并非总是期望的,也很少有最好的解决方案是转移到不合适的CPU额外代码(例如,由于指令计数)。在分支的情况下,您可以: 将分支条件检查移动到CPU 拆分并移动以分离着色器分支实体 根据条件检查的结果绑定适当的着色器 这是你

我有这个代码片段(用于cubemap PCF过滤)。我想为着色器模型2优化它。我尝试用统一存储的置换矩阵消除分支,但它需要太多(2x24)

GLSL处理得很好。目标是向后兼容


(BTW.算法是错误的,但这不是现在的问题)

不是真正的优化,而是考虑测试这个。

显然,在这种情况下,并非总是期望的,也很少有最好的解决方案是转移到不合适的CPU额外代码(例如,由于指令计数)。在分支的情况下,您可以:

  • 将分支条件检查移动到CPU
  • 拆分并移动以分离着色器分支实体
  • 根据条件检查的结果绑定适当的着色器
这是你能做的最简单的事情。而且不需要在汇编程序中到处乱翻。问题是在着色器内计算条件时


希望能有所帮助。

虽然我不知道SM2.0能否解决这个问题,但考虑到GPU能力的提升,我提供了一个SM3.0解决方案

请记住,这段代码是我自己的着色器语言的一个片段(但与HLSL类似):

模板
浮点PCFIrregularCUBE(采样器阴影贴图、采样器噪声测试、浮点3 ldir、浮点2 sloc、浮点2 texelsize)
{
常量浮点内核半径=2.0f;
float3 l=正常化(ldir);
3铝=abs(l);
浮子2噪声;
浮动2旋转;
浮动标准差,t,s;
浮动d=长度(ldir);
噪声=tex2D(noisetex,sloc);
噪声=正常化(噪声*2.0f-1.0f);
float2-rotmat0=float2(noise.x,noise.y);
float2-rotmat1=float2(-noise.y,noise.x);
浮动3次;
s=0;
对于(int i=0;isd)-0.0f:1.0f);
s+=((标准差<0.001f)~1.0f:t);
}
返回s*(1.0f/样本);
}
CubeOffsetXXX类似于:

float3 CubeOffsetZXY(float3 swiz, float2 off, float2 texelsize)
{
    float3 ret;

    ret.xy = swiz.xy + 2.0f * off * texelsize * swiz.z;
    ret.z = sqrt(1.0f - dot(ret.xy, ret.xy));

    if( swiz.z < 0 )
        ret.z *= -1.0f;

    return ret;
}
float3立方体偏移设置zxy(float3开关、float2关闭、float2 texelsize)
{
浮动3-ret;
ret.xy=swiz.xy+2.0f*off*texelsize*swiz.z;
ret.z=sqrt(1.0f-点(ret.xy,ret.xy));
如果(开关z<0)
ret.z*=-1.0f;
返回ret;
}
如需了解更多详细信息,请在谷歌上搜索不规则PCF。最糟糕的结果(如“相机靠近”)是:


请注意由不规则PCF引起的“盐和胡椒”噪音。从远处看,这是完全可以接受的(Crysis 1方法)。

条件在着色器内部,因此我无法将其移动到CPU(ldir=wpos-lightpos)请提供
CubeOffset()
definitionadded;我想(也许)把它预先计算成一个纹理顺便问一下,你优化的目标是什么?你不符合规定吗?根据多少?107算术,总共111个(SM2中允许64和96个)
float3 CubeOffset(float3 swiz, float2 off, float2 texelsize)
{
    float3 ret;

    ret.yz = swiz.yz + 2.0f * off * texelsize;
    ret.x = sqrt(1.0f - dot(ret.yz, ret.yz));

    if( swiz.x < 0 )
        ret.x *= -1.0f;

    return ret;
}
error X5608: Compiled shader code uses too many arithmetic instruction slots (107).
Max. allowed by the target (ps_2_0) is 64.

error X5609: Compiled shader code uses too many instruction slots (111).
Max. allowed by the target (ps_2_0) is 96.
template <int samples>
float PCFIrregularCUBE(sampler shadowmap, sampler noisetex, float3 ldir, float2 sloc, float2 texelsize)
{
    const float kernelradius = 2.0f;

    float3    l     = normalize(ldir);
    float3    al    = abs(l);
    float2    noise;
    float2    rotated;

    float    sd, t, s;
    float    d = length(ldir);

    noise = tex2D(noisetex, sloc);
    noise = normalize(noise * 2.0f - 1.0f);

    float2 rotmat0 = float2(noise.x, noise.y);
    float2 rotmat1 = float2(-noise.y, noise.x);
    float3 off;

    s = 0;

    for( int i = 0; i < samples; ++i ) {
        rotated.x = dot(irreg_kernel[i], rotmat0) * kernelradius;
        rotated.y = dot(irreg_kernel[i], rotmat1) * kernelradius;

        if( al.x < al.y ) {
            if( al.y < al.z )
                off = CubeOffsetZXY(l, rotated, texelsize);
            else
                off = CubeOffsetYXZ(l, rotated, texelsize);
        } else {
            if( al.x < al.z )
                off = CubeOffsetZXY(l, rotated, texelsize);
            else
                off = CubeOffsetXYZ(l, rotated, texelsize);
        }

        sd = texCUBE(shadowmap, off).r;

        t = ((d > sd) ? 0.0f : 1.0f);
        s += ((sd < 0.001f) ? 1.0f : t);
    }

    return s * (1.0f / samples);
}
float3 CubeOffsetZXY(float3 swiz, float2 off, float2 texelsize)
{
    float3 ret;

    ret.xy = swiz.xy + 2.0f * off * texelsize * swiz.z;
    ret.z = sqrt(1.0f - dot(ret.xy, ret.xy));

    if( swiz.z < 0 )
        ret.z *= -1.0f;

    return ret;
}