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.