首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Direct3D9 / HLSL深度语义不起作用

Direct3D9 / HLSL深度语义不起作用
EN

Stack Overflow用户
提问于 2013-06-21 18:03:57
回答 1查看 922关注 0票数 0

我的着色器代码(HLSL)有问题。我使用“托管代码的DirectX”和Shader Model3.0。我尝试通过在像素着色器输出结构中使用深度语义来将自定义深度值写入深度缓冲区:

代码语言:javascript
复制
struct PSOutput
{
    float4 col : COLOR0;
    float dept : DEPTH;
};

我在我的像素着色器中使用这个结构作为返回值:

代码语言:javascript
复制
PSOutput PSFunction(VertexShaderOutput input)
{
    PSOutput output;
    ...
    output.col = float4(...);
    output.dept = ...;

    return output;
}

当我尝试编译此着色器时,DirectX抛出异常,但没有给出详细的原因信息。但是,当我从输出结构中删除深度变量时,它就可以工作了!我也试着把DEPTH0写成语义的,但是没有成功。我希望任何人能帮助我做这件事。

编辑:

如果我写下以下代码,它将失败:

代码语言:javascript
复制
PSOutput PSFunction(VertexShaderOutput input)
{
    PSOutput output;

    float resDepth = input.Position[2] / input.Position[3];

    if(...)
    {
       resDepth = ...; 
    }
    output.col = float4(...);
    output.dept = resDepth;

    return output;
}

但是如果我写这段代码,它会编译:

代码语言:javascript
复制
PSOutput PSFunction(VertexShaderOutput input)
{
    PSOutput output;

    float resDepth = input.Position[2] / input.Position[3];

    if(...)
    {
       resDepth = ...; 
    }
    output.col = float4(...);
    output.dept = 0.5;

    return output;
}

有什么想法吗?

下面是完整的代码:

代码语言:javascript
复制
float4x4 World;
float4x4 View;
float4x4 Projection;

float4 CamPos;
float4 LightDir;
float4 ObjColor;

static const float PI = 3.14159265f;

static const int MAX_FU = 32;

float fuPercent[MAX_FU];
float4 fuColor[MAX_FU];

int buildDir;
static int fuCount = 2;

float4 boxMin;
float4 boxMax;

struct VertexShaderInput
{
    float4 Position : POSITION0;
    float3 Normal : NORMAL;
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float3 Normal : NORMAL;
    float3 ExactPos : TEXCOORD1;
};

struct PSOutput
{
    float4 col : COLOR0;
    //float dept : DEPTH;
};

VertexShaderOutput VSFunction(VertexShaderInput input)
{
    VertexShaderOutput output;

    float4 worldPosition = mul(input.Position, World);
    float4 viewPosition = mul(worldPosition, View);
    output.Position = mul(viewPosition, Projection);
    output.Normal = mul(input.Normal, World);
    output.ExactPos = input.Position;

    return output;
}

PSOutput PSFunction(VertexShaderOutput input)
{
    PSOutput output;

    float4 resColor = ObjColor;
    float resDepth = input.Position[2] / input.Position[3];

    float prpos = 0;

    if (buildDir == 0)
    {
        prpos = (input.ExactPos[1] - boxMin[1]) / (boxMax[1] - boxMin[1]);
    }
    else if (buildDir == 1)
    {
        prpos = 1.0 - ((input.ExactPos[1] - boxMin[1]) / (boxMax[1] - boxMin[1]));
    }
    else if (buildDir == 2)
    {
        prpos = (input.ExactPos[2] - boxMin[2]) / (boxMax[2] - boxMin[2]);
    }
    else if (buildDir == 3)
    {
        prpos = 1.0 - ((input.ExactPos[2] - boxMin[2]) / (boxMax[1] - boxMin[2]));
    }
    else if (buildDir == 4)
    {
        prpos = (input.ExactPos[0] - boxMin[0]) / (boxMax[0] - boxMin[0]);
    }
    else if (buildDir == 5)
    {
        prpos = 1.0 - ((input.ExactPos[0] - boxMin[0]) / (boxMax[0] - boxMin[0]));
    }

    float currPerc = 1.1;

    for (int i = 0; i < fuCount; i++)
    {
        if (prpos - 0.0001 <= fuPercent[i])
        {
            if (fuPercent[i] < currPerc)
            {
                currPerc = fuPercent[i];
                resColor = fuColor[i];
            }
        }
        else
        {
            resDepth = 1.0;
            resColor[3] = 0.0;
        }
    }

    float3 nor = input.Normal;
    float3 pos = input.ExactPos;
    float glo = 0.5;

    float id = (acos(dot(LightDir,nor) / pow(dot(LightDir,LightDir) * dot(nor, nor), 0.5))  / PI );
    id = pow(id,2);

    float3 look = reflect(normalize(pos - CamPos), nor);
    float gl = (acos(dot(LightDir,look) / pow(dot(LightDir,LightDir) * dot(look, look), 0.5))  / PI );
    gl = max(gl * 10.0 - 9.0, 0.0);
    gl = pow(gl,2) * glo;

    output.col = float4(resColor[0] * id + gl, resColor[1] * id + gl, resColor[2] * id + gl, resColor[3]);
    //output.dept = resDepth;

    return output;
}

technique MyTechnique
{
    pass Pass1
    {
        VertexShader = compile vs_3_0 VSFunction();
        PixelShader = compile ps_3_0 PSFunction();
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-06-21 18:40:59

如果FXC在编译过程中抛出异常,而不是给您一个编译错误,这可能不是您做错了什么。

如果您使用的是DirectX软件开发工具包,请确保您使用的是最新版本(2010年6月)。如果您使用的是Windows Kit 8.0 SDK,那么您可能会发现一个编译器错误。您使用的是什么版本的SDK / fxc?

你能发布一个实际编译的着色器(一个带有缺失的VertexShaderOutput结构的着色器,而不是实际的代码)吗?我已经填充了缺失的代码,使用Windows Kit8.0中的fxc编译它没有问题。

编辑:

不,我没有注意到你注释掉了导致它不能编译的代码。

果然,它不能编译,但这是因为它不是有效的代码(正如编译错误所报告的)。您正在使用位置语义作为像素着色器的输入,这是无效的。如果要使用从顶点着色器输出的位置作为像素着色器的输入,请将其复制到第二个属性中并改用该属性。如果我将下面的代码替换到你的着色器中,它就会被编译。

代码语言:javascript
复制
struct VertexShaderOutput
{
    float4 ClipPosition : POSITION; // Renamed this to ClipPosition.
    float4 Position : TEXCOORD0;    // This is valid to use as an input to the pixel shader.
    float3 Normal : NORMAL;
    float3 ExactPos : TEXCOORD1;
};

struct PSOutput
{
    float4 col : COLOR0;
    float dept : DEPTH;
};

VertexShaderOutput VSFunction(VertexShaderInput input)
{
    VertexShaderOutput output;

    float4 worldPosition = mul(input.Position, World);
    float4 viewPosition = mul(worldPosition, View);
    output.ClipPosition = mul(viewPosition, Projection); 
    output.Position = output.ClipPosition; // Copy output position to our other attribute.
    output.Normal = mul(input.Normal, World);
    output.ExactPos = input.Position;

    return output;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17232537

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档