理论上,我认为从高度图生成的地形曲面细分代码应该可以工作,但我在屏幕上什么都没有。我正在为我的拓扑使用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);
}