2011-01-26 87 views
2

我有一個關於折射的查詢。Opengl折射,紋理重複在橢球物體上

我正在使用紋理圖像進行折射(refertest_car.png)。

但不知何故,紋理越來越相乘,

我使用以下着色器givinga失真的圖像(參見Screenshot.png)。

attribute highp vec4 vertex; 
attribute mediump vec3 normal; 

uniformhighp mat4 matrix; 
uniformhighp vec3 diffuse_color; 
uniformhighp mat3 matrixIT; 

uniformmediump mat4 matrixMV; 
uniformmediump vec3 EyePosModel; 
uniformmediump vec3 LightDirModel; 
varyingmediump vec4 color; 

constmediump float cShininess = 3.0; 
constmediump float cRIR = 1.015; 

varyingmediump vec2 RefractCoord; 

vec3 SpecularColor= vec3(1.0,1.0,1.0); 

voidmain(void) 
{ 
    vec3 toLight = normalize(vec3(1.0,1.0,1.0)); 

    mediump vec3 eyeDirModel = normalize(vertex.xyz -EyePosModel); 
    mediump vec3 refractDir =refract(eyeDirModel,normal, cRIR); 

    refractDir = (matrix * vec4(refractDir, 0.0)).xyw; 

    RefractCoord = 0.5 * (refractDir.xy/refractDir.z) + 0.5; 

    vec3 normal_cal = normalize(matrixIT *normal); 
    float NDotL = max(dot(normal_cal, toLight), 0.0); 

    vec4 ecPosition = normalize(matrixMV * vertex); 
    vec3 eyeDir = vec3(1.0,1.0,1.0); 
    float NDotH = 0.0; 
    vec3 SpecularLight = vec3(0.0,0.0,0.0); 

    if(NDotL > 0.0) 
    { 
     vec3 halfVector = normalize(eyeDirModel + LightDirModel); 
     float NDotH = max(dot(normal_cal, halfVector), 0.0); 
     float specular =pow(NDotH,3.0); 

     SpecularLight = specular * SpecularColor; 
    } 

    color = vec4((NDotL * diffuse_color.xyz) + (SpecularLight.xyz) ,1.0); 

    gl_Position = matrix * vertex; 
} 

而且

varyingmediump vec2 RefractCoord; 
uniformsampler2D sTexture; 
varyingmediump vec4 color; 

voidmain(void) 
{ 
     lowp vec3 refractColor = texture2D(sTexture,RefractCoord).rgb; 
     gl_FragColor = vec4(color.xyz + refractColor,1.0); 
} 

任何人都可以讓我知道了解決這個問題?

感謝您的任何幫助。

對不起,我不能附上圖像。

+0

準確地說,refractColor的計算是完全正確的,它真的只是RefractCoord導致了問題?如果你能夠在某處上傳圖片,我可以附上它 - 我認爲它們對那些聲譽低於一定數量的人禁用了它。 – Tommy 2011-01-27 00:30:13

回答

0

看來你是在錯誤地計算折射向量。 Hovewer,你的問題的答案已經在它的標題。如果您正在觀看橢球體,則視圖中的光線會跨過一個圓錐體,將橢圓體包裹起來。但折射後,錐體可能會更寬,超出圖像的邊緣,因此紋理座標大於0 - 1,導致紋理被包裹。所以我們也需要照顧這一點。

vec3 eyeDirModel = normalize(-vertex * matrix); 
vec3 refractDir = refract(eyeDirModel, normal, cRIR); 

RefractCoord = normalize((matrix * vec4(refractDir, 0.0)).xyz); // no dehomog! 

RefractCoord現在包含折射眼空間矢量:

首先,折射座標應當在頂點着色器計算如下。這要看「矩陣」是模型視圖矩陣(這不是從你的代碼清楚,但我懷疑它是)。如果你希望着色器運行得更快,你可能會跳過標準化,但不應該引起明顯的錯誤。現在對你的片段着色器進行一些修改。

vec3 refractColor = texture2D(sTexture, normalize(RefractCoord).xy * .5 + .5).rgb; 

在這裏,用規範()可以確保紋理座標不會導致紋理重複。

請注意,使用2D紋理進行折射只能通過動態生成(例如半條命2)來證明其正確,否則應該使用立方體貼圖紋理,這會對您進行規範化併爲您提供基於3D方向的顏色 - 這就是你需要的。

希望這有助於......(哦,是的,我從記憶中寫道,如有任何錯誤,請評論)。