我有一个关于折射的问题。
我正在使用纹理图像进行折射(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);
}
有谁能让我知道这个问题的解决方案?
感谢您的帮助。
对不起家伙我无法附上图片。
答案 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方向 - 这是您所需要的。
希望这有帮助......(而且,是的,我是从记忆中写的,如果有任何错误,请发表评论)。