인스턴스 렌더링 아이디어를 사용하기 위해 많은 노력을했지만 지금은 geometryshader로 아이디어를 변경했으며 구현하기가 매우 쉽습니다. 입력으로 선 (2 개의 정점)이되고 출력은 30 삼각형입니다.) 이제 사진,
#include <psiPosition.hlsli>
//#pragma warning (disable:3206)
//#pragma warning (disable:3554)
static const float PI = 3.1415926f;
static const float fRatio = 2.0f;
static float fThickness = 0.01f;
void addHalfCircle(inout TriangleStream<PS_INPUT> triangleStream, int nCountTriangles, float4 linePointToConnect, float fPointWComponent, float fAngle)
{
PS_INPUT output = (PS_INPUT)0;
for (int nI = 0; nI < nCountTriangles; ++nI)
{
output.Pos.x = cos(fAngle + (PI/nCountTriangles * nI)) * fThickness/fRatio;
output.Pos.y = sin(fAngle + (PI/nCountTriangles * nI)) * fThickness;
output.Pos.z = 0.0f;
output.Pos.w = 0.0f;
output.Pos += linePointToConnect;
output.Pos *= fPointWComponent;
triangleStream.Append(output);
output.Pos = linePointToConnect * fPointWComponent;
triangleStream.Append(output);
output.Pos.x = cos(fAngle + (PI/nCountTriangles * (nI + 1))) * fThickness/fRatio;
output.Pos.y = sin(fAngle + (PI/nCountTriangles * (nI + 1))) * fThickness;
output.Pos.z = 0.0f;
output.Pos.w = 0.0f;
output.Pos += linePointToConnect;
output.Pos *= fPointWComponent;
triangleStream.Append(output);
triangleStream.RestartStrip();
}
}
[maxvertexcount(42)]
void main(line PS_INPUT input[2], inout TriangleStream<PS_INPUT> triangleStream)
{
PS_INPUT output= (PS_INPUT)0;
int nCountTriangles =6;
float4 positionPoint0Transformed = input[0].Pos;
float4 positionPoint1Transformed = input[1].Pos;
float fPoint0w = positionPoint0Transformed.w;
float fPoint1w = positionPoint1Transformed.w;
//calculate out the W parameter, because of usage of perspective rendering
positionPoint0Transformed.xyz = positionPoint0Transformed.xyz/positionPoint0Transformed.w;
positionPoint0Transformed.w = 1.0f;
positionPoint1Transformed.xyz = positionPoint1Transformed.xyz/positionPoint1Transformed.w;
positionPoint1Transformed.w = 1.0f;
//calculate the angle between the 2 points on the screen
float3 positionDifference = positionPoint0Transformed.xyz - positionPoint1Transformed.xyz;
float3 coordinateSysten = float3(1.0f, 0.0f, 0.0f);
positionDifference.z = 0.0f;
coordinateSysten.z = 0.0f;
float fAngle = acos(dot(positionDifference.xy, coordinateSysten.xy)/(length(positionDifference.xy) * length(coordinateSysten.xy)));
if (cross(positionDifference, coordinateSysten).z < 0.0f)
{
fAngle = 2.0f * PI - fAngle;
}
fAngle *= -1.0f;
fAngle -= PI *0.5f;
//first half circle of the line
addHalfCircle(triangleStream, nCountTriangles, positionPoint0Transformed, fPoint0w, fAngle);
addHalfCircle(triangleStream, nCountTriangles, positionPoint1Transformed, fPoint1w, fAngle + PI);
//connection between the two circles
//triangle1
output.Pos.x = cos(fAngle) * fThickness/fRatio;
output.Pos.y = sin(fAngle) * fThickness;
output.Pos.z = 0.0f;
output.Pos.w = 0.0f;
output.Pos += positionPoint0Transformed;
output.Pos *= fPoint0w; //undo calculate out the W parameter, because of usage of perspective rendering
triangleStream.Append(output);
output.Pos.x = cos(fAngle + (PI/nCountTriangles * (nCountTriangles))) * fThickness/fRatio;
output.Pos.y = sin(fAngle + (PI/nCountTriangles * (nCountTriangles))) * fThickness;
output.Pos.z = 0.0f;
output.Pos.w = 0.0f;
output.Pos += positionPoint0Transformed;
output.Pos *= fPoint0w;
triangleStream.Append(output);
output.Pos.x = cos(fAngle + (PI/nCountTriangles * (nCountTriangles))) * fThickness/fRatio;
output.Pos.y = sin(fAngle + (PI/nCountTriangles * (nCountTriangles))) * fThickness;
output.Pos.z = 0.0f;
output.Pos.w = 0.0f;
output.Pos += positionPoint1Transformed;
output.Pos *= fPoint1w;
triangleStream.Append(output);
//triangle2
output.Pos.x = cos(fAngle) * fThickness/fRatio;
output.Pos.y = sin(fAngle) * fThickness;
output.Pos.z = 0.0f;
output.Pos.w = 0.0f;
output.Pos += positionPoint0Transformed;
output.Pos *= fPoint0w;
triangleStream.Append(output);
output.Pos.x = cos(fAngle) * fThickness/fRatio;
output.Pos.y = sin(fAngle) * fThickness;
output.Pos.z = 0.0f;
output.Pos.w = 0.0f;
output.Pos += positionPoint1Transformed;
output.Pos *= fPoint1w;
triangleStream.Append(output);
output.Pos.x = cos(fAngle + (PI/nCountTriangles * (nCountTriangles))) * fThickness/fRatio;
output.Pos.y = sin(fAngle + (PI/nCountTriangles * (nCountTriangles))) * fThickness;
output.Pos.z = 0.0f;
output.Pos.w = 0.0f;
output.Pos += positionPoint1Transformed;
output.Pos *= fPoint1w;
triangleStream.Append(output);
}
나는 그것이 매우 하드 알지만, 적어도 작동 :
다음
struct PS_INPUT
{
float4 Pos : SV_POSITION;
};
지오메트리 쉐이더 여기
pixelshader 입력 구조체 두꺼운 선이있는 입방체 (원근 투영에서 첫 번째, 정사영 투영에서 두 번째) 나는 이것을 누군가에게 도움이되기를 바랍니다. 두꺼운 선을 구현하는 것이 더 좋은 아이디어라면 의견을 남겨주세요.
이 종류의 벡터 그래픽 그리기를 수행하도록 설계된 Direct2D 만 사용해보십시오. –
@ChuckWalbourn 3D로 된 선 또한 Direct2D를 사용할 수 없습니다. Direct3D 11 만 사용할 수 있습니다. – Thomas
지오메트리 셰이더를 사용하여 쿼드 및 빌보드로 포인트를 확장하는 방법에 대해 생각해 보셨습니까? 기본적으로 한 점에 정점 A와 B 위치를 저장하고 확장 할 수 있습니다. 카메라 행렬에서도 카메라의 위쪽 벡터를 도출 할 수 있습니다. 따라서 권리에 따라 교차 제품을 계산하여 4 개 꼭지점을 생성 할 수 있습니다. 그게 문제의 일부일 뿐이지 만 카메라에서 거리에 따라 선 두께를 에뮬레이트하기 위해 정확한 너비를 계산해야합니다. 나는 그것이 단순한 선형 거리 관계라고 생각한다. – ErnieDingo