본문으로 바로가기
반응형


TA Study에서 리뷰했던 시그라프2016 Uncharted 4 Technical art 주요 내용입니다




1. Mipmap fog

mipLevel= (1.0-saturate((depth-nearParam)/(farParam-nearParam))) * numMipLevels;
fogColor= SampleFogTexture(cameraVec, mipLevel);[각주:1]


2. Micro Shadow

float ApplyMicroShadow(float ao, float3 N, float3 L, float shadow)
 {
float aperture= 2.0 * ao* ao;
float microShadow = saturate(abs(dot(L, N)) + aperture- 1.0);
return shadow* microShadow;
 }






3. Ambient Occlusion Fresnel
float aoFadeTerm= saturate(dot(vertexNormalWS, viewWS));
ao= lerp(1.0, ao, aoFadeTerm);[각주:2]


4. Moss Material

float3 ApplyLightWrap(float3 lightWrapColor, float3 normalWS, float3 vertexNormalWS, float3 lightDirWS)
{
float lightWrapDistance = 0.1;
float3 wrapLight = lightWrapDistance* lightWrapColor;
float NdotL = dot(normalWS, lightDirWS);
NdotL = lerp(max(wrapLight.r, max(wrapLight.g, wrapLight.b)), 1.0, NdotL);
float wrapForwardNdotL = max(NdotL, dot(vertexNormalWS, lightDirWS))
float3 wrapForward = lerp( wrapLight, float3(1.0, 1.0, 1.0), wrapForwardNdotL);
float3 wrapRecede = lerp(-wrapLight, float3(1.0, 1.0, 1.0), NdotL);
float3 wrapLighting = saturate(lerp(wrapRecede, wrapForward, lightWrapColor));
return wrapLighting;
}




5. Wetness Material

마스크의 모든 입력 값에 대해 의미있는 젖은 결과를 제공하므로 사용하기 매우 직관적입니다. wetness intensity가 98 %를 초과하면 버텍스 노멀이 똑바로 위로 향하도록 강제합니다. 이렇게하면 기본 형상이 평평하지 않더라도 물이 고인 표면이 평평해 지도록 만드는 매우 확실한 작업을 수행합니다.
float ClampRange(float input, float minimum, float maximum)
{
return saturate((input- minimum) / (maximum- minimum));
}


float3 baseColorSqr = baseColor*baseColor;
baseColor = lerp(baseColor, baseColorSqr, ClampRange(wetness, 0.0, 0.35) * porosity);
roughness = lerp(roughness, 0.1, ClampRange(wetness, 0.2, 1.0));
specular = lerp(specular, 0.25, ClampRange(wetness, 0.25, 0.5));
ao = lerp(ao, 1.0, ClampRange(wetness, 0.45, 0.95));
normalTS = lerp(normalTS, float2(0.5), ClampRange(wetness, 0.45, 0.95));
vertexNormalWS= normalize(lerp(vertexNormalWS, float3(0,1,0), ClampRange(wetness, 0.98, 1.0)));




6. Glass Material

유리를 "투명"이라고 생각할 때 실제로 투명한 것은 디퓨즈의 구성 요소입니다. 반사 구성 요소는 다른 단단한 표면과 동일합니다. 따라서 표준 알파 블렌딩을 수행하는 경우 알파 채널을 미리 분할하고 결과적으로 확산만 투명도의 영향을받는 결과를 얻을 수 있습니다. 표면은 다양한 투명도를 가질 수 있으며 (예 : 창이 지저분한 경우) 반사 결과는 표면 전체에서 일정하게 나타납니다. 유일한 문제는 투명도가 0에 가까워 질 때 부동 소수점 부정확성입니다.
Premultiplied alpha를 사용하면 이 문제가 훨씬 더 간단 해집니다. 스페큘러가 아닌 디퓨즈에만 투명도를 적용하십시오!

finalLight = diffuseLight + (specularLight / max(transparency, 0.01));
float NdotV= dot(normalWS, viewWS);
float3 refractWS= refract(viewWS, normalWS, ior);

// Calculate distance ray travels through the medium
float rayLengthSolid= thickness;
float rayLengthShell= thickness/ max(pixelDepth* NdotV, 0.5);
float rayLength= lerp(rayLengthSolid, rayLengthShell, isShell);
float3 refractVectorWS = refractWS* rayLength;

// Convert world-space to view space, add to current screen UV, sample screen buffer
float3 refractionLight= FetchRefractedPixel(refractVectorWS);

// Final color based on Fresnel darkening and remaining user inputs
refractionLight*= mediumColor * SchlickFresnel(NdotV, ior);
diffuseLight = lerp(diffuseLight, refractionLight, surfaceTransparency);




7. Wind System
wind animation : ambient + gust
float noise = Get2dNoise(dot(windDirection, pivotWS), time);
float animation = sin(windSpeed * time + timeOffset);
float angle = windIntensity * animation * noise + gust;





8. Ambient Animation
VAT를 활용. HLSL에서 Load api를 활용해 필터링 혹은 샘플링 없이 텍스쳐에서 정보를 로딩.
Particle optimization : 각 파티클 플립북에 대해 각 프레임에서 보이는 픽셀의 로컬 공간 경계가있는 키 프레임 텍스처를 만듭니다. 이를 통해 버텍스 셰이더의 FX 쿼드를 수정하여 현재 플립북 프레임에 필요한 공간만 차지할 수 있습니다. 따라서 fx 오버 드로우 및 픽셀 셰이더 압력을 크게 줄입니다. 추가 패스로 키프레임 텍스처에 UV 위치를 추가하고 해상도 손실을 최소화하거나 전혀없이 플립북을 절반 크기로 다시 포장 할 수있었습니다.





9. And more..
  • 가능한 한 물리적 현상을 기반으로 사물을 만듭니다. 바람의 경우 여러 단계의 사인함수를 레이어링하는 것이 일반적이지만 joint rotation을 수행하는 것이 훨씬 좋아 보이고 아티스트가 이해하기 더 쉽습니다!
  • 가능한 한 적은 수의 매개 변수 만들기 : 모든 단일 변수에 대한 슬라이더를 사용하는 것보다 사용 사례의 80 %를 다루는 작은 컨트롤 세트를 사용하는 것이 더 좋습니다.
  • 프레임 속도에 대한 책임 : 하루를 끝낼때 게임은 타겟 프레임 안에서 구동해야 합니다. 비효율적 인 코드를 작성하면 어딘가에서 아트 퀄리티를 깎아야 합니다
  • 모르실 때는 물어보세요! : Andrew와 저는 프로그래머에게 끊임없이 도움을 요청하지 않았다면이 모든 기술을 만들 수 없었을 것입니다. 적절한 행렬 변환을 수행하는 방법, 최적화하는 방법, 심지어 변수 이름을 올바르게 지정하는 방법까지.



  1. Depth texture를 사용한다면 모바일에서도 충분히 쉽게 구현할 수 있는 기법이다. [본문으로]
  2. AO 계산에 프레스넬 계산을 추가하는 것 만으로 AO에 의해 어둡지 않아야 하는 부분에 대해 특별한 처리 없이 보완 가능한 방법 [본문으로]
반응형