포인트를 입력으로 삼고 삼각형 스트림을 출력하는 지오메트리 셰이더를 사용하여 빌보드를 렌더링하려고합니다 (DirectX11 사용). 그러나 현재 결과는 내가 기대하는 바가 아닙니다.빌보드 기하학 쉐이더 사용
비교를 위해 동일한 방향에서 보았을 때 매우 비슷한 입자 집합을 렌더링하는 두 개의 스크린 샷이 있습니다. (한 번 더 90 °까지 카메라를 회전시켜야 했음) 한 번 점으로 그리고 한 번 렌더링되었습니다. 내 광고판 쉐이더 렌더링 : 두 번째 그림에서 볼 수 있듯이, 포인트로 렌더링 할 때, 하나는 분명히 입자가 거의 전체를 덮고, 중심에서 멀리 이동하는 '것을 볼 수 있습니다
스크린 빌더 쉐이더로 렌더링 할 때, 스케일이 약간 변하지 만 항상 고정되어 있습니다.
불행히도, 나는 이것을 일으키는 원인에 대한 단서가 없습니다. 나는 this과 같은 튜토리얼을 따라 왔는데, 매트릭스가 어떻게 설정되어야하는지 설명하지만 결과는 내 기대 또는 구현이 잘못되었음을 보여줍니다. 다음
가빌보드 대한 두 개의 삼각형을 방출 한 후, 입자의 방향을 설명하는 행렬을 구축하고 빌보드 쉐이더위한 코드이다 : 참고로
#include <Materials/SceneConstants.hlsl>
#include <Materials/ModelConstants.hlsl>
#include <Particles/Particle.hlsl>
Texture2D diffuseTexture : register(ps, t[0]);
SamplerState diffuseSampler : register(ps, s[0]);
struct PS_IN
{
float4 Position : SV_POSITION;
float4 Color : COLOR;
float2 TexCoord : TEXCOORD;
};
Particle vs(Particle input)
{
return input;
}
[maxvertexcount(4)]
void gs(point Particle particles[1], inout TriangleStream<PS_IN> triStream)
{
// We need to create a matrix for the local coordinate system for the billboard of the given particle.
// One axis points from the particle to the camera, one axis is the camera's side axis (for example to
// the left) and the third one is perpendicular to both.
Particle particle = particles[0];
float3 zAxis = normalize(CameraPosition - particle.Position);
float3 xAxis = normalize(cross(float3(0, 1, 0), zAxis));
float3 yAxis = cross(zAxis, xAxis);
// The matrix to describe the local coordinate system is easily constructed:
float4x4 localToWorld;
localToWorld._11 = xAxis.x;
localToWorld._21 = xAxis.y;
localToWorld._31 = xAxis.z;
localToWorld._12 = yAxis.x;
localToWorld._22 = yAxis.y;
localToWorld._32 = yAxis.z;
localToWorld._13 = zAxis.x;
localToWorld._23 = zAxis.y;
localToWorld._33 = zAxis.z;
localToWorld._41 = particle.Position.x;
localToWorld._42 = particle.Position.y;
localToWorld._43 = particle.Position.z;
localToWorld._14 = 0;
localToWorld._24 = 0;
localToWorld._34 = 0;
localToWorld._44 = 1;
// And the matrix to transform from local to screen space...
float4x4 transform = localToWorld * World * ViewProjection;
// The positions of that quad is easily described in the local coordinate system:
// -z points towards the camera, y points upwards and x towards the right.
// The position marks the center of the quad, hence (0, 0, 0) is the center of the quad in
// local coordinates and the quad has an edge-length of particle.Size to either side.
PS_IN v1, v2, v3, v4;
//float size = particle.Size/2;
float size = 0.5f;
v1.Position = mul(float4(-size, size, 0, 1), transform);
v1.TexCoord = float2(0, 0);
v1.Color = particle.Color;
v2.Position = mul(float4(size, size, 0, 1), transform);
v2.TexCoord = float2(1, 0);
v2.Color = particle.Color;
v3.Position = mul(float4(-size,-size, 0, 1), transform);
v3.TexCoord = float2(0, 1);
v3.Color = particle.Color;
v4.Position = mul(float4(size, -size, 0, 1), transform);
v4.TexCoord = float2(1, 1);
v4.Color = particle.Color;
triStream.Append(v1);
triStream.Append(v2);
triStream.Append(v3);
triStream.Append(v4);
}
float4 ps(PS_IN input) : SV_TARGET0
{
/*float4 texel = diffuseTexture.Sample(diffuseSampler, input.TexCoord);
return input.Color * texel;*/
return float4(1, 1, 1, 1);
}
여기 용 쉐이더 코드 간단하게 포인트뿐만 아니라 입자를 렌더링 :
#include <Materials/SceneConstants.hlsl>
#include <Materials/ModelConstants.hlsl>
#include <Particles/Particle.hlsl>
struct PS_IN
{
float4 Position : SV_POSITION;
float4 Color : COLOR;
};
PS_IN vs(Particle input)
{
PS_IN output;
float4 posWorld = mul(float4(input.Position, 1), World);
output.Position = mul(posWorld, ViewProjection);
output.Color = input.Color;
return output;
}
float4 ps(PS_IN input) : SV_TARGET0
{
//return input.Color;
return float4(1, 1, 1, 1);
}
내가 눈치 또 다른 이상한 것은 내 광고판이 적어도 항상 카메라를 마주보고 있지 않은 것입니다. 내가 매트릭스를 설정하는 방식에서, 그러나, 나는 그들을 기대할 것이다. 대신 카메라는 두 개의 반대 방향에서 보았을 때만 카메라를 향한 다음 카메라 회전을 시작하자마자 너비를 줄입니다.
이것은 내가 매트릭스를 만드는 데 실수를했다고 믿게했지만, 나는 그것을 발견 할 수 없습니다.
여러분이 문제를 찾을 수 있도록 도와주세요. 도와 주셔서 미리 감사드립니다.
편집
나는 이것이 하나의 이유 그러나 내가 이해하지 못하는이 문제에 대한 해결책을 찾을 것으로 보인다. 기묘한 이유 때문에 localToWorld 행렬에 ViewProjection 행렬을 곱할 수 없습니다. 대신에, 나는과 같이 두 단계로 분리 할 수 있습니다
v1.Position = mul(float4(-size, size, 0, 1), localToWorld);
v1.Position = mul(v1.Position, ViewProjection);
이 경우 왜 이해가 안가, 어쩌면 그것은 row_major 행렬 대신 기본, column_major을 사용하여 연결된. 하지만 지금은 이러한 행동이 전혀 이상하지 않습니다. 행렬 곱셈은 연관 적이어야하며 위의 코드 조각은 원래 코드와 동일한 결과를 가져와야하지만 분명히 그렇지 않습니다. 어쩌면 당신 중 일부는 여기에서 벌어지는 일에 대해 밝힐 수 있습니다.
가 보이는 읽어야 당신이 행렬의 잘못된 부분에 번역 벡터를 가지고 생각합니다. – gareththegeek
그게 처음에 생각한거야, 그러나 이것은 "localToWorld"의 번역 부분을 particle.Position으로 설정하여 이루어져야합니다. 각 꼭지점의 위치는 행렬에 의해 변형되므로 위치에 따라 이동해야합니다. 그렇지 않아야합니까? – Simon