TECHARTNOMAD | TECHARTFLOWIO.COM

TECH.ART.FLOW.IO

[번역] 플루이드 플럭스 2.0 근해 파도

jplee 2024. 6. 28. 17:08

역자의 말. 
꽤나 오랜 시간동안 이런 바다와 근해 렌더링 업무에서 떨어져 있다보니 최근 플루이드 플럭스 등의 효과등을 보고 무척 놀랄때가 많습니다. 최근 개발하고 있는 게임에서도 물 표현이 조금 등장 하는데요... 같은 팀의 팀원분이 약간 더 보강하기로 했지만 트렌드세터? 답게 요즘 어떻게 돌아가고 있는지 좋은 기사를 올려주신 중국의 다자령 TA 의 기사를 살펴보고 싶었습니다.


저자:다자령(戴子玲 : daijjeuring )

작년 말에 저는 UE5 마켓플레이스에 있는 플러그인의 물결을 맹목적으로 분석했습니다 - 플루이드 플럭스 1.0 물 효과-그다지 깊게 공부하지 않았습니다.

 

https://zhuanlan.zhihu.com/p/588195833

 

zhuanlan.zhihu.com

올여름 플루이드 플럭스의 개발사인 ImaginaryBlend는 오픈 월드의 거대한 해안선 파도를 지원하는 버전 2.0을 출시하여 놀라운 결과물을 선보였습니다.

 

虚幻引擎5!Fluid Flux 2.0 海岸线!_哔哩哔哩_bilibili

https://www.youtube.com/watch?v=zLmiqJJI5ZQ&t=11s 转~虚幻引擎5!Fluid Flux 2.0 海岸线! 喜欢++++关注

www.bilibili.com

새로운 FF 2.0 동영상을 보자마자 이 효과를 요청했습니다.

이 글에서는 플루이드 플럭스 2 근해파를 분해하고 Unity로 포팅한 경험을 기록하고, 플루이드 플럭스 2 근해파를 포팅하는 비용 효율적이고(?) 프로세스 친화적인 접근 방식을 소개합니다. 비용 효율적이고 프로세스 친화적인 접근 방식을 소개합니다.

엔지니어링 프로젝트

 

GitHub - DaiZiLing/Flux2-Shoreline-Wave-HLSL

Contribute to DaiZiLing/Flux2-Shoreline-Wave-HLSL development by creating an account on GitHub.

github.com

대부분의 키 노드에서 hlsl 함수로 변환된 FF2 수면 머티리얼  M_FluxSurfaceOver  안에 있는 이 프로젝트는 셰이더로 직접 열어 사용할 수 없다는 점에 유의하세요.

이론적으로는 독자가 게임을 코드로 번역할 수도 있지만, 저는 이미 동료 IRIN의 도움을 받아 이 작업을 수행했기 때문에 독자는 이 단계를 생략할 수 있습니다!

단일 레이어 셰이딩 모델 코드가 포함되어 있지 않으므로 이를 사용하려는 독자는 ue에서 유니티로 해당 코드를 가져와야 합니다.

pbr과 관련된 조명 함수를 포함하지 않음, 내 계산 출력은 ue MaterialAttributes와 동일, 독자는 BaseColor, Roughness 및 기타 매개 변수를 사용하여 자신의 pbr에 출력해야합니다.

유체 플럭스 2 내의 모든 에셋의 복제 및 배포는 포함되지 않으며, 씬 지형에 대한 메시 및 텍스처 에셋을 포함하되 이에 국한되지 않습니다. 이 글에 언급된 매핑 에셋과 이 글의 데모 이미지에 있는 씬 및 그 지형은 독자가 FF 플러그인에서 추출해야 합니다.

쇼케이스

언리얼 엔진에서 FF2의 모습은 다음과 같습니다.

아래는 제가 포팅한 Unity 내 이펙트로, 디테일 노멀, 스플래시 파티클, 커스틱스는 추가하지 않았습니다.

유니티 쇼케이스 내부(클로즈업)
유니티 쇼케이스 내부(클로즈업)

Unity 디버그 뷰의 주요 메시지는 다음과 같습니다.

  • 월드스페이스 노멀

버텍스 변위

Transmission

알파

분해

FF 플러그인의 수역은 총 다음과 같은 구성 요소로 이루어져 있습니다.

  • Vertex Aniamtion
  • Shading
  • Interation

一、Vertex Aniamtion - 버텍스 애니메이션

Meshing - 그리드 세분화

다양한 바다 메시 밀도를 표현하기 위해 FF2는 카메라 거리를 기준으로 씬에 64개의 동일한 3w 면을 배치하는 "NS_InfiniteSurfaceMesh"라는 나이아가라 시스템을 사용하여 "SM_FluxPlane128x128 "를 사용하여 메시의 LOD를 생성합니다.

SM_FluxPlane128x128

메시를 위해 나이아가라의 GPU 구동 기능을 차용했는데, 이는 매우 멋진 방법입니다!

NS_InfiniteSurfaceMesh를 열면 이름에서 알 수 있듯이 두 개의 이미터가 있는데, 가까운 곳의 메시 니어와 먼 곳의 메시 파가 있습니다.

NS_InfiniteSurfaceMesh

로드 카메라와 NMS 표면 그리드 위치는 표면을 배치하는 데 사용되며, NMS 플럭스 상태 데이터는 머티리얼에 정보를 전송합니다.

FF 프로젝트에는 M_DebugGrid라는 머티리얼이 있는데, 이 머티리얼의 BaseColor는 메시의 UV이며, 이를 메시의 머티리얼로 사용하면 메시 LOD가 쿼드 트리와 같은 분포를 갖는 것을 볼 수 있습니다. 카메라가 떨어지면 가장 가까운 SM_FluxPlane128x128이 1에서 4로 전환됩니다.

NMS Surface Grid Location

이 나이아가라 기능이 구현되는 방식은 FF2의 워터 컬러링에는 메시 자체에 어트리뷰트가 필요하지 않고 버텍스 위치 외에는 추가 정보가 없으며 UV나 버텍스 컬러도 필요하지 않으므로 Unity로 옮기는 데 아무런 영향을 미치지 않습니다.

Unity에서는 충분히 많은 수의 면을 가진 메시를 준비하면 충분하며, CDLOD와 같은 것을 사용하여 생성할 수 있습니다.

연속적인 거리 의존적 디테일 레벨

Vertex Displacement - 버텍스 변위

FF1에서 먼 바다 파도의 버텍스 애니메이션은 게르스트너 파도이고, 가까운 바다 파도는 실시간으로 해결된 파도입니다.

FF1 

FF1의 이매지너블블렌드 문서에 따르면 실시간 해결된 물은 여러 RT를 사용하므로 대규모 바닷물을 렌더링하기에는 오버헤드가 너무 많은 오픈 월드에는 적합하지 않으므로 FF2의 근해 파도 솔루션을 도입했다고 설명합니다.

FF1 멀티 RT

FF 2에서는 RT를 사용하지 않았고, 원거리 파도 버텍스 애니메이션에는 구운 FFT 플립북을, 근거리 파도 버텍스 애니메이션에는 벡터 디스플레이스먼트 텍스처(아래 VDM)를 사용했습니다.

상상블렌드는 여러 웨이브 프로파일을 그려 웨이브 메시로 합성한 다음 VDM을 베이크할 수 있는 BP_FluxWaveProfileGenerator 툴을 제공합니다. Z축 변위만 있는 FF1에 비해 FF2 웨이브 VDM은 웨이브 팁이 구부러지고 끊어지는 효과가 있습니다.

BP_FluxWaveProfileGenerator

 

ue 프로젝트의 BP_FluxWaveProfileGenerator를 열면 이 VDM은 평범한 정적 변위 맵에 불과하며, 이를 단독으로 꺼내 vertex.postionWS += displacement.xyz를 실행하면 웨이브가 움직이지 않습니다.

BP_FluxWaveProfileGenerator

정말 멋진 점은 FF2가 이 VDM 바이파티트(매핑 워프 모드는 X축 워프, Y축 클램프)를 해안선 위에 펼쳐서 동적으로 플레이한다는 것입니다!

일반적으로 오브젝트의 가장자리에 흑백 전환 그라데이션이 있는 경우(예: DistanceToNearestSurface 노드 사용), 이 전환에 매핑 바이파티트를 맞추기가 매우 어려운데, 이는 흑백 전환이 하나만 있기 때문입니다(즉, UV의 Y축만 샘플링에 사용할 수 있기 때문입니다).

DistanceToNearestSurface 示例

일반적인 폭력적인 해결책은 오브젝트 주위에 메시 원을 생성하거나 손으로 배치하고 메시의 UV를 사용하여 텍스처를 배치하는 것인데, 오픈 월드에서는 절대 해서는 안 되며 장인은 손에 든 칼을 조용히 들어 올립니다.

이미지 소스:www.gamedeveloper.com/programming/how-to-create-a-semi-procedural-cartoon-foam-shader

 

이 문제를 해결하기 위해 FF2는 웨이브 생성을 구동하기 위해 지형에 대한 다음 정보를 구워냅니다. 4개의 채널 모두 우수한 선형 보간 특성을 가지고 있으므로 3킬로미터의 지형에는 512개의 맵이면 충분합니다.

  • 해안에서 바라본 수면 컬러링 포인트 sdf
  • 오버헤드 깊이 차트
  • 지형의 오버헤드 경사도 ddx ddy

FF2 프로세스 내 sdf, 지면 깊이, gradient.xy

 

지형의 기울기는 파도의 방향을 결정하는 데 사용되며, 이 기울기 값의 색상 전환을 사용하여 X축 방향의 UV를 계산할 수 있습니다.

아래 그림은 화살표 방향(즉, 해안 방향)을 따라 G채널의 녹색이 점진적으로 감소하는 모습을 보여줍니다.

위 그림에서 계산된 결과를 샘플링된 VDM의 UV X축으로, 베이크된 sdf를 Y축으로 사용하여 해안을 따라 수평으로 재생되는 VDM의 UV 마스크를 얻습니다.

 

이 네 가지 맵을 사용하여 FF2에서 지형을 굽는 것은 해안의 마스크를 계산하고 약간 손질한 후 다양한 노이즈와 파도 텍스처로 작업하는 엔비디아 웨이브웍스 솔루션과 동일합니다. FF2의 근해 파도에 비해 웨이브웍스 효과는 훨씬 더 스크러시한 느낌을 줍니다.

웨이브웍스에서는 컴퓨트 셰이더를 사용하여 오프라인 툴로 sdf 및 그레이디언트 계산을 구워내는데, 계산된 결과가 FF2와 정확히 같지는 않지만 비슷합니다. 이제 웨이브웍스는 소스 코드를 볼 수 없으며, 심지어 ue 4.27 통합 버전 gihub도 사라졌으며, 다음은 언리얼 4.18 컴퓨트 셰이더의 웨이브웍스입니다.

https://github.com/windystrife/UnrealEngine_NVIDIAGameWorks/blob/4.18-GameWorks/Engine/Shaders/Private/GFSDK_WaveWorks_ShoreLineDistanceField.usf

 

UnrealEngine_NVIDIAGameWorks/Engine/Shaders/Private/GFSDK_WaveWorks_ShoreLineDistanceField.usf at 4.18-GameWorks · windystrife/

This repository contains stable builds of several Nvidia technology merged together in Unreal Engine 4.18.3 - Visual Studio 2015 Recommended* Note: Wavework usage requires CUDA cores, which means N...

github.com

다시 주제로 돌아와서, 해안을 따라 측면 재생에서 VDM의 UV 마스크를 약간의 노이즈와 함께 가져온 후 MF_SampleWaveProfile에서 폼 마스크와 포워드업워드를 얻습니다.

MF_SampleWaveProfile - Foam Mask

파도는 해안을 향해 밀려올 때 로컬 공간에서 위쪽과 앞으로만 이동하는 경향이 있기 때문에 실제로 로컬 공간에서 파도의 국부적 이동은 전진-후진 두 가지뿐입니다.

로컬 공간 애니메이션은 sdf 맵에 주입되고 월드 포지션 오프셋으로 변환됩니다. 여기서는 부드러운 색상 전환을 보여주기 위해 MF_SurfaceFlux_Coastline의 오프셋에 리맵을 추가하여 미리보기로 사용했습니다.

MF_SurfaceFlux_Coastline - Offset

버텍스 변위 후 노멀을 얻기 위해 MF_TriangleNormal은 픽셀 셰이더에서 작은 편향이 있는 WPO를 두 번 더 계산하고 세 개의 WPO를 뺀 다음 결과를 교차하는 고전적인 접근 방식을 사용합니다.

MF_TriangleNormal

이것으로 버텍스 애니메이션과 노멀의 분해가 끝났으며, 모두 MF_SurfaceFlux_Coastline에서 계산됩니다. MF_SurfaceFlux_Coastline은 전체 M_FluxSurfaceOver에서 가장 복잡한 머티리얼 함수라고 할 수 있으며, 셰이딩 섹션에서 설명할 WPO와 노멀 외에 폼, 마스크, 속도, 다이버전스 및 기타 어트리뷰트를 계산합니다.。

二、Shading - 착색

일반적인 개요

물 표면: M_FluxSurfaceOver. 싱글 레이어 워터 셰이딩 모델, PBR의 머티리얼 어트리뷰트와 SLW의 스캐터, 흡수, 위상G, 배후 색의 최종 출력입니다.

수중: MI_OceanUnder, MI_OceanFogAbsorptionVolume, MI_OceanFogScatteringVolume

그을린 분산 및 수중 습도: MI_OceanCausticsDecal이라는 동일한 데칼을 공유합니다.

드래프트 라인 효과: 워터라인 프로 프로그램과 유사합니다.

图源 https://www.unrealengine.com/marketplace/en-US/product/waterline

Surface Shading - 표면 착색

수면 컬러링은 M_FluxSurfaceOver로 구현됩니다.

M_FluxSurfaceOver의 근해 파도 섹션을 쉽게 마이그레이션하기 위해 "Section", "Interaction", "Painter", "Simulation", "State" 등의 키워드를 가진 함수 등 파도 이외의 함수를 적절히 분리했습니다, "페인터", "시뮬레이션", "상태" 및 기타 키워드.

M_FluxSurfaceOver는 아래와 같이 간소화되었습니다.

  • 가장 왼쪽의 MF_SurfaceLayer는 근해와 원해가 있는 표면 레이어를 계산합니다;
  • 표면 레이어는 머티리얼이 SLW 특성을 갖도록 MF_FluidScattering, MF_FluidWaterLayer, MF_WaterTransition을 결합하여 유체 레이어를 얻습니다;
  • MF_FluidFoam 내에서 새 폼 레이어 머티리얼 어트리뷰트를 생성하여 폼 레이어를 유체 레이어와 결합합니다;
  • 폼이 있는 유체 레이어는 PBR 섹션의 최종 결과물입니다.
  • SLW 섹션 최종 출력 MF_SingleLayerWater

M_FluxSurfaceOver

 

MF_SurfaceLayer

마이그레이션의 용이성을 위해 웨이브 이외의 기능을 적절히 분리하면 다음과 같은 연결이 이루어집니다.

  • 가장 왼쪽에 있는 MF_SurfaceFlux_Coastline은 위에서 설명한 근해 파도에 대한 변위, 법선 및 몇 가지 추가 데이터를 계산합니다.
  • MF_SurfaceFlux_WaveTexture는 먼 바다의 파도입니다.
  • MF_SurfaceFlux_Blend는 MF_SurfaceFlux_Coastline 및 MF_SurfaceFlux_WaveTexture로 Lerp를 수행합니다.
  • 최종 출력은 SurfaceLayerVS

 

MF_WaterTransition

순전히 장인의 기능... SLW 출력을 얻기 위해 수십 가지 색상의 화려한 계산이 필요합니다.

예를 들어 SurfaceAbsption0은 표면 색상, SurfaceAbsption1은 브러시 사용자 지정 색상, SurfaceAbsptionShoreline은 가까운 해안선 색상입니다.

 

MF_FluidScattering

phaseG 파라미터와 결합된 산란은 물에 이방성 산란 효과를 줍니다.

FF에는 네 가지 스캐터링 구현이 있습니다. 사용자는 저렴한 스캐터링만 사용하거나 나머지 세 가지를 조합하여 사용할 수 있습니다.

  • Cheap Scattering
  • Cheap Scattering
float Vertex_NoV = dot(VertexNormal, CameraDir);
float Pixel_NoV = dot(PixelNormal, CameraDir);
FluidScattering = lerp(Vertex_NoV, abs(Pixel_NoV), _CheapScatteringDetails);
FluidScattering -= CameraDir.g;
FluidScattering = saturate(FluidScattering);
FluidScattering = pow(FluidScattering, _CheapScatteringPower);
FluidScattering = saturate(FluidScattering * _CheapScatteringScale);

MF_ScatteringPhysical

MF_ScatteringPhysical

ScatteringPhysical = MF_ScatteringPhysical(ScatteringPhysical_L, ScatteringPhysical_N, CameraDir, 4.0, 2.0, 0.6, PosWS);

float MF_ScatteringPhysical (float3 L, float3 N, float3 V, float LTPower, float LTIntensity, float LTDistortion, float3 PosWS)
{
    float Scattering;
    float3 Subtract_A = LTDistortion * N * (-1.0);
    float3 Subtract_B = L;
    Scattering = normalize(Subtract_A - Subtract_B);
    Scattering = pow(saturate(dot(Scattering, V)), LTPower) * LTIntensity;
    return Scattering;
}

MF_ScatteringNorma

MF_ScatteringNormal

ScatteringNormal = MF_ScatteringNormal(CameraDir, _DirectionalLightDirection, 0.05, 8.0, 10.0, 0.1, 0.7, PixelNormal);

float MF_ScatteringNormal (float3 V, float3 L, float Intensity, float Distortion, float FrasnelPower, float FrasnelBase, float SunAngle, float3 VertexNormal)
{
    float Scattering;
    float Part_1, Part_2, Part_3, Part_4;
    Part_1 = pow(max(0.0, dot(V, VertexNormal)), FrasnelPower) + FrasnelBase;
    Part_2 = pow(dot(VertexNormal - float3(L.x, 0.7, L.z), V), Distortion);
    Part_3 = dot(float3(VertexNormal.x, 1 - VertexNormal.y, VertexNormal.z) * (-1.0), L);
    Part_4 = max(0.0, saturate(Part_1 * Part_2 * Intensity) * Part_3);
    Scattering = Part_4;
    return Scattering;
}

MF_ScatteringAquatic

ScatteringAquatic = MF_ScatteringAquatic(CameraDir, 0.1, 0, 0.1, PixelNormal);

float MF_ScatteringAquatic (float3 V, float Distance, float3 Flatten, float Intensity, float3 VertexNormal)
{
    Flatten   = lerp(float3(1.2, 1.2, 0.7), float3(0.4, 0.4, 1.4), 0);
    float Scattering;
    Scattering  = Pow2(1.0 - V.y) * (1.0 + dot(_DirectionalLightDirection, V * float3(-1, 1, -1)));
    Scattering *= dot(VertexNormal, V * Flatten);
    Scattering *= Intensity;
    return Scattering;
}

MF_FluidWaterLayer

이 함수는 브라이트닝 및 프레시닝과 같은 작업을 수행합니다. 들어오는 표면 레이어의 스페큘러, 러프니스, IOR 및 베이스 컬러를 가져와 미세한 조각 작업을 수행합니다. 보다 만족스러운 효과를 얻을 수 있습니다.

Basecolor ,roughness,specular

 

MF_SurfaceFlux_WaveTexture

파 웨이브는 일반 XY, 변위 높이, 폼 마스크가 포함된 FFT 수면의 순차 프레임을 저장하는 8x8 이차 연속 플립북을 사용합니다.

방법은 평소와 동일합니다. normal.rg를 사용하여 노멀을 구하고, 대체 높이 값을 사용하여 버텍스 애니메이션을 수행하고, 월드 위치의 Y축 높이를 사용하여 파도가 얼마나 높게 거품이 일어날지 알아냅니다.

변위 및 자코비 노멀의 FFT 실시간 계산과 같은 RT 접근 방식에 비해 다음과 같이 작성하는 것이 더 간단합니다.

T_OceanWave.PNG flipbook
baked FFT ocean wavve

MF_SurfaceFlux_Coastline

위에서 언급했듯이 MF_SurfaceFlux_Coastline은 가장 복잡한 머티리얼 노드 중 하나입니다. 노멀과 오프셋을 계산하는 것 외에도 다음 파라미터도 계산합니다.

Foam

그런 다음 MF_SampleWaveProfile의 폼 마스크를 계산하여 해안을 따라 움직이는 여분의 마스크 레이어가 있는 것처럼 보이도록 합니다.

Velocity

이 효과는 첨부된 폼 맵의 흐름을 제어하는 데 사용되는 플로우맵과 동일합니다.

거품의 흐름 방향은 구운 기울기에서 파생되며, 기본 방향은 해안에서 멀어지고 파도가 밀려오면 속도 값이 역전되어 거품이 육지 쪽으로 흐르고 속도 차이를 사용하여 "거품이 해안을 때리고 후퇴하는" 효과를 얻습니다.

velocity.rg
거품이 위아래로 감싸고 있습니다.

MF_FluidFoam

거품의 반복을 피하기 위해 이 머티리얼 노드 내에서 색상 변화의 RGB 가중치에 따라 세 번 가중치를 부여하여 거품을 샘플링하고 해당 노멀 맵과 거품 색을 혼합하는 MF_AdvectionData를 사용하여 색상 전환 마스크를 계산합니다.

MF_AdvectionData
MF_FluidFoamAdvect

거품이 나타나는 영역은 위에서 설명한 거품 마스크이며, 거품의 흐름 방향은 위에서 언급한 속도입니다.

 

거품이 사라질 때 딱딱해 보이지 않게 하기 위해 거품과 지면 사이에 디더 전환이 있는데, 여기서는 DitherTemporalAA로 계산한 결과를 사용하여 PixelOffset을 일정 거리 이동하고 이를 OpacityMask로 사용하여 slw의 결과를 버립니다.

파도 끝에 공기가 섞이고 파도가 끝에서 부서질 때 거품이 생기는 현상을 시뮬레이션하는 파도 디더(Dither)도 마찬가지입니다.

오파시티 마스

Detail WPO

먼 바다에는 FFT 매크로 웨이브 외에도 디테일 노멀과 미세 버텍스 디스플레이스먼트를 구동하는 디테일 웨이브 레이어가 있습니다.

 

 

Others

이것으로 수면 섹션의 대부분의 기능에 대한 분석이 완료되었습니다.

수면 외에도 먼 바다 파도의 경우와 마찬가지로 집중된 흩어짐 아플리케에 플립북을 사용하는 것도 언급할 가치가 있습니다.

FF는 플립북을 기반으로 아웃포커싱된 색상의 색수차를 개선하여 아웃포커싱된 색상을 더욱 풍부하게 표현합니다.

플립

chromatic aberration

폼 맵과 동일한 속도를 가지며 파도와 함께 움직입니다.

물과 교차하는 오브젝트의 습도 변화는 초점 분산 데칼에서도 구현되어 베이스 컬러를 어둡게 하면서 러프니스를 증가시키며, 물론 습도에 대해 진지하게 고민한다면 파크라이의 다공성 방식을 사용하여 습도를 적용하는 것도 가능합니다...

III. 인터랙션 - 상호 작용

반면 캐릭터 상호작용은 고품질의 안정적인 동적 상호작용 방식인 얕은 물 방정식 방식을 사용합니다.

함정

ue와 유니티의 단위와 축이 동일하지 않으므로 다음 문제에 주의해야 합니다.

  • 셰이더 계산에서 들어오는 PositonWS에 100을 곱하고 xyz를 xzy로 변환해야 합니다.
  • 버텍스 셰이더가 전송한 PositonWS를 100으로 나눕니다.
  • ue에서 추출한 모든 맵의 Y축을 반전합니다.

 

shader 구체적인 의사 코드는 다음과 같습니다.。

VS에서 버텍스 애니메이션이 없는 WPT_ExcludeAllShaderOffsets의 복사본을 PS에 전달하여 PosData와 함께 사용하려면 CameraVectorWS, CameraPositionWS, ScreenUV, PositionWS, ViewSpaceZ 등에 대한 일반 정보를 기록하는 구조체라는 점에 유의하세요. PosData

// Vertex Shader 

    // WPT_ExcludeAllShaderOffsets : Absolute World Position (Excluding Material Offsets)
    float3 WPT_ExcludeAllShaderOffsets = TransformPositionOSToPositionWS(vertex.PositionOS, GetObjectToWorldMatrix());
    vertex.PositionWSRaw = WPT_ExcludeAllShaderOffsets;

// Vertex Shader 

    float3               UEPositionWS = float3(vertex.PositionOS.xzy); // -- UE to UNITY -- (Chirality)
    UEPositionWS *= 100; // -- UE to UNITY -- (Unit)
    MaterialAttributes SurfaceLayerVS = MF_FluxSurfaceOver(UEPositionWS, PosData).SurfaceLayerVS;
    vertex.PositionWS += float3(SurfaceLayerVS.WorldPositionOffset.xzy * 0.01); // -- UE to UNITY -- (Chirality)

// Pixel Shader

    float3 WPT_ExcludeAllShaderOffsets  = vertex.PositionWSRaw;
           WPT_ExcludeAllShaderOffsets  = float3(WPT_ExcludeAllShaderOffsets.xzy);  // -- UE to UNITY -- (Chirality)
           WPT_ExcludeAllShaderOffsets *= 100;                                      // -- UE to UNITY -- (Unit)
           
     FluxSurfaceOver    SurfaceLayer   = MF_FluxSurfaceOver(WPT_ExcludeAllShaderOffsets, PosData);
    MaterialAttributes SurfaceLayerVS = SurfaceLayer.SurfaceLayerVS;

	YourPBR.Opacity                      = SurfaceLayerVS.Opacity;
    YourPBR.BaseColor                    = SurfaceLayerVS.BaseColor * MInput.Opacity;
    YourPBR.DepthOffset                  = SurfaceLayerVS.PixelDepthOffset;
    
	   YourSLW.Scattering = SurfaceLayer.Scattering;
	   YourSLW.Absorption = SurfaceLayer.Absorption;
	   YourSLW.ColorBehind = SurfaceLayer.ColorBehind;
	   YourSLW.PhaseG       = SurfaceLayer.PhaseG;
	   ......

요약

FF2는 전형적인 "애니메이션 웨이브 + 물리적 웨이브"조합입니다. 상상 블렌드는 FF 플러그인을 개발하는 데 20 개월 이상을 보냈고, 시간 비용만으로도 20 만 달러의 가치가 있으며, 그는 모든 사람의 문제를 해결하기 위해 열정적으로 불화를 겪었고, 불법 복제를 통해이 플러그인을 얻는 사용자는 정말 냉담합니다 ...이 기사에서 해상 파도의 해체는 Fluid Flux 플러그인의 빙산의 일각에 불과하며 디자인 컨셉과 경이는 내 종류의 pow a 2.2.2, 디자인 컨셉과 경이는 내 종류의 pow a 2.2.2가 아닙니다. 플러그인은 350달러이지만 그만한 가치가 있습니다. 디자인 컨셉과 미묘함은 저처럼 2.2에 1.5를 곱할 수 있는 쓰레기 아티스트에게는 적합하지 않습니다!

상상블렌드가 자신의 플러그인에 대한 저의 이해를 칭찬합니다 ^_^

 

적응성 측면에서 메시의 토폴로지에 대한 요구 사항이 없으며 메시를 인위적으로 프로그래밍 할 필요가 없으며 정점 수가 파도 정점 애니메이션이 삼각형 도그 투스를 생성하지 않도록하기에 충분하다면 괜찮습니다. 정점 수가 삼각형 표면 애니메이션이 톱니 모양을 생성하지 않을 정도로 충분하다면 괜찮습니다. 그리고 근해 파도는 완전히 계산된 결과이며 메시로 전달되는 메시 파라미터는 PositionWS뿐이므로 테셀레이션을 원한다면 이 또한 친숙합니다.

 

코드와 사용성 측면에서 볼 때, 셰이더의 파라미터, slw 섹션, pbr 조명 함수를 제외하고 HLSL로 변환된 전체 FluxSurfaceOver는 약 1200줄의 코드입니다. FF2의 파라미터 패널은 거의 200개에 달하는 파라미터와 여러 토글로 매우 길며, 대부분 거의 사용되지 않기 때문에 개인 프로젝트에서 셰이더를 구현하려면 코드와 파라미터를 줄여야 합니다.

이것이 모든 매개 변수입니다.

아트 퍼포먼스 측면에서 FF는 1.0 버전에서 언리얼 몰의 필수 구매 플러그인 중 하나로 선정되었으며, 2023년에 출시된 2.0 니어쇼어 웨이브는 더욱 놀라운 성능을 자랑합니다.

지난 주에는 250에 판매되었습니다.

 

개인적으로 저 같은 아웃소싱 TA에게 FluxSurfaceOver의 모든 머티리얼 노드를 분석하고 번역하는 작업은 시간을 투자할 만한 가치가 있었습니다. DitherTAA가 어떻게 작성되는지, 다중 스캐터링 함수의 요령, 대형 셰이더의 프레임워크를 배웠고, 언리얼 셰이더와 Unity의 차이점을 더 잘 다룰 수 있게 되었습니다!

 

사용 측면에서 보면 씬에 따라 달라지는 근해 파도에 대한 맵은 단 하나, 바로 sdf 깊이 맵입니다. 웨이브웍스에서 계산 셰이더 코드를 제공했기 때문에 유니티 툴에서 이 sdf 맵을 오프라인으로 계산하는 것은 어렵지 않습니다. 이 sdf의 해상도 요구 사항은 높지 않으며, 512 해상도를 사용하는 3km의 맵이면 충분합니다.

 

매핑 오버헤드 측면에서 이 체계에서 사용되는 맵 목록은 다음과 같습니다.

(이론적으로는 CoastlineMap_Coastline_Coastline, CoastlineMap_Coastline_Ground, T_DefaultWaveProfile_Forard, 디더 컷 아웃, 다른 구성표인 폼을 사용하여 원거리 파도만 사용하는 것으로 축소할 수 있습니다. 색상은 흰색이고 노멀이 잘려나가고 노이즈도 잘려나갑니다.)

  • CoastlineMap_Coastline_Coastline.exr(다음 그림과 결합할 수 있습니다.)
  • CoastlineMap_Coastline_Ground.exr(위의 그림과 결합할 수 있습니다.)
  • T_DefaultWaveProfile_Forard.png(Wave profile vector displacement texture)
  • Good64x64TilingNoiseHighFreq.png(Dither)
  • T_OceanWave.png(远海浪的 64 帧 Flipbook)
  • T_Seafoam_03_NSH.png(浮沫)

 

 

Fluid Flux – Imaginary Blend

 

imaginaryblend.com

https://www.unrealengine.com/marketplace/en-US/product/fluid-flux

읽어주셔서 감사합니다 ^_^


원문

https://zhuanlan.zhihu.com/p/661621289?utm_psn=1774042961174491136&utm_id=0

 

https://zhuanlan.zhihu.com/p/661621289?utm_id=0&utm_psn=1774042961174491136

 

zhuanlan.zhihu.com