OpenGL-모서리 감지


12

임의의 메쉬를로드하고 가장자리를 따라 두꺼운 검은 선을 그려 툰 쉐이딩처럼 보이게하고 싶습니다. 스텐실 버퍼를 사용하여 객체 주위에 검은 실루엣을 그렸습니다. 결과는 여기에서 볼 수 있습니다.

여기에 이미지 설명을 입력하십시오

그러나 누락 된 것은 객체 자체의 검은 선입니다. 정규 불연속 검사에 대해 생각했습니다. 인접 픽셀이 현재 픽셀과 다른 법선 벡터를 갖는지 확인합니다. 그렇다면 가장자리를 찾았습니다. 불행히도 OpenGL이나 GLSL 버텍스 / 프래그먼트 셰이더 에서이 접근법을 어떻게 구현할 수 있는지 잘 모르겠습니다.

이 방법에 대한 도움이나 가장자리 탐지에 관한 도움에 매우 기쁩니다.

편집 : 메쉬에 텍스처를 사용하지 않습니다.

더 정확하게 말하자면, 가능한 한 많이 보이는 CAD / CAM 솔루션을 만들고 싶습니다 (Top Solid https://www.youtube.com/watch?v=-qTJZtYUDB4 ).

여기에 이미지 설명을 입력하십시오


"가장자리"를 더 자세하게 정의해야한다고 생각합니다. 간단한 와이어 프레임과 어떻게 다릅니 까? cifz 답변에는 화면 공간 사후 프로세스에 대한 좋은 설명이 있지만 질문에서 적용 가능한지 결정하기가 어렵습니다.
Andreas

글쎄, 가장자리와 나는 고체를 형성하는 "주름"과 "마루"를 의미합니다. 와이어 프레임에는 모든 삼각형면이 표시되지만 원하는 것은 아닙니다.
enne87

좋아, 정확히 내가 요청한 것은 :-) 주름과 융기 부분에서 와이어 프레임을 생성합니다. 까다로운 부분은 여전히 ​​주름 / 리지가 무엇인지 확인하는 것입니다. 그렇게하는 방법에 대한 아이디어가 있습니까?
Andreas

1
cad 프로그램은 대부분 셰이더를 사용하여이 작업을 수행하지 않습니다. 대신 모델의 단단한 가장자리를 알고 해당 정보의 메쉬 위에 선을 그립니다.
joojaa

joojaa이 기술에 대한 정보가 더 있습니까? 이중 곡면 자유 곡면의 경우 어떻게됩니까? 또한 자유로운 형태로 잘라내거나 잘라지는 원뿔이나 실린더가있을 때 어떤 일이 발생하는지 잘 모르겠습니다. stackoverflow.com/questions/43795262/…
두산 Bosnjak 'pailhead'Jul

답변:


18

일반적으로 가장자리 감지 기능이 다운되어 높은 경사도 값으로 이미지 영역을 감지합니다.

우리의 경우 이미지 함수의 파생물로 그라디언트를 대략적으로 볼 수 있으므로 그라디언트의 크기는 이미지가 로컬 에서 얼마나 많이 변경 되는지에 대한 정보를 제공합니다 (인접한 픽셀 / 텍셀과 관련).
이제 가장자리는 불연속의 표시라고 말 했으므로 이제 그라디언트를 정의 했으므로이 정보 만 있으면됩니다. 이미지의 그라디언트를 찾으면 이진 값 에지 / 비 에지 값을 얻기 위해 임계 값을 적용하기 만하면됩니다.

이 그라디언트는 실제로 당신이 요구하는 것인데 어떻게 대답하지 않습니까?

많은 방법! 여기에 몇 가지 :)

내장 셰이더 기능

hlsl과 glsl은 모두 미분 함수를 제공합니다. GLSL 에는 x와 y 방향의 그라디언트 정보를 제공하는 dFdx와 dFdy 가 있습니다. 일반적으로 이러한 기능은 2x2 조각으로 평가됩니다.
단일 방향에 관심이 없으면 영역의 그라디언트가 얼마나 강한 지 나타내는 컴팩트 한 결과를 얻는 좋은 방법 은 dFdy와 dFdy의 절대 값의 합 외에 다른 것을 제공하지 않습니다.
특정 채널이 아닌 전체 이미지의 가장자리에 관심이있을 수 있으므로 이미지 기능을 루마로 변환 할 수 있습니다. 이를 염두에두고, 가장자리 감지와 관련하여 쉐이더는 다음과 같은 것을 포함 할 수 있습니다.

  float luminance = dot(yourFinalColour,vec3(0.2126, 0.7152, 0.0722));
  float gradient = fwidth(luminance );
  float isEdge = gradient > threshold;

임계 값이 높으면 가장자리가 거칠고 반대로 임계 값이 낮 으면 잘못된 가장자리를 감지 할 수 있습니다. 요구 사항에 더 적합한 임계 값을 찾기 위해 실험해야합니다.

이러한 기능이 작동하는 이유는 언급 할 가치가 있지만 지금은 시간이 없습니다. 나중에이 답변을 업데이트 할 가능성이 큽니다.

화면 공간 후 처리

이보다 더 멋진 경험을 할 수 있습니다. 이제 이미지 처리에서 가장자리 감지 필드가 엄청납니다. 필요에 따라 에지 감지를 감지하는 수십 가지 좋은 방법을 인용 할 수는 있지만, 지금 당장 간단하게 유지하십시오. 관심이 있으시면 더 많은 옵션을 인용 할 수 있습니다!

따라서 아이디어는 위의 것과 비슷하지만 더 넓은 이웃을보고 원하는 경우 해리 운딩 샘플에 가중치 세트를 사용할 수 있다는 차이점이 있습니다. 일반적으로 좋은 그라디언트 정보를 제공하는 커널을 사용하여 이미지를 컨볼 루션으로 실행합니다.
가장 일반적인 선택은 Sobel 커널입니다

                                   여기에 이미지 설명을 입력하십시오

각각 x 및 y 방향의 그라디언트를 제공합니다.

                                  오래된 pdf에서 나는 오래 전에 썼다.

와 같이 기울기에서 단일 값을 얻을 수 있습니다.GradientMagnitude=(Gradientx)2+(Gradienty)2

그런 다음 위에서 언급 한 것과 같은 방식으로 임계 값을 지정할 수 있습니다.

보시 다시피이 커널은 중앙 픽셀에 더 많은 가중치를 부여하므로 그라디언트 + 약간의 스무딩을 효과적으로 계산하는 데 도움이됩니다.

위의 내용은 잘 작동하지만 스무딩이 마음에 들지 않으면 Prewitt 커널을 사용할 수 있습니다.

                                                   여기에 이미지 설명을 입력하십시오

(참고로 서두르면 곧 이미지 대신 적절한 형식의 텍스트를 작성합니다!)

실제로 실시간 그래픽이 아닌 이미지 프로세스 방식으로 에지 감지를 찾을 수있는 커널과 기술이 훨씬 더 많으므로 dFdx / y 함수를 사용하면 더 복잡한 방법을 배제 할 수 있습니다. .


아주 좋은 설명 cifz, 그러나 특정 상황에서 그래디언트가 보이지 않으면 어떻게합니까? 예를 들어, 큐브 뒷면에 광원이 없으므로 그래디언트가 보이지 않습니다. 그런 다음 이미지 기반 가장자리 감지 프로세스가 작동하지 않습니다. 맞습니까?
enne87

디퍼 드 렌더러를 사용하는 경우 일반 버퍼에서 동일하게 또는 다시 수행 할 수 있으며 프리 패스가있는 경우 알고리즘을 깊이에 적용 할 수 있습니다. 화면 공간 접근 방식이 모든 경우에 이상적이지는 않을 수도 있습니다. :) 실행 가능한 솔루션은이 효과의 예산, 장면의 복잡도에 따라 다릅니다.
cifz

잠재적으로 이것이 게임의 중심에 있다면, 매우 쉽지만 잠재적으로 과세되면 각 정점 (로드 시간에 오프라인)에 대한 이웃 법선의 그라디언트를 계산 하고이 요소를 추가 정점 속성으로 전달합니다.
cifz

당신의 도움을 위해 다시 cifz를 움직입니다. 글쎄, 내가 달성하고자하는 것은 다음과 비슷한 CAD / CAM 솔루션을 개발하는 것입니다 : youtube.com/watch?v=-qTJZtYUDB4 그리고 나는 그들이 모든 검은 가장자리, 주름을 렌더링하기 위해 어떻게 관리했는지 알고 싶습니다. 능선. cifz, 스크린 공간 접근 방식 중 하나를 사용하여이 모양을 달성 한 그래픽 프로그래밍 전문가라고 생각하십니까? 아니면 이웃 법선의 기울기를 계산하여? 나는 이것이 어떻게 이루어질 수 있는지 정말로 알고 싶다. 다시 감사합니다!
enne87

1
누구에게도 비용을 지불 할 필요는 없으며 온라인에서 몇 가지 자습서를 읽고 책을 구입하고 열심히 공부하십시오. :) 결국에는 매우 보람이있을 것입니다!
cifz

3

: 그냥 경우에 사람이 ELSO 또한 가장자리를 감지 할 필요가 여기에 와이어 프레임을 표시하는 방법 좋은 기사이며 문서에서는 가장자리를 표시하는 방법에 대해 설명합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.