WebGL 网站在 PC 上看起来不错,但在移动设备上看起来很奇怪
WebGL website looks fine on PC, but looks weird on mobile devices
所以我做了一个 WebGL 网站,可以在这里访问:
https://jameswebsite.azurewebsites.net/
它在 PC 上看起来不错(或符合预期),但在移动设备上看起来很有趣。看起来纹理映射可能已关闭(可能是纹理裁剪问题),但似乎也没有出现任何阴影。
PC端截图如下:
PC 图片
]1
这是移动设备的屏幕截图:
手机图片
我已经关闭了纹理,但仍然有这个问题。这使我相信问题可能出在我的着色器中。这是我的着色器:
<script id="per-fragment-lighting-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec2 vTextureCoord;
varying vec3 vTransformedNormal;
varying vec4 vPosition;
uniform float uMaterialShininess;
uniform bool uShowSpecularHighlights;
uniform bool uUseLighting;
uniform bool uUseTextures;
uniform vec3 uAmbientColor;
uniform vec3 uPointLightingLocation;
uniform vec3 uPointLightingSpecularColor;
uniform vec3 uPointLightingDiffuseColor;
uniform sampler2D uSampler;
void main(void) {
vec3 lightWeighting;
if (!uUseLighting) {
lightWeighting = vec3(1.0, 1.0, 1.0);
} else {
vec3 lightDirection = normalize(uPointLightingLocation - vPosition.xyz);
vec3 normal = normalize(vTransformedNormal);
float specularLightWeighting = 0.0;
if (uShowSpecularHighlights) {
vec3 eyeDirection = normalize(-vPosition.xyz);
vec3 reflectionDirection = reflect(-lightDirection, normal);
specularLightWeighting = pow(max(dot(reflectionDirection, eyeDirection), 0.0), uMaterialShininess);
}
float diffuseLightWeighting = max(dot(normal, lightDirection), 0.0);
lightWeighting = uAmbientColor
+ uPointLightingSpecularColor * specularLightWeighting
+ uPointLightingDiffuseColor * diffuseLightWeighting;
}
vec4 fragmentColor;
if (uUseTextures) {
fragmentColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
} else {
fragmentColor = vec4(1.0, 1.0, 1.0, 1.0);
}
gl_FragColor = vec4(fragmentColor.rgb * lightWeighting, fragmentColor.a);
}
<script id="per-fragment-lighting-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;
attribute vec2 aTextureCoord;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat3 uNMatrix;
varying vec2 vTextureCoord;
varying vec3 vTransformedNormal;
varying vec4 vPosition;
void main(void) {
vPosition = uMVMatrix * vec4(aVertexPosition, 1.0);
gl_Position = uPMatrix * vPosition;
vTextureCoord = aTextureCoord;
vTransformedNormal = uNMatrix * aVertexNormal;
}
有任何想法吗?提前致谢!
在移动设备上,WebGL 实现可能对非基础二维纹理等事物敏感,或者可能需要显式设置纹理环绕行为。
我注意到您的 grass texture 尺寸为 590x590。考虑将你的纹理调整到最接近的两个维度(即,在你的草纹理的情况下,512x512)
此外,我建议您将纹理对象上的 gl.TEXTURE_WRAP_S
和 gl.TEXTURE_WRAP_T
参数明确设置为 gl.GL_REPEAT
,因为这可能是您的纹理唯一的另一个原因部分显示在几何体上。
您可以通过以下方式在纹理对象上设置环绕行为:
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
根据@gman:
change mediump to highp in your shaders and see what that does
这确实有效!!谢谢@gman!
所以我做了一个 WebGL 网站,可以在这里访问: https://jameswebsite.azurewebsites.net/
它在 PC 上看起来不错(或符合预期),但在移动设备上看起来很有趣。看起来纹理映射可能已关闭(可能是纹理裁剪问题),但似乎也没有出现任何阴影。
PC端截图如下:
PC 图片
这是移动设备的屏幕截图:
手机图片
我已经关闭了纹理,但仍然有这个问题。这使我相信问题可能出在我的着色器中。这是我的着色器:
<script id="per-fragment-lighting-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec2 vTextureCoord;
varying vec3 vTransformedNormal;
varying vec4 vPosition;
uniform float uMaterialShininess;
uniform bool uShowSpecularHighlights;
uniform bool uUseLighting;
uniform bool uUseTextures;
uniform vec3 uAmbientColor;
uniform vec3 uPointLightingLocation;
uniform vec3 uPointLightingSpecularColor;
uniform vec3 uPointLightingDiffuseColor;
uniform sampler2D uSampler;
void main(void) {
vec3 lightWeighting;
if (!uUseLighting) {
lightWeighting = vec3(1.0, 1.0, 1.0);
} else {
vec3 lightDirection = normalize(uPointLightingLocation - vPosition.xyz);
vec3 normal = normalize(vTransformedNormal);
float specularLightWeighting = 0.0;
if (uShowSpecularHighlights) {
vec3 eyeDirection = normalize(-vPosition.xyz);
vec3 reflectionDirection = reflect(-lightDirection, normal);
specularLightWeighting = pow(max(dot(reflectionDirection, eyeDirection), 0.0), uMaterialShininess);
}
float diffuseLightWeighting = max(dot(normal, lightDirection), 0.0);
lightWeighting = uAmbientColor
+ uPointLightingSpecularColor * specularLightWeighting
+ uPointLightingDiffuseColor * diffuseLightWeighting;
}
vec4 fragmentColor;
if (uUseTextures) {
fragmentColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
} else {
fragmentColor = vec4(1.0, 1.0, 1.0, 1.0);
}
gl_FragColor = vec4(fragmentColor.rgb * lightWeighting, fragmentColor.a);
}
<script id="per-fragment-lighting-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;
attribute vec2 aTextureCoord;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat3 uNMatrix;
varying vec2 vTextureCoord;
varying vec3 vTransformedNormal;
varying vec4 vPosition;
void main(void) {
vPosition = uMVMatrix * vec4(aVertexPosition, 1.0);
gl_Position = uPMatrix * vPosition;
vTextureCoord = aTextureCoord;
vTransformedNormal = uNMatrix * aVertexNormal;
}
有任何想法吗?提前致谢!
在移动设备上,WebGL 实现可能对非基础二维纹理等事物敏感,或者可能需要显式设置纹理环绕行为。
我注意到您的 grass texture 尺寸为 590x590。考虑将你的纹理调整到最接近的两个维度(即,在你的草纹理的情况下,512x512)
此外,我建议您将纹理对象上的 gl.TEXTURE_WRAP_S
和 gl.TEXTURE_WRAP_T
参数明确设置为 gl.GL_REPEAT
,因为这可能是您的纹理唯一的另一个原因部分显示在几何体上。
您可以通过以下方式在纹理对象上设置环绕行为:
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
根据@gman:
change mediump to highp in your shaders and see what that does
这确实有效!!谢谢@gman!