Refraction in OpenGL ES 2.0/3.0. Large pixels texture
尝试在 OpenGL ES 2.0/3.0 中实现折射。使用了以下着色器:
顶点着色器:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#version 300 es precision lowp float; uniform mat4 u_mvMatrix; in vec4 a_position; const mediump float eta = 0.95; void main() { // eye direction in model space // calculate refraction direction in model space // project refraction // map refraction direction to 2d coordinates |
片段着色器:
1
2 3 4 5 6 7 |
… in mediump vec2 v_refractCoord; uniform samplerCube s_texture; // skybox void main() { |
纹理加载方法:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
@JvmStatic fun createTextureCubemap(context: Context, rowID: Int) { val input = context.resources.openRawResource(rowID) val bitmap = BitmapFactory.decodeStream(input) val textureId = IntArray(1) GLUtils.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, bitmap, 0) glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST) |
但是纹理是用大像素获得的,例如:
这可能是什么原因?也许这对于低多边形模型来说是正常的?好像贴图太接近了。
注意:多边形越少 – 质量就越差。
提前感谢您的任何评论/回答!
图片来自 goodfon.ru
解决方案:根据@Rabbid76 的建议,我更改了正常数据。事实证明,在 Blender 中,您需要将对象的 Shading 设置为平滑(不平坦) – 这会在导出为 *.obj 格式时增加法线数量:为什么 OBJ 导出写入面法线而不是顶点法线 另外,根据@Rabbid76 的建议,我更改了以下内容: 结果,像素化消失了: 此外,在顶点着色器中计算折射时也可能出现像素伪影,因此我将计算转移到片段着色器中。这是修改后的着色器代码: 顶点着色器: in vec4 a_position; out vec3 v_normal; out vec3 v_eyeDirectModel; float getSpecularIntensity(vec4 position, vec3 a_normal, vec3 eyeDirectModel) { void main() { 片段着色器: in vec3 v_normal; out vec4 outColor; const float eta = 0.65; vec4 glassColor = texture(s_texture, vec3(refractCoord, 1.0)); 首先在着色器代码中有一个错误。 // eye direction in model space 此外,这是一个法线向量属性的问题。 由于相邻曲面之间的法线向量不同,您可以在网格面之间看到明显的边缘。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
precision lowp float;
uniform mat4 u_mvpMatrix;
uniform mat4 u_mvMatrix;
in vec3 a_normal;
out lowp float SpecularIntensity;
float shininess = 30.0;
vec3 lightPosition = vec3(–20.0, 0.0, 0.0);
mediump vec3 LightDirModel = normalize(lightPosition – position.xyz);
mediump vec3 halfVector = normalize(LightDirModel + eyeDirectModel);
lowp float NdotH = max(dot(a_normal, halfVector), 0.0);
return pow(NdotH, shininess);
}
v_normal = a_normal;
vec4 eyePositionModel = u_mvMatrix * a_position;
// Eye direction in model space
vec3 eyeDirectModel = normalize(– eyePositionModel.xyz);
// specular lighting
SpecularIntensity = getSpecularIntensity(a_position, a_normal, eyeDirectModel);
v_eyeDirectModel = eyeDirectModel;
gl_Position = u_mvpMatrix * a_position;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
precision lowp float;
uniform mat4 u_mvpMatrix;
in lowp float SpecularIntensity;
in vec3 v_eyeDirectModel;
uniform samplerCube s_texture; // skybox
void main() {
// Calculate refraction direction in model space
vec3 refractDirect = refract(v_eyeDirectModel, normalize(v_normal), eta);
// Project refraction
refractDirect = (u_mvpMatrix * vec4(refractDirect, 0.0)).xyw;
// Map refraction direction to 2d coordinates
vec2 refractCoord = 0.5 * (refractDirect.xy / refractDirect.z) + 0.5;
outColor = glassColor + SpecularIntensity;
outColor.a = 0.8; // transparent
}
您必须在视图空间中计算
2
3
4
mediump vec3 eyeDirectView = normalize(– eyePositionView.xyz);
问题是由于法向量是按面计算的,而不是针对每个顶点单独计算的。
注意,折射方向(
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/269069.html