티스토리 뷰
관련 글은 Game programming gem 2권에 존재한다.
http://www.gpgstudy.com/gpg2/gpg2s5-1draft.html
몇몇 방법은 너무 오래되었다.
물론 거기서 normal 확장 방법을 설명하는데 그건 아직 현역이다.
그냥 단순히 구현한다면,
float3 pos = input.position + input.normal * EdgeSize * 0.01;
matrix clipToProj = mul(projection, mul(view, model));
return mul(clipToProj, float4(pos, 1.0));
아래와 같이 가까워지면 굵어지는 문제 존재한다
굵기를 고정시키려면, 카메라와의 거리를 고려해야한다.
아래 방법은 대충 비례식이 맞는거 같은데
y/posVS.z = halfTan (화면 거리에 따른 높이 비례)
y = posVS.z * halfTan
(화면의 높이 비례 = 현재 z 축의 높이 대비 a 의 크기 비례)
outline / height * 2 = a / y
outline / height * 2 * y = a
outline / height * 2 * posVS.z * halfTan = a
posVS.xyz += normalVS * posVS.z * 2 * outline / height * halfTan;
작동을 하지 않았다.
그냥 camera 대비 거리 비교 구문은 잘 동작하였다.
대략 모델의 거리를 카메라와 비교하여 사용한다.
MMDAI's source code
IVertex::EdgeSizePrecision Model::edgeScaleFactor(const Vector3 &cameraPosition) const
{
IVertex::EdgeSizePrecision length = 0;
if (m_context->bones.count() > 1) {
IBone *bone = m_context->bones.at(1);
length = (cameraPosition - bone->worldTransform().getOrigin()).length() * m_context->edgeWidth;
}
return length / IVertex::EdgeSizePrecision(1000.0);
}
저 값을 넘기기 약간 애매하기 때문에 VS 공간에서 거리를 찾아오는
루틴을 작성하였다.
float4 vsOutline(VertexInput input) : SV_POSITION
{
matrix toView = mul(view, model);
float3 posVS = mul(toView, float4(input.position, 1));
float scale = length(posVS.xyz) / 1000;
posVS = posVS + normalVS * EdgeSize * input.edgeScale * scale;
matrix viewToClip = mul(projection, toView);
return mul(viewToClip, float4(pos, 1.0));
}
다만, 멀어졌을때 아래와 같이 윤각선만 튄는데 깨끗하지 않다.
FXAA로는 못잡는듯 변화가 없다
TempolarAA 나 SMAA 추가했을 경우 어케되는지 확인 필요하다.
문제는 아래와 같이 vertex가 작고 선이 굵은 모델의 경우 이상하게 나타난다
또한, Lighting 기반으로 한 모델에서는 어색해보인다.
'Game > MMD' 카테고리의 다른 글
Deferred Rendering (2) (0) | 2017.10.02 |
---|---|
Tone mapping (3) (0) | 2017.09.22 |
Deferred Rendering (1) (0) | 2017.09.19 |
Bullet (5) Skinning (0) | 2017.08.31 |
Bullet (5) Skinning (0) | 2017.08.31 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크