使用HLSL进行地形镶嵌

时间:2018-01-15 14:53:33

标签: c++ directx shader hlsl

理论上,我认为从高度图生成的地形曲面细分代码应该可以工作,但我在屏幕上什么都没有。我正在为我的拓扑使用D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST。类似的代码适用于简单的平面网格。 任何人都可以发现为什么它不输出任何东西?

 // VERTEX SHADER

    // TYPEDEFS
    struct VertexIn
    {
        float4 position : POSITION;
        float2 tex : TEXCOORD0;
        float3 normal : NORMAL;
        float3 position3D : TEXCOORD1;
    };

    struct VertexOut
    {
        float4 position : POSITION;
        float2 tex : TEXCOORD0;
        float3 normal : NORMAL;
        float3 position3D : TEXCOORD1;
    };

    VertexOut main(VertexIn input)
    {
        // return output;
        VertexOut output;

        output.position = input.position;

        output.position3D = input.position3D;
        // Store the texture coordinates for the pixel shader.
        output.tex = input.tex;

        output.normal = input.normal;

        return output;
    }


    // HULL SHADER

    cbuffer CameraBuffer : register(cb0)
    {
        float3 cameraPosition;
        float padding;
    };

    // Input control point
    struct VertexOut // VS_CONTROL_POINT_OUTPUT
    {
        //float3 vPosition : WORLDPOS;
        float4 position : POSITION;
        float2 tex : TEXCOORD0;
        float3 normal : NORMAL;
        float3 position3D : TEXCOORD1;
    };

    // Output control point
    struct HullOut
    {
        //float3 vPosition : WORLDPOS; 
        float4 position : POSITION;
        float2 tex : TEXCOORD0;
        float3 normal : NORMAL;
        float3 position3D : TEXCOORD1;
    };

    // Output patch constant data.
    // Triangle
    struct PatchTess // HS_CONSTANT_DATA_OUTPUT
    {
        //float EdgeTessFactor[3]           : SV_TessFactor; // e.g. would be [4] for a quad domain
        //float InsideTessFactor            : SV_InsideTessFactor; // e.g. would be Inside[2] for a quad domain
        // TODO: change/add other stuff
        float edges[3] : SV_TessFactor;
        float inside : SV_InsideTessFactor;
    };

    #define NUM_CONTROL_POINTS 3

    // Patch Constant Function
    PatchTess ConstantHS(
        InputPatch<VertexOut, NUM_CONTROL_POINTS> inputPatch,
        uint patchId : SV_PrimitiveID)
    {
        PatchTess output;
        float tessellationAmount;

        float3 distance = inputPatch[patchId].position.xyz - cameraPosition.xyz;

        if (length(distance) > 8.0f)
            tessellationAmount = 4.0f;
        else
            tessellationAmount = 64.0f / length(distance);

        // Tessellating a triangle patch also consists of two parts:
        // 1. Three edge tessellation factors control how much to tessellate along each edge.
        // Set the tessellation factors for the three edges of the triangle.
        // Uniformly tessellate the patch 'tessellationAmount' times.
        output.edges[0] = 4.0f;
        output.edges[1] = 4.0f;
        output.edges[2] = 4.0f;

        // 2. One interior tessellation factor indicates how much to tessellate the triangle patch.
        // Set the tessellation factor for tessallating inside the triangle.
        // Uniformly tessellate the patch 'tessellationAmount' times.
        output.inside = 4.0f;

        return output;
    }

    [domain("tri")]
    [partitioning("fractional_even")]
    [outputtopology("triangle_cw")]
    [outputcontrolpoints(3)]
    [patchconstantfunc("ConstantHS")]
    HullOut main(
        InputPatch<VertexOut, NUM_CONTROL_POINTS> patch,
        uint pointId : SV_OutputControlPointID,
        uint patchId : SV_PrimitiveID)
    {
        HullOut output;

        // Set the position for this control point as the output position.
        output.position = patch[pointId].position;
        output.position3D = patch[pointId].position3D;
        // Set the input tex as the output tex.
        output.tex = patch[pointId].tex;

        output.normal = patch[pointId].normal;

        return output;
    }

    // DOMAIN SHADER
// TEXTURES
Texture2D tex0 : register(t0);

// SAMPLE STATES
SamplerState Sampler0 : register(s0);

// Globals
cbuffer MatrixBuffer : register(cb0)
{
    matrix worldMatrix;
    matrix viewMatrix;
    matrix projectionMatrix;
};

cbuffer TimeBuffer : register(cb1)
{
    float time;
    float height;
    float frequency;
    float padding;
};

// Output control point
struct HullOut
{
    //float3 vPosition : WORLDPOS;
    float4 position : POSITION; // SV - system value
    float2 tex : TEXCOORD0;
    float3 normal : NORMAL;
    float3 position3D : TEXCOORD1;
};

struct DomainOut
{
    //float4 vPosition  : SV_POSITION;
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD0;
    float3 normal : NORMAL;
    float3 position3D : TEXCOORD1;
};

// Output patch constant data.
struct PatchTess // HS_CONSTANT_DATA_OUTPUT
{
    //float EdgeTessFactor[3]           : SV_TessFactor; // e.g. would be [4] for a quad domain
    //float InsideTessFactor            : SV_InsideTessFactor; // e.g. would be Inside[2] for a quad domain
    float edges[3] : SV_TessFactor;
    float inside : SV_InsideTessFactor;
};

#define NUM_CONTROL_POINTS 3

[domain("tri")]
DomainOut main(
    PatchTess input, // HS_CONSTANT_DATA_OUTPUT
    float3 uvwCoord : SV_DomainLocation,
    const OutputPatch<HullOut, NUM_CONTROL_POINTS> patch)
{
    DomainOut output;
    float3 vertexPosition;
    float2 texPosition;
    float3 normalPosition;
    float3 vertex3DPosition;

    //output.position = float4(
    //  patch[0].vPosition*domain.x+patch[1].vPosition*domain.y+patch[2].vPosition*domain.z,1);

    // Determine the position of the new vertex.
    // Invert the Y and Z components of uvwCoord as these coords are generated in UV space and therefore Y is positive downward.
    // Alternatively you can set the output topology of the hull shader to cw instead of ccw (or vice versa).
    // position
    vertexPosition = 
    uvwCoord.x * patch[0].position + 
    uvwCoord.y * patch[1].position + 
    uvwCoord.z * patch[2].position;
    // tex 
    texPosition =
    uvwCoord.x * patch[0].tex +
    uvwCoord.y * patch[1].tex +
    uvwCoord.z * patch[2].tex;
    // normal
    normalPosition = 
    uvwCoord.x * patch[0].normal +
    uvwCoord.y * patch[1].normal +
    uvwCoord.z * patch[2].normal;
    // position3D
    vertex3DPosition =
    uvwCoord.x * patch[0].position3D +
    uvwCoord.y * patch[1].position3D +
    uvwCoord.z * patch[2].position3D;

     // Sample the pixel color from the texture using the sampler at this texture coordinate location.
    float4 textureColor = tex0.SampleLevel(Sampler0, texPosition, 0);

    // Sample height map
    for (float i = 1.0f; i >= 0.0f; i -= 0.01f)
    {
        if (textureColor.r > i)
        {
            vertexPosition.y -= i * 0.5f;
            normalPosition.y -= abs(0.9 * 15.0f);
        }
    }

    // Calculate the position of the vertex against the world, view, and projection matrices.
    output.position = mul(float4(vertexPosition, 1.0f), worldMatrix);
    output.position = mul(output.position, viewMatrix);
    output.position = mul(output.position, projectionMatrix);

    // Store normals for the pixel shader
    output.normal = mul(float4(vertexPosition, 1.0f), worldMatrix);
    output.normal = normalize(output.normal); // (float3x3) 

    output.tex = patch[0].tex;

    output.position3D = mul(vertexPosition, worldMatrix);

    return output;
}

    // PIXEL SHADER

// Textures
Texture2D shaderTexture : register(t0);

// Sample states
SamplerState SampleType : register(s0);

// Constant buffers
cbuffer LightBuffer : register(cb0)
{
    float4 ambientColor;
    float4 diffuseColor;
    float3 lightDirection;
    float specularPower;
    float4 specularColor;
    float3 lightPosition;
};

// Typedefs
struct PixelInputType
{
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD0;
    float3 normal : NORMAL;
    float3 position3D : TEXCOORD1;
};

// PIXEL SHADER
float4 main(PixelInputType input) : SV_TARGET
{
    float4 textureColor;
    float3 lightDir;
    float lightIntensity;
    float4 color;
    float attenuation;
    float slope;

    // Sample the pixel color from the texture using the sampler at this texture coordinate location.
    textureColor = shaderTexture.SampleLevel(SampleType, input.tex, 0);

    // Set the default output color to the ambient light value for all pixels.
    color = ambientColor;

    lightDir = -(lightPosition - input.position3D);

    float distance = length(lightDir);

    //lightDir /= distance;

    lightDir = normalize(lightDir);

    // Calculate the amount of light on this pixel.
    lightIntensity = saturate(dot(input.normal, -lightDir));

    if (lightIntensity > 0.0f)
    {
        // attenuation
        attenuation = 1.0f / (1.0f + 0.125f * distance + 0.0f * pow(distance, 2));

        // Determine the final diffuse color based on the diffuse color and the amount of light intensity and attenuation.
        color += (diffuseColor * lightIntensity * attenuation);

        // Saturate the ambient and diffuse color.
        color = saturate(color);
    }

    // Multiply the texture pixel and the input color to get the textured result.
    color = color * textureColor;

    //// Add the specular component last to the output color.
    //color = saturate(color + specular);

    return color;
    //return float4(1.0, 0.0, 0.0, 1.0);
}

0 个答案:

没有答案