OpenGL은 여러 개의 겹치는 객체의 개요를 얻습니다.


10

c ++에서 opengl로 만든 진행중인 게임에 대한 아이디어를 얻었습니다. 플레이어가 무언가를 이길 때 겹치는 여러 객체에 큰 개요 (5-6 픽셀)를 갖고 싶습니다.

스텐실 버퍼를 사용하는 것이 가장 좋은 방법이라고 생각했지만 스텐실 버퍼의 화면 밖 렌더링을 시도하는 데 몇 시간이 걸리므로 probab과 같은 결과를 얻을 수 없습니다. 다른 기술이 있습니다!

이것이 내가 얻고 싶은 것입니다 :

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

어떤 아이디어?


가장자리 감지 필터를 사용하고 가장자리를 두꺼운 선으로 채운 다음 렌더링 된 도형의 이미지를 추출하고 색칠 된 선 레이어 위에 오버레이 하시겠습니까?
Shotgun Ninja

에지 감지 필터 란 무엇입니까? 쉐이더? 이미지 처리 필터? opencv (텍스처에 렌더링, 텍스처에 필터 적용, 수정 된 텍스처 푸시 백)?
nkint

나는 모른다 3D 렌더링에 익숙하지 않습니다.
Shotgun Ninja

이 같은 스텐실 버퍼의 예가 있습니까? 스텐실 버퍼를 사용하는 것이 더 깔끔한 방법이라고 생각하지만 스텐실 버퍼를 작동시킬 수 없습니다.
nkint

답변:


4
  1. 스텐실 버퍼를 활성화하고 지 웁니다.
  2. 스텐실 버퍼를 설정하여 객체를 그립니다. 객체는 반투명 등일 수 있습니다.
  3. 이제 스텐실 모드가 스텐실이 설정되지 않은 픽셀 만 쓰도록 설정하십시오.
  4. 원하는 테두리 색상과 질감없이 각 개체를 약간 확대하여 다시 그립니다.
  5. 스텐실 버퍼를 비활성화합니다.

내가 일하고있는 일부 webGL 스텐실 코드에서 수정 된 코드는 다음과 같습니다.

// drawing will set stencil stencil
    gl.enable(gl.STENCIL_TEST);
    gl.stencilFunc(gl.ALWAYS,1,1);
    gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE);
    gl.stencilMask(1);
    gl.clearStencil(0);
    gl.clear(gl.STENCIL_BUFFER_BIT);
// draw objects
for(var object in objects)
  objects[object].draw();
// set stencil mode to only draw those not previous drawn
    gl.stencilFunc(gl.EQUAL,0,1);
    gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
    gl.stencilMask(0x00);
// draw object halo
for(var object in objects)
  objects[object].drawHalo(1.1,red); // each mesh should be individually scaled e.g. by 1.1
// done
    gl.disable(gl.STENCIL_TEST);

나는 RTS 게임 에서이 접근법을 사용하여 선택한 단위 주위에 후광을 그렸지만 오래 전에 일어 났으며 어떤 뉘앙스와 뉘앙스가 있는지 기억 나지 않습니다.


이 같은 스텐실 버퍼의 예가 있습니까? 스텐실 버퍼를 사용하는 것이 더 깔끔한 방법이라고 생각하지만 스텐실 버퍼를 작동시킬 수 없습니다.
nkint

7
약간 확대 된 객체를 렌더링하면 균일 한 선 두께가 생성되지 않습니다. 가장자리가 멀수록 얇아집니다. 물체의 크기를 조절할 때이 점을 고려하면, 거리까지 뻗어있는 긴 물체의 두께는 균일하지 않습니다. 이 효과에는 조금 더 선이 멋지고 고르게 만들어집니다.
Sean Middleditch

2
단순히 객체를 확장하는 것보다 각 정점을 법선을 따라 짧은 거리만큼 오프셋하는 정점 셰이더를 작성하는 것이 좋습니다. 부드러운 물체에는 잘 작동하지만 단단한 가장자리에 균열이 생길 수 있습니다. 어디에서나 부드럽게되는 대체 법선 세트로 메시를 만들 수 있으며 어디로 가는지 알 수 있습니다.
Nathan Reed

2

모든 객체 그룹을 찾는 것으로 시작하십시오. 여기서 객체 그룹은 겹치는 객체 모음입니다. 표준 충돌 감지가 작업을 수행해야합니다. 각 그룹에 고유 한 색상을 지정하십시오. 어떤 색상이든 가능합니다.

그룹 색상을 사용하여 텍스처에 모든 객체를 단색으로 렌더링합니다.

렌더 대상과 치수가 동일한 새 윤곽선 텍스처를 만듭니다. 렌더 타겟의 각 텍셀을 스캔하여 주변 텍셀과 다른 색상인지 확인합니다. 그렇다면 외곽선 텍스처의 해당 텍셀을 원하는 선 색상으로 변경하십시오.

마지막으로이 윤곽 텍스처를 가져 와서 화면에 그리려는 이미지의 상단에 렌더링합니다 (물론 조각 쉐이더의 가장자리 감지와 동시에이를 수행하여 첫 번째 가장자리 텍스처를 만들지 않아도됩니다) 장소).

for 루프를 사용하여 렌더링 대상의 텍셀을 통과하여 CPU에서이 단계를 수행하면 속도가 느리지 만 테스트 및 사용하기에 충분할 수 있습니다. 이것을 실시간으로 사용하려면 이것을 셰이더에서 처리하는 것이 가장 좋습니다.

이 가장자리 감지를위한 프래그먼트 셰이더는 다음과 같습니다.

precision mediump float;

uniform sampler2D s_texture;

varying vec2 v_texCoord;

void main()
{
    gl_FragColor = vec4(0.0);

    vec4 baseColor = texture2D(s_texture, v_texCoord);
    gl_FragColor += baseColor - texture2D(s_texture, top);
    gl_FragColor += baseColor - texture2D(s_texture, topRight);
    gl_FragColor += baseColor - texture2D(s_texture, right);
    gl_FragColor += baseColor - texture2D(s_texture, bottomRight);
    gl_FragColor += baseColor - texture2D(s_texture, bottom);
    gl_FragColor += baseColor - texture2D(s_texture, bottomLeft);
    gl_FragColor += baseColor - texture2D(s_texture, left);
    gl_FragColor += baseColor - texture2D(s_texture, topLeft);
}

texture2D 조회의 두 번째 값은 v_texCoord를 기준으로 2d 좌표입니다. 첫 번째 렌더 대상을 전체 화면 쿼드의 텍스처로 렌더링하여이를 적용합니다. 이것은 구 아시안 흐림과 같은 전체 화면 흐림 효과를 적용하는 방법과 유사합니다.

단색으로 첫 번째 렌더 타겟을 사용하는 이유는 단순히 서로 다른 객체간에 겹치는 가장자리가 없는지 확인하기 위해서입니다. 화면 이미지에서 단순히 가장자리 감지를 수행 한 경우 겹치는 부분의 가장자리도 감지 할 수 있습니다 (물체의 색상 / 텍스처 / 조명이 다른 경우).


2
죄송하지만 "각 텍셀을 통해 스캔"은 무슨 뜻입니까? 각 픽셀을 통해 for 루프? CPU에? 그래서 그것은 단색으로 텍스처에 렌더링하고, 이미지를 CPU로 전송하고, 스캔을하고, 텍스처에 다시 넣습니까? 아니면 쉐이더에서합니까?
nkint

포스트 프로세스 블러 효과를 수행하는 것과 비슷한 방식으로 렌더 대상을 텍스처로 사용하여 전체 화면 쿼드를 렌더링하여 쉐이더에서 수행하는 것이 바람직하지만, 먼저 for 루프로 CPU에서 작업하도록 할 수 있습니다. 제대로 작동하면
OriginalDaemon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.