물체가 표면 근처에있을 때 점등되는 쉐이더를 작성하려면 어떻게해야합니까?


15

에서 오버 워치 게임 플레이 영상 , 캐릭터의 방패는 다른 객체의 형상 근처 지역에 흰색 불이 들어옵니다.

일부 레벨 형상을 클리핑하는 라인 하르트의 방패

바닥, 벽 및 기둥 근처의 파란색 실드의 흰색 가장자리를 확인하십시오.

쉴드는 자체 모델을 가지고 있으며 그 효과는 셰이더로 수행된다고 생각하지만 "근접성"개념을 셰이더 프로그래밍으로 변환하는 방법을 찾지 못했습니다.


2
Unity를 사용하는 경우이 대화가 흥미로울 수 있습니다 . 슬라이드 26에서 시작하는 "교차점 하이라이트"섹션을 확인하십시오.
DMGregory

이에 대한 답변은 이미 아래에 나와 있지만 여기에 설명되어있는 비디오가 있습니다. youtube.com/watch?v=C6lGEgcHbWc
CobaltHex

답변:


28

일반적인 개요 :

  1. 실드없이 장면 의 깊이 맵 을 만듭니다 . 투명한 객체는 나중에 패스로 렌더링되기 때문에 무료로 효과적으로 얻을 수 있습니다. 그렇지 않으면 장면 셰 이즈 쉴드를 깊이 셰이더 를 사용하여 RTT 에 렌더링하여 깊이 맵을 만들 수 있습니다 .

  2. 장면을 정상적으로 렌더링하고 깊이 맵을 방패 셰이더에 전달하십시오.

  3. 셰이더에서 실드 조각의 깊이와 장면 깊이의 차이를 계산하고 그 차이를 사용하여 조각 색상을 수정하십시오.

데모

간단한 WebGL 데모를 작성했습니다.

데모 스크린 샷

한 줄씩

프래그먼트 셰이더 코드를 자세히 살펴 보겠습니다.

float solidsDepth = texture2D(depthMap, gl_FragCoord.xy / dims).r;

모든 조각에서 깊이 맵을 샘플링하십시오. 조각을 화면 공간 [0, 너비 / 높이]에서 정규화 된 [0.0, 1.0] 좌표로 변환하려면 뷰포트 크기로 나눕니다. 이 시점에서 프래그먼트 색상을 샘플링 된 깊이 맵 픽셀로 설정하면 다음과 같습니다.

깊이 맵의 스크린 샷

깊이 맵은 회색조이므로 모든 채널에서 값을 얻을 수 있습니다 ( r여기에서 사용 했습니다).

float solidsDiff = 1.0 - smoothstep(
    zNear,
    zFar,
    gl_FragCoord.z / gl_FragCoord.w
  ) - solidsDepth;

그런 다음 해당 깊이 샘플을 사용하여 장면 깊이와 실드 조각 깊이 간의 차이를 찾을 수 있습니다. [zNear, zFar] (카메라의 가까운 평면과 먼 평면)에서 [0.0, 1.0]으로 가져 오려면 깊이를 정규화해야합니다. smoothstep이 잘한다. 는 1.0 -같은 값을 반전하는 solidsDiff최소 (0.0)에서 0.0 - 차가 최대 (zNear zFar) 인 경우 1.0이다.

필자는 solidsDepth깊이 맵을 만든 깊이 쉐이더에서 이미 정규화 되었다고 가정 합니다.

float alpha = 0.3 + max(0.0, 1.0 - log(100.0 * (solidsDiff - 0.005) + 1.0));

그런 다음 깊이 차이에 따라 방패의 알파 채널을 수정할 수 있습니다. 여기서 우리는 최소 알파인 0.3에서 시작한 다음 차이 가 가까워 질 수록 알파가 크게 급격히 증가0.0 합니다.

- 0.005단지 "교차로"두껍게 만들기 위해 흰색 여백을 추가 오프셋. 수정 해보십시오!

gl_FragColor = vec4(vec3(1.0), alpha);

마지막으로 해당 알파를 조각 색상에 적용하십시오.


향상

곡선 쉴드를 만들거나 , "에너지 쉴드"모양 (데모)을위한 플라즈마를 추가 하거나 교차점 (demo) 만 표시 하여 효과를 탐색 할 수 있습니다 .

하늘 그래픽 카드가 한계입니다!


오. 나의. 좋은 소식. 멋진 튜토리얼을 위해 타이.
Blue Bug

5

깊이 맵을 사용하고 있습니다. 월드를 렌더링 한 다음 쉴드를 렌더링하고 쉴드의 렌더링 된 z 값과 깊이 버퍼 z 값의 차이를 사용하여 픽셀을 더 흰색으로 채 웁니다.


3

어떤 엔진을 사용하고 있는지 잘 모르겠습니다. 또는 어떤 언어로 작업하고 있습니까? 그러나 온라인에서 찾을 수있는 대부분의 항목은 원하는 환경을 얻기 위해 한 환경에서 다른 환경으로 이식하기가 어렵지 않습니다.

그리고 확실히 당신에게 도움이 될 수있는 자료가 온라인에 있습니다. Unity와 관련된이 토론을 참조하십시오 : http://www.superspacetrooper.com/2012/06/tutorial-force-field-weapon-impact-energy-dispersion/ 이 질문 UE4 관련 : https : //answers.unrealengine. com / questions / 74858 / dynamic-forcefield-shader.html . 완전한 쉐이더 예를 들어, 레딧에서 아주 최근의 논쟁에서 그 차폐 효과를 구현, 당신은 볼 수 https://www.reddit.com/r/Unity3D/comments/3edi0n/does_any_one_knows_how_to_make_this_shield_effect/ 그리고 튜토리얼 그것은 아니다 정확히 그것에 관심이 있지만 관심이있을만큼 관련이 있습니다 : http://www.nightbox-studios.com/2015/09/05/assets-shield-effect-scripts-for-texture3d-perlin-noise-shader/

또한이 사이트에서 이전에 작성한 3 가지 관련 질문에 대한 링크는 다음과 같습니다. 달성하려는 목표의 개념을 이해하는 데 큰 도움이 될 것입니다.

우주선 방패 플레어

게임에서 스타 워 에너지 쉴드를 구현하는 방법

원시 영역 문제가있는 XNA 차폐 효과

마지막으로, 해당 엔진 중 하나를 사용하는 경우 Unity 및 Unreal Engine 모두에서 각각의 가상 저장소에 쉴드 셰이더를 구현하는 것이 몇 가지 있습니다. 그들은 일반적으로 물론 자산을 지불하지만 구입 후 거의 항상 오픈 소스이며 종종 저렴합니다. 이러한 엔진을 사용하지 않더라도 이러한 자산은 놀아 배우고 배우는 데 도움이 될 수 있습니다.

도움이 되길 바랍니다.


이러한 링크가 도움이 되더라도이 답변은 기본적으로 링크 일 뿐이며 실제로 직접 질문을 다루지는 않습니다. 링크의 관련 내용을 실제 설명으로 추출하는 것이 좋습니다.
Anko

이 링크가 질문에 대한 답변을 제공 할 수 있지만 여기에 답변의 필수 부분을 포함시키고 참조 용 링크를 제공하는 것이 좋습니다. 링크 된 페이지가 변경되면 링크 전용 답변이 유효하지 않을 수 있습니다. - 검토에서
Vaillancourt

@Anko 물론입니다. 나는 일반적으로 설명과 링크 모음을 포함하지만 이번에는 당신이 옳았다. 실제 설명은 빠졌다. 아마 대답을 삭제하겠습니다.
MAnd

@AlexandreVaillancourt OP를 원래 소스로 리디렉션하는 대신 다른 링크에서 복사하여 붙여 넣는 아이디어가 마음에 들지 않습니다. 그렇다면 내가 생각하는 가장 좋은 것은 질문에 대한 의견에 링크를 제공하는 것입니다. 그러한 문제는 도움이 될만한 자료를 많이 알고 있지만 설명하기에는 너무 큽니다. 그러나 여전히 좋은 설명 답변이 이미 여기에 게시
되었으므로이 질문을
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.