[14.09.01] dynamic lighting in god of war3(shader study)

Post on 24-Jun-2015

326 views 1 download

description

원문 http://advances.realtimerendering.com/s2011/index.html

Transcript of [14.09.01] dynamic lighting in god of war3(shader study)

Dynamic lighting in God of War3

ShaderStudy해강

Siggraph2011 발표God of War3 에서 다수의 동적 라이팅을 처리한 내용

PS3 에서는 RSX(geforce7800 GPU) 가 병목PS3 는 pixel 연산이 느림

SPU 를 활용해 , RSX 를 싸게 유지하는게 목표아티스티들이 더 많은 per pixel lighting 요구

GOW3 에서 라이트 종류1. Ambient - 환경광은 하나의 RGB 로 통합하므로 해당 안됨2. Omni(point)3. DirectionalHybrid vertex lights 로 통합

Vertex 에서 다수의 라이트들을 합성해 pixel 에서는 하나의 라이트로 계산

Vertex 애 대해서 거리에 따른 감쇠 계산- 정점의 거리에 따라 falloff( 광량 변화 ) 계산

하나의 라이트로 합친다합쳐진 Light Position 보간

하나의 라이트로 스펙큘러 등을 계산

왜 빛의 위치로 계산하는가 ?

픽셀별로 빛의 방향을 저장할 경우

A 와 B 에서 저장된 방향을 보간

엉뚱한 곳을 가리키게 된다

빛의 위치를 저장할 경우

A 와 B 에 저장된 라이트 위치가 같다면 AB 중앙 픽셀에 영향을 주는 빛도 움직이지 않는다

영향을 받는 빛을 올바르게 계산

부드럽고 , 저렴하게 만들기 위해서왼쪽 : 선형 falloff

오른쪽 : GOW3 falloff

같은 거리에서는 0 에 도달하도록 구성

라이트 위치와 falloff 가중치만으로는 부족거리에 관계없이 강도에 따라 빛이 오버할 가능성

픽셀당 라이트의 방향을 보간하는 것은 안 된다- 잘못된 라이트를 가리킨다

정점 당 조명 위치를 평균화하는 것도 안 된다- 라이트가 오버할 가능성

Vertex 애 대해서 거리에 따른 감쇠 계산- 정점의 거리에 따라 falloff( 광량 변화 ) 계산

하나의 라이트로 합친다- 정점에 따라 조명 방향을 저장한다

합쳐진 Light Position 보간하나의 라이트로 스펙큘러 등을 계산

상대 경로 생성을 위해서 라이트에서 정점 위치를 뺀다길이와 가중치를 계산 ( 강도는 1 로 )상대 경로 ( 방향 ) 에 가중치를 곱한다

라이트의 방향을 추가가중치 축적

위치에서 가중치를 곱셈

통합된 라이트 벡터 얻음라이트의 월드좌표를 위해 정점 위치를 추가

수식

지금까지 라이트는 그림자에 관계 없이 결합되어 있기 때문에다시 버택스에 라이트가 직면하도록 계산

Vertex 애 대해서 거리에 따른 감쇠 계산- 정점의 거리에 따라 falloff( 광량 변화 ) 계산

하나의 라이트로 합친다- 정점에 따라 조명 방향을 저장한다

합쳐진 Light Position 보간-Back facing, normalize check

하나의 라이트로 스펙큘러 등을 계산

Back facing라이트 가중치에 N dot L 을 포함

문제점서로 반대의 방향에서 빛의 영향을 받을 경우

A 와 B 중 한곳에서 N dot L 보다 높은 값이 발생

P 지점 오버헤드

라이트 벡터가 임계값 보다 짧은 경우에는 normalize 를 하지 않는다

집계된 라이트의 색상을 계산하는 방법이 필요하다

물리적으로 올바른 값은 손실

Vertex 애 대해서 거리에 따른 감쇠 계산- 정점의 거리에 따라 falloff( 광량 변화 ) 계산

하나의 라이트로 합친다- 정점에 따라 조명 방향을 저장한다

합쳐진 Light Position 보간-Back facing, normalize check

하나의 라이트로 스펙큘러 등을 계산

통합된 빛의 위치 계산빛의 방향을 정규화

내적

수식

RGB 집계 최종

여러가지 조명을 넣어도 결과값은 예측값의 합과 동일하다때문에 휘도값이 적절하게 들어간다

( 부하에 관한 이야기는 없었으나 적절한 제한은 필요할 듯 )

휘도에 대한 근사치 최종 공식

버텍스에서 라이트를 하나로 통합해픽셀에서 스펙큘러등의 최종처리포워드에서도 활용 가능할 것임

버텍스에서 계산하고 픽셀에서는 반사 스펙큘러를 계산한다결과 확인을 위한 확인 작업이 복잡하기 때문에 -

GOW3 의 발표는 감쇠에 의해 색을 축적색을 축적하는 것이 아니라 라이트 방향을 축적해 해결하자는 의견

스펙큘러나 컬러는 걍 가져다 쓰자

half3 HemiDiffuse : COLOR0; // Diffuse hemisphere lightinghalf3 HemiSpecular : COLOR1; // Specular hemisphere lightinghalf3 SunDiffuse : TEXCOORD0; // Diffuse lighting for the sunhalf3 SunH : TEXCOORD1; // Half-angle vector for the sunhalf3 PointsDiffuse : TEXCOORD2; // Agg. diffuse lighting from pointshalf3 PointsH : TEXCOORD3; // Agg. half-angle vector from pointshalf3 N : TEXCOORD4; // Surface normal

// pixel shader: half2 highlights;highlights.x = pow( saturate( dot( N, SunH ) ), SPEC_POWER );highlights.y = pow( saturate( dot( N, PointsH ) ), SPEC_POWER );highlights *= SPEC_NORMFACTOR; half3 result = 0; result += DiffTexture * ( In.HemiDiffuse + In.SunDiffuse + In.PointDiffuse ); result += SpecTexture * ( In.HemiSpecular + In.SunDiffuse * highlights.x + In.PointsDiffuse * highlights.y );

// vertex shader: float3 PointsL = 0;for( int i = 0; i < NUM_POINTS; ++i ){ half3 dx = LightPosition[i] - WorldPosition; half attenuation = // some function of distance half3 attenL = normalize( dx ) * attenuation; Out.PointDiffuse += saturate( dot( N, attenL ) ) * LightColor[i]; PointsL += attenL;} Out.PointsH = normalize( PointsL ) + V;