Opengl折射,纹理在椭圆体对象上重复

时间:2011-01-26 10:57:33

标签: opengl

我有一个关于折射的问题。

我正在使用纹理图像进行折射(refertest_car.png)。

但不知何故,纹理越来越多,并且给出了扭曲的图像(Refer 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);
}

有谁能让我知道这个问题的解决方案?

感谢您的帮助。

对不起家伙我无法附上图片。

1 个答案:

答案 0 :(得分: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;

在这里,使用normalize()可确保纹理坐标不会导致纹理重复。

请注意,使用2D纹理进行折射时,只能通过动态生成它来证明(例如Half-Life 2),否则应该使用立方体贴图纹理,它可以为您进行标准化并为您提供颜色基于3D方向 - 这是您所需要的。

希望这有帮助......(而且,是的,我是从记忆中写的,如果有任何错误,请发表评论)。