这个着色器可以在笔记本电脑上运行,但由于某种原因,它在移动设备上一直失败我认为我在精度上做错了什么,但我不知道这里的错误是什么:
THREE.WebGLProgram:着色器错误:0 35715 false gl.getProgramInfoLog 无效着色器 THREE.WebGLShader:gl.getShaderInfoLog() 片段 0:434: S0032: 没有为变量“float[4]”定义默认精度1: #版本 300 es 2: #define 变化于 3: out highp vec4 pc_fragColor;
这是 js 选项卡中的着色器代码: https://codepen.io/uiunicorn/pen/QWQrQBB
满:
export const terrain_shader = (function() {
const _VS_1 = `
// Triplanar Attributes
in vec4 weights1;
in vec4 weights2;
// Outputs
out vec3 vCoords;
out vec4 vWeights1;
out vec4 vWeights2;
`;
const _VS_2 = `
vCoords = transformed.xyz;
vWeights1 = weights1;
vWeights2 = weights2;
`;
const _VS = `
// Attributes
in vec3 coords;
in vec3 color;
in vec4 weights1;
in vec4 weights2;
// Outputs
out vec2 vUV;
out vec4 vColor;
out vec3 vNormal;
out vec3 vCoords;
out vec4 vWeights1;
out vec4 vWeights2;
void main(){
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
vUV = uv;
vNormal = normal;
vColor = vec4(color, 1);
vCoords = position.xyz;
vWeights1 = weights1;
vWeights2 = weights2;
}
`;
const _PS = `
precision highp float;
precision highp int;
precision highp sampler2DArray;
uniform sampler2DArray TRIPLANAR_normalMap;
uniform sampler2DArray TRIPLANAR_diffuseMap;
uniform sampler2D TRIPLANAR_noiseMap;
in vec3 vCoords;
in vec4 vWeights1;
in vec4 vWeights2;
const float _TRI_SCALE = 10.0;
float sum( vec3 v ) { return v.x+v.y+v.z; }
vec4 hash4( vec2 p ) {
return fract(
sin(vec4(1.0+dot(p,vec2(37.0,17.0)),
2.0+dot(p,vec2(11.0,47.0)),
3.0+dot(p,vec2(41.0,29.0)),
4.0+dot(p,vec2(23.0,31.0))))*103.0);
}
vec4 _TerrainBlend_4(vec4 samples[4]) {
float depth = 0.2;
float ma = max(
samples[0].w,
max(
samples[1].w,
max(samples[2].w, samples[3].w))) - depth;
float b1 = max(samples[0].w - ma, 0.0);
float b2 = max(samples[1].w - ma, 0.0);
float b3 = max(samples[2].w - ma, 0.0);
float b4 = max(samples[3].w - ma, 0.0);
vec4 numer = (
samples[0] * b1 + samples[1] * b2 +
samples[2] * b3 + samples[3] * b4);
float denom = (b1 + b2 + b3 + b4);
return numer / denom;
}
vec4 _TerrainBlend_4_lerp(vec4 samples[4]) {
return (
samples[0] * samples[0].w + samples[1] * samples[1].w +
samples[2] * samples[2].w + samples[3] * samples[3].w);
}
// Lifted from https://www.shadertoy.com/view/Xtl3zf
vec4 texture_UV(in sampler2DArray srcTexture, in vec3 x) {
float k = texture(TRIPLANAR_noiseMap, 0.0025*x.xy).x; // cheap (cache friendly) lookup
float l = k*8.0;
float f = fract(l);
float ia = floor(l+0.5); // suslik's method (see comments)
float ib = floor(l);
f = min(f, 1.0-f)*2.0;
vec2 offa = sin(vec2(3.0,7.0)*ia); // can replace with any other hash
vec2 offb = sin(vec2(3.0,7.0)*ib); // can replace with any other hash
vec4 cola = texture(srcTexture, vec3(x.xy + offa, x.z));
vec4 colb = texture(srcTexture, vec3(x.xy + offb, x.z));
return mix(cola, colb, smoothstep(0.2,0.8,f-0.1*sum(cola.xyz-colb.xyz)));
}
vec4 _Triplanar_UV(vec3 pos, vec3 normal, float texSlice, sampler2DArray tex) {
vec4 dx = texture_UV(tex, vec3(pos.zy / _TRI_SCALE, texSlice));
vec4 dy = texture_UV(tex, vec3(pos.xz / _TRI_SCALE, texSlice));
vec4 dz = texture_UV(tex, vec3(pos.xy / _TRI_SCALE, texSlice));
vec3 weights = abs(normal.xyz);
weights = weights / (weights.x + weights.y + weights.z);
return dx * weights.x + dy * weights.y + dz * weights.z;
}
vec4 _TriplanarN_UV(vec3 pos, vec3 normal, float texSlice, sampler2DArray tex) {
// Tangent Reconstruction
// Triplanar uvs
vec2 uvX = pos.zy; // x facing plane
vec2 uvY = pos.xz; // y facing plane
vec2 uvZ = pos.xy; // z facing plane
// Tangent space normal maps
vec3 tx = texture_UV(tex, vec3(uvX / _TRI_SCALE, texSlice)).xyz * vec3(2,2,2) - vec3(1,1,1);
vec3 ty = texture_UV(tex, vec3(uvY / _TRI_SCALE, texSlice)).xyz * vec3(2,2,2) - vec3(1,1,1);
vec3 tz = texture_UV(tex, vec3(uvZ / _TRI_SCALE, texSlice)).xyz * vec3(2,2,2) - vec3(1,1,1);
vec3 weights = abs(normal.xyz);
weights = weights / (weights.x + weights.y + weights.z);
// Get the sign (-1 or 1) of the surface normal
vec3 axis = sign(normal);
// Construct tangent to world matrices for each axis
vec3 tangentX = normalize(cross(normal, vec3(0.0, axis.x, 0.0)));
vec3 bitangentX = normalize(cross(tangentX, normal)) * axis.x;
mat3 tbnX = mat3(tangentX, bitangentX, normal);
vec3 tangentY = normalize(cross(normal, vec3(0.0, 0.0, axis.y)));
vec3 bitangentY = normalize(cross(tangentY, normal)) * axis.y;
mat3 tbnY = mat3(tangentY, bitangentY, normal);
vec3 tangentZ = normalize(cross(normal, vec3(0.0, -axis.z, 0.0)));
vec3 bitangentZ = normalize(-cross(tangentZ, normal)) * axis.z;
mat3 tbnZ = mat3(tangentZ, bitangentZ, normal);
// Apply tangent to world matrix and triblend
// Using clamp() because the cross products may be NANs
vec3 worldNormal = normalize(
clamp(tbnX * tx, -1.0, 1.0) * weights.x +
clamp(tbnY * ty, -1.0, 1.0) * weights.y +
clamp(tbnZ * tz, -1.0, 1.0) * weights.z
);
return vec4(worldNormal, 0.0);
}
vec4 _Triplanar(vec3 pos, vec3 normal, float texSlice, sampler2DArray tex) {
vec4 dx = texture(tex, vec3(pos.zy / _TRI_SCALE, texSlice));
vec4 dy = texture(tex, vec3(pos.xz / _TRI_SCALE, texSlice));
vec4 dz = texture(tex, vec3(pos.xy / _TRI_SCALE, texSlice));
vec3 weights = abs(normal.xyz);
weights = weights / (weights.x + weights.y + weights.z);
return dx * weights.x + dy * weights.y + dz * weights.z;
}
vec4 _TriplanarN(vec3 pos, vec3 normal, float texSlice, sampler2DArray tex) {
vec2 uvx = pos.zy;
vec2 uvy = pos.xz;
vec2 uvz = pos.xy;
vec3 tx = texture(tex, vec3(uvx / _TRI_SCALE, texSlice)).xyz * vec3(2,2,2) - vec3(1,1,1);
vec3 ty = texture(tex, vec3(uvy / _TRI_SCALE, texSlice)).xyz * vec3(2,2,2) - vec3(1,1,1);
vec3 tz = texture(tex, vec3(uvz / _TRI_SCALE, texSlice)).xyz * vec3(2,2,2) - vec3(1,1,1);
vec3 weights = abs(normal.xyz);
weights *= weights;
weights = weights / (weights.x + weights.y + weights.z);
vec3 axis = sign(normal);
vec3 tangentX = normalize(cross(normal, vec3(0.0, axis.x, 0.0)));
vec3 bitangentX = normalize(cross(tangentX, normal)) * axis.x;
mat3 tbnX = mat3(tangentX, bitangentX, normal);
vec3 tangentY = normalize(cross(normal, vec3(0.0, 0.0, axis.y)));
vec3 bitangentY = normalize(cross(tangentY, normal)) * axis.y;
mat3 tbnY = mat3(tangentY, bitangentY, normal);
vec3 tangentZ = normalize(cross(normal, vec3(0.0, -axis.z, 0.0)));
vec3 bitangentZ = normalize(-cross(tangentZ, normal)) * axis.z;
mat3 tbnZ = mat3(tangentZ, bitangentZ, normal);
vec3 worldNormal = normalize(
clamp(tbnX * tx, -1.0, 1.0) * weights.x +
clamp(tbnY * ty, -1.0, 1.0) * weights.y +
clamp(tbnZ * tz, -1.0, 1.0) * weights.z);
return vec4(worldNormal, 0.0);
}
void main() {
vec3 worldPosition = vCoords;
float weightIndices[4] = float[4](vWeights1.x, vWeights1.y, vWeights1.z, vWeights1.w);
float weightValues[4] = float[4](vWeights2.x, vWeights2.y, vWeights2.z, vWeights2.w);
// TRIPLANAR SPLATTING w/ NORMALS & UVS
vec3 worldSpaceNormal = normalize(vNormal);
vec4 diffuseSamples[4];
vec4 normalSamples[4];
for (int i = 0; i < 4; ++i) {
vec4 d = vec4(0.0);
vec4 n = vec4(0.0);
if (weightValues[i] > 0.0) {
d = _Triplanar_UV(
worldPosition, worldSpaceNormal, weightIndices[i], TRIPLANAR_diffuseMap);
n = _TriplanarN_UV(
worldPosition, worldSpaceNormal, weightIndices[i], TRIPLANAR_normalMap);
d.w *= weightValues[i];
n.w = d.w;
}
diffuseSamples[i] = d;
normalSamples[i] = n;
}
vec4 diffuseBlended = _TerrainBlend_4(diffuseSamples);
vec4 normalBlended = _TerrainBlend_4(normalSamples);
vec3 diffuse = diffuseBlended.xyz;
vec3 finalColour = diffuse;
// finalColour = vec3(sin(worldPosition.x), sin(worldPosition.y), sin(worldPosition.z));
gl_FragColor = vec4(finalColour, 1);
}
`;
const _PS_1 = `
precision mediump sampler2DArray;
uniform sampler2DArray TRIPLANAR_normalMap;
uniform sampler2DArray TRIPLANAR_diffuseMap;
uniform sampler2D TRIPLANAR_noiseMap;
in vec3 vCoords;
in vec4 vWeights1;
in vec4 vWeights2;
const float _TRI_SCALE = 10.0;
float sum( vec3 v ) { return v.x+v.y+v.z; }
vec4 hash4( vec2 p ) {
return fract(
sin(vec4(1.0+dot(p,vec2(37.0,17.0)),
2.0+dot(p,vec2(11.0,47.0)),
3.0+dot(p,vec2(41.0,29.0)),
4.0+dot(p,vec2(23.0,31.0))))*103.0);
}
vec4 _TerrainBlend_4(vec4 samples[4]) {
float depth = 0.2;
float ma = max(
samples[0].w,
max(
samples[1].w,
max(samples[2].w, samples[3].w))) - depth;
float b1 = max(samples[0].w - ma, 0.0);
float b2 = max(samples[1].w - ma, 0.0);
float b3 = max(samples[2].w - ma, 0.0);
float b4 = max(samples[3].w - ma, 0.0);
vec4 numer = (
samples[0] * b1 + samples[1] * b2 +
samples[2] * b3 + samples[3] * b4);
float denom = (b1 + b2 + b3 + b4);
return numer / denom;
}
vec4 _TerrainBlend_4_lerp(vec4 samples[4]) {
return (
samples[0] * samples[0].w + samples[1] * samples[1].w +
samples[2] * samples[2].w + samples[3] * samples[3].w);
}
// Lifted from https://www.shadertoy.com/view/Xtl3zf
vec4 texture_UV(in sampler2DArray srcTexture, in vec3 x) {
float k = texture(TRIPLANAR_noiseMap, 0.0025*x.xy).x; // cheap (cache friendly) lookup
float l = k*8.0;
float f = fract(l);
float ia = floor(l+0.5); // suslik's method (see comments)
float ib = floor(l);
f = min(f, 1.0-f)*2.0;
vec2 offa = sin(vec2(3.0,7.0)*ia); // can replace with any other hash
vec2 offb = sin(vec2(3.0,7.0)*ib); // can replace with any other hash
vec4 cola = texture(srcTexture, vec3(x.xy + offa, x.z));
vec4 colb = texture(srcTexture, vec3(x.xy + offb, x.z));
return mix(cola, colb, smoothstep(0.2,0.8,f-0.1*sum(cola.xyz-colb.xyz)));
}
vec4 _Triplanar_UV(vec3 pos, vec3 normal, float texSlice, sampler2DArray tex) {
vec4 dx = texture_UV(tex, vec3(pos.zy / _TRI_SCALE, texSlice));
vec4 dy = texture_UV(tex, vec3(pos.xz / _TRI_SCALE, texSlice));
vec4 dz = texture_UV(tex, vec3(pos.xy / _TRI_SCALE, texSlice));
vec3 weights = abs(normal.xyz);
weights = weights / (weights.x + weights.y + weights.z);
return dx * weights.x + dy * weights.y + dz * weights.z;
}
vec4 _TriplanarN_UV(vec3 pos, vec3 normal, float texSlice, sampler2DArray tex) {
// Tangent Reconstruction
// Triplanar uvs
vec2 uvX = pos.zy; // x facing plane
vec2 uvY = pos.xz; // y facing plane
vec2 uvZ = pos.xy; // z facing plane
// Tangent space normal maps
vec3 tx = texture_UV(tex, vec3(uvX / _TRI_SCALE, texSlice)).xyz * vec3(2,2,2) - vec3(1,1,1);
vec3 ty = texture_UV(tex, vec3(uvY / _TRI_SCALE, texSlice)).xyz * vec3(2,2,2) - vec3(1,1,1);
vec3 tz = texture_UV(tex, vec3(uvZ / _TRI_SCALE, texSlice)).xyz * vec3(2,2,2) - vec3(1,1,1);
vec3 weights = abs(normal.xyz);
weights = weights / (weights.x + weights.y + weights.z);
// Get the sign (-1 or 1) of the surface normal
vec3 axis = sign(normal);
// Construct tangent to world matrices for each axis
vec3 tangentX = normalize(cross(normal, vec3(0.0, axis.x, 0.0)));
vec3 bitangentX = normalize(cross(tangentX, normal)) * axis.x;
mat3 tbnX = mat3(tangentX, bitangentX, normal);
vec3 tangentY = normalize(cross(normal, vec3(0.0, 0.0, axis.y)));
vec3 bitangentY = normalize(cross(tangentY, normal)) * axis.y;
mat3 tbnY = mat3(tangentY, bitangentY, normal);
vec3 tangentZ = normalize(cross(normal, vec3(0.0, -axis.z, 0.0)));
vec3 bitangentZ = normalize(-cross(tangentZ, normal)) * axis.z;
mat3 tbnZ = mat3(tangentZ, bitangentZ, normal);
// Apply tangent to world matrix and triblend
// Using clamp() because the cross products may be NANs
vec3 worldNormal = normalize(
clamp(tbnX * tx, -1.0, 1.0) * weights.x +
clamp(tbnY * ty, -1.0, 1.0) * weights.y +
clamp(tbnZ * tz, -1.0, 1.0) * weights.z
);
return vec4(worldNormal, 0.0);
}
vec4 _Triplanar(vec3 pos, vec3 normal, float texSlice, sampler2DArray tex) {
vec4 dx = texture(tex, vec3(pos.zy / _TRI_SCALE, texSlice));
vec4 dy = texture(tex, vec3(pos.xz / _TRI_SCALE, texSlice));
vec4 dz = texture(tex, vec3(pos.xy / _TRI_SCALE, texSlice));
vec3 weights = abs(normal.xyz);
weights = weights / (weights.x + weights.y + weights.z);
return dx * weights.x + dy * weights.y + dz * weights.z;
}
vec4 _TriplanarN(vec3 pos, vec3 normal, float texSlice, sampler2DArray tex) {
vec2 uvx = pos.zy;
vec2 uvy = pos.xz;
vec2 uvz = pos.xy;
vec3 tx = texture(tex, vec3(uvx / _TRI_SCALE, texSlice)).xyz * vec3(2,2,2) - vec3(1,1,1);
vec3 ty = texture(tex, vec3(uvy / _TRI_SCALE, texSlice)).xyz * vec3(2,2,2) - vec3(1,1,1);
vec3 tz = texture(tex, vec3(uvz / _TRI_SCALE, texSlice)).xyz * vec3(2,2,2) - vec3(1,1,1);
vec3 weights = abs(normal.xyz);
weights *= weights;
weights = weights / (weights.x + weights.y + weights.z);
vec3 axis = sign(normal);
vec3 tangentX = normalize(cross(normal, vec3(0.0, axis.x, 0.0)));
vec3 bitangentX = normalize(cross(tangentX, normal)) * axis.x;
mat3 tbnX = mat3(tangentX, bitangentX, normal);
vec3 tangentY = normalize(cross(normal, vec3(0.0, 0.0, axis.y)));
vec3 bitangentY = normalize(cross(tangentY, normal)) * axis.y;
mat3 tbnY = mat3(tangentY, bitangentY, normal);
vec3 tangentZ = normalize(cross(normal, vec3(0.0, -axis.z, 0.0)));
vec3 bitangentZ = normalize(-cross(tangentZ, normal)) * axis.z;
mat3 tbnZ = mat3(tangentZ, bitangentZ, normal);
vec3 worldNormal = normalize(
clamp(tbnX * tx, -1.0, 1.0) * weights.x +
clamp(tbnY * ty, -1.0, 1.0) * weights.y +
clamp(tbnZ * tz, -1.0, 1.0) * weights.z);
return vec4(worldNormal, 0.0);
}
`;
const _PS_2 = `
{
vec3 worldPosition = vCoords;
float weightIndices[4] = float[4](vWeights1.x, vWeights1.y, vWeights1.z, vWeights1.w);
float weightValues[4] = float[4](vWeights2.x, vWeights2.y, vWeights2.z, vWeights2.w);
// TRIPLANAR SPLATTING w/ NORMALS & UVS
vec3 worldSpaceNormal = normalize(vNormal);
vec4 diffuseSamples[4];
// vec4 normalSamples[4];
for (int i = 0; i < 4; ++i) {
vec4 d = vec4(0.0);
// vec4 n = vec4(0.0);
if (weightValues[i] > 0.0) {
d = _Triplanar_UV(
worldPosition, worldSpaceNormal, weightIndices[i], TRIPLANAR_diffuseMap);
// n = _TriplanarN_UV(
// worldPosition, worldSpaceNormal, weightIndices[i], TRIPLANAR_normalMap);
d.w *= weightValues[i];
// n.w = d.w;
}
diffuseSamples[i] = d;
// normalSamples[i] = n;
}
vec4 diffuseBlended = _TerrainBlend_4(diffuseSamples);
// vec4 normalBlended = _TerrainBlend_4(normalSamples);
diffuseColor = sRGBToLinear(diffuseBlended);
// normal = normalBlended.xyz;
}
`;
return {
VS: _VS,
PS: _PS,
VS1: _VS_1,
VS2: _VS_2,
PS1: _PS_1,
PS2: _PS_2,
};
})();
感谢您的阅读
更新我尝试添加:
precision mediump sampler2DArray;
precision mediump float;
precision mediump int;
uniform sampler2DArray TRIPLANAR_normalMap;
uniform sampler2DArray TRIPLANAR_diffuseMap;
uniform sampler2D TRIPLANAR_noiseMap;
to: const _PS_1 和 _PS 错误仍然存在 这样做也会引发一个新错误:
名称相同但类型/精度不同的制服
我可以通过添加以下内容来消除此错误:
precision mediump float;
到顶点着色器,但我仍然留下原来的错误:
no default precision defined for variable 'float[4]'1
更新
尝试添加
renderer.precision="mediump";
这没有效果
我还注意到地面的纹理,这在移动设备上也是同样的问题,它不会显示出来..我在 Firefox 中也遇到了同样的问题,它正确工作的浏览器是 chrome,
这是网站: http://wonder-3d.hol.es/ADz(1)z/115(1)
这是着色器文件: http://wonder-3d.hol.es/ADz(1)z/src/terrain-shader.js
chrome 的小问题: 在 Chrome 中,如果我在地面纹理加载之前打开和关闭开发工具,纹理将不会像在 Firefox 和移动设备中那样显示,但前提是您完全使用开发工具执行此操作,如果不这样做,它就可以正常工作。 ..所以这不是一个大问题,我可以通过重新打开开发工具来使地形纹理再次显示,并且一切都按预期进行。
感谢您的帮助。
该错误表示
no default precision defined
,因为您没有在着色器代码的开头定义精度。
确保每个完成的着色器在分配给材质时在每个着色器的开头都包含
precision highp float;
。您已将着色器分解为几个单独的文件,因此很难判断它到底应该放在哪里,只需确保它位于开头即可。
OpenGL规范没有为片段着色器定义精度限定符,这意味着您应该自己定义它。
您应该将这两行添加到着色器代码中的 const _PS_1 声明下:
precision highp float; // Define float precision
precision highp int; // Define int precision
导致以下结果:
const _PS_1 = `
precision mediump sampler2DArray;
precision highp float; // Define float precision
precision highp int; // Define int precision
uniform sampler2DArray TRIPLANAR_normalMap;
uniform sampler2DArray TRIPLANAR_diffuseMap;
uniform sampler2D TRIPLANAR_noiseMap;
in vec3 vCoords;
in vec4 vWeights1;
in vec4 vWeights2;
为了获得良好的性能,请始终使用最低精度,即 可能的。这对于低端硬件尤其重要。好的 经验法则是:
- 对于世界空间位置和纹理坐标,请使用 **highp float ** 精度。
- 对于其他所有内容(矢量、HDR 颜色等),请从 **中浮点 ** 精度开始。仅在必要时增加。
我在某些 Android 手机 (Android 12) 上遇到了与您完全相同的问题。它与您初始化数组的方式有关
weightIndices
和weightValues
。
替换:
float weightIndices[4] = float[4](vWeights1.x, vWeights1.y, vWeights1.z, vWeights1.w);
与(与权重值相同):
float weightIndices[4];
weightIndices[0] = vWeights1.x;
weightIndices[1] = vWeights1.y;
weightIndices[2] = vWeights1.z;
weightIndices[3] = vWeights1.w;
我在某些设备上遇到了同样的问题。我相信它与https://www.reddit.com/r/opengl/comments/zs60wi/es_gl_no_default_ precision_defined_for_variable/
相同它看起来像是某些设备或驱动程序上的着色器编译器中的错误。