2011-01-26 78 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方向的颜色 - 这就是你需要的。

希望这有助于......(哦,是的,我从记忆中写道,如有任何错误,请评论)。