2014-01-23 2 views
0

방금 ​​스펙 테라 하이라이트 구현을 시도했습니다. 문제는 표면에서 멀리 이동할 때 하이라이트가 강하고 강해지 고 하이라이트의 가장자리가 매우 거칠어진다는 것입니다. 표면에 너무 가까이 접근하면 하이라이트가 완전히 사라집니다.반사 하이라이트는 카메라의 거리에 따라 달라집니다.

내 조각 쉐이더의 관련 부분입니다. 모든 계산은 뷰 공간에 있습니다. 나는 방향성 태양 빛을 사용한다.

// samplers 
vec3 normal = texture2D(normals, coord).xyz; 
vec3 position = texture2D(positions, coord).xyz; 
float shininess = texture2D(speculars, coord).x; 

// normalize directional light source 
vec3 source; 
if(directional) source = position + normalize(light); 
else source = light; 

// reflection 
float specular = 0; 
vec3 lookat = vec3(0, 0, 1); 
float reflection = max(0, dot(reflect(position, normal), lookat)); 
int power = 5; 
specular = shininess * pow(reflection, power); 

// ... 

// output 
image = color * attenuation * intensity * (fraction + specular); 

이것은 내 조명 버퍼의 스크린 샷입니다. 가장 먼 배럴에는 반사 강조가 전혀없고 멀리있는 배럴은 너무 강하게 빛나는 것을 볼 수 있습니다. 가운데 배럴은 원하는대로 밝게 빛납니다. 내가 잘못 뭐하는 거지

far highlights are too strong and near highlights disappear

?

+0

클라이언트 측 코드, 특히 조명 벡터를 표시하십시오. 위치를 길 찾기와 혼동하지 않도록하십시오. –

+0

지향성 광원의 경우 해당 위치를 방향으로 처리합니다. 예를 들어 태양의 위치는'0.5, 1.0, 1.5'입니다. 이것이 문제가 되는가? 문제는 방향 조명과 포인트 조명에 대해 동일합니다. – danijar

+1

코드가 충분하지 않습니다. 모델보기 행렬을 구성하는 방법을 보여줍니다. 예를 들어 벡터의 모양이 x, y, z, 1과 같은 경우 문제가 될 수 있습니다. –

답변

2

거꾸로 빛의 방향 (물체에서 광원으로 향함)을 사용하는 대신 대상 위치에서 반사 벡터를 계산합니다.

그것은이 그림에서 L 대신 V를 사용 같다 : 또한

, 내가 휘성이 선형 적으로 반사 공헌을 곱하지 뭔가 표현식의 지수해야한다고 생각합니다.

+0

고마워. 'float reflection = max (0, dot (reflection (normalize (source-position), normal), lookat));를 사용할 때 더 이상 보이는 하이라이트가 없다. 'specular'에 10을 곱하면 어떤 종류의 하이라이트가 나타나지만 어떤 방향으로는 여전히 방향이 어긋납니다. 내 문제를 어떻게 더 디버깅 할 수 있습니까? 확산 조명은 점 광원으로 작동하기 때문에 행렬이 정확하다는 것을 알고 있습니다. – danijar

+0

나는 당신이 사용해야한다고 생각한다 : specular = pow (reflection, shininess); Btw, 나는 또한 셰이더를 디버깅하기가 어렵다. 나는 보통 "컬러 디버깅"을한다. (예 : http://en.wikibooks.org/wiki/Cg_Programming/Unity/Debugging_of_Shaders) –

+0

' shininess' 가치는 그때? 나는 거울 반사가 전혀없는 표면을 가지고 있습니다. 'shininess'를 0으로 설정할 때, pow 함수는 하나가되고, 곱 해지지 않고 조명에 추가됩니다. 셰이더의 단일 단계의 스크린 샷을 화면에 인쇄 할 수 있습니다. 어떤 단계가 도움이 될까요? – danijar

1

변수 이름이 당신을 혼란스럽게합니다. 내가 읽고 있어요 무엇에서

vec3 lookat = vec3(0, 0, 1); 
float reflection = max(0, dot(reflect(position, normal), lookat)); 

lookat는 방향 빛과 position는 실제 lookat이다 (당신이 카메라 공간과 쓰는 손 지식 없이도있어 가정).

normal (이미 정규화되었을 가능성이 높음) 및 position (lookat)이 정규화되어 있는지 확인하십시오.

덜 혼란 코드는 다음과 같습니다

vec3 light_direction = vec3(0, 0, 1); 
vec3 lookat = normalize(position-vec3(0,0,0)); 
float reflection = max(0, dot(reflect(light_direction, normal), -lookat)); 

position을 정상화하지 않고, reflection는 바이어스됩니다. position이 카메라에서 멀리 떨어져있을 때 바이어스가 강할 것입니다 vec3(0,0,0)

어떻게 lookat이 상수가 아닌지주의하십시오. 그것은 각 위치마다 바뀝니다. lookat = vec3(0,0,1)은보기 공간에서 단일 위치를 찾고 있습니다.

+0

(point - vec3 (0, 0,0))은 점에서 카메라까지의 벡터가 필요할 때 '카메라'에서 점으로 벡터를 반환하지 않습니까? –

+0

@racarate (위치 - vec3 (0, 0,0))는 카메라에서 위치까지의 벡터이며 "look at"입니다. 그렇지만 당신은 맞습니다. 점은 반사 광선과 카메라를 가리키는 위치에서 벡터 사이에 있어야합니다 (-lookat). –

관련 문제