[英]"require() of ES Module [...] is not supported" when using typescript
[英]OpenGL ES 2 Shader linking fails when accessing texture using i
我正在嘗試在我的着色器中添加對多個陰影貼圖的支持,當我嘗試訪問統一結構中的 sampler2D 時,它只是沒有鏈接。 我的片段着色器:
#version 300 es
precision highp float;
precision highp int;
const int MAX_LIGHTS = 3;
#ifndef LIGHTINFO_STRUCT_H
#define LIGHTINFO_STRUCT_H
struct LightInfo {
sampler2D shadow_map;
vec3 reverse_light_direction;
vec4 color;
vec3 position;
float intensity;
mat4 texture_matrix;
};
#endif
in vec2 vtf_tex_coord;
in vec4 vtf_projected_tex_coords[MAX_LIGHTS];
in vec3 vtf_normal;
in vec3 vtf_frag_pos;
uniform sampler2D u_map_albedo;
uniform sampler2D u_map_normal;
uniform LightInfo u_lights[MAX_LIGHTS];
uniform int u_present_lights;
out vec4 out_color;
const vec4 AMBIENT_LIGHT = 0.1 * vec4(0.8, 0.8, 1, 1);
const float BIAS = -0.006;
float calculateLightIncidence(vec3 position, vec3 lightPosition, float intensity) {
float d = distance(position, lightPosition);
return intensity / (1.0 + d * d);
}
bool isInRange(vec2 tex_coord) {
return tex_coord.x >= 0.0 && tex_coord.x <= 1.0 && tex_coord.y >= 0.0 && tex_coord.y <= 1.0;
}
void main() {
vec3 testNormal = texture(u_map_normal, vtf_tex_coord).rgb;
vec3 normal = normalize(vtf_normal);
float fragmentDirectLight = 0.0;
float fragmentLightMultiplier = 1.0;
// calculate for all light sources
for (int i = 0; i < 3; i++) {
// if (i >= u_present_lights) break;
fragmentDirectLight += dot(normal, u_lights[i].reverse_light_direction);
// shadow map coords
vec3 projectedShadowMapCoords = vtf_projected_tex_coords[i].xyz / vtf_projected_tex_coords[i].w;
float projectedCurrentDepth = projectedShadowMapCoords.z + BIAS;
float projectedDepth = texture(u_lights[i].shadow_map, projectedShadowMapCoords.xy).r;
float projectedShadowLight = projectedCurrentDepth < projectedDepth ? 1.0 : 0.0;
float shadowMultiplier = isInRange(projectedShadowMapCoords.xy) ? clamp(projectedShadowLight, 0.3, 1.0) : 1.0;
fragmentLightMultiplier *= shadowMultiplier;
}
fragmentDirectLight = clamp(fragmentDirectLight, 0.1, 1.0);
float at = calculateLightIncidence(vtf_frag_pos, u_lights[0].position, u_lights[0].intensity);
vec4 tex_color = texture(u_map_albedo, vtf_tex_coord);
vec3 col = mix(tex_color.rgb, u_lights[0].color.rgb, at);
out_color = vec4(col * fragmentLightMultiplier * clamp(fragmentDirectLight, 0.3, 1.0), 1.0);
}
不要介意顏色的混亂,我正在嘗試讓陰影貼圖首先工作。
問題是:如果我換行
float projectedDepth = texture(u_lights[i].shadow_map, projectedShadowMapCoords.xy).r;
至
float projectedDepth = texture(u_lights[0].shadow_map, projectedShadowMapCoords.xy).r;
它可以正常工作,所有內容都鏈接並正確顯示。 但是如果我把它改回索引訪問,它就不再鏈接了。
為了清楚起見,我的這部分代碼中報告了鏈接錯誤:
static createProgram(gl: WebGL2RenderingContext, vertexShader: string, fragmentShader: string): WebGLProgram {
const program = gl.createProgram();
if (!program) throw `Failed to create shader program with shaders: ${vertexShader} and ${fragmentShader}`;
gl.attachShader(program, this.createShader(gl, gl.VERTEX_SHADER, vertexShader));
gl.attachShader(program, this.createShader(gl, gl.FRAGMENT_SHADER, fragmentShader));
gl.linkProgram(program);
const success = gl.getProgramParameter(program, gl.LINK_STATUS);
if (success)
return program;
gl.deleteProgram(program);
throw `Failed to link shader program with shaders: \n\n${vertexShader}\n\n and \n\n${fragmentShader}\n\nError: ${gl.getError()}`
}
它打印錯誤代碼0。
所有制服都設置正確,如果我將其更改為訪問u_lights[i].shadow_map
,為什么它沒有鏈接?
另外,評論中斷是因為我嘗試將 for 循環設置為執行固定次數以查看是否是問題所在,然后才for (int i = 0; i < u_present_lights; i++)
。
我沒有收到編譯錯誤,只是無法鏈接着色器。
這是我的頂點着色器以防萬一:
#version 300 es
precision highp float;
precision highp int;
const int MAX_LIGHTS = 3;
#ifndef LIGHTINFO_STRUCT_H
#define LIGHTINFO_STRUCT_H
struct LightInfo {
sampler2D shadow_map;
vec3 reverse_light_direction;
vec4 color;
vec3 position;
int casts_shadows;
float intensity;
mat4 texture_matrix;
};
#endif
layout (location = 0) in vec3 a_pos;
layout (location = 1) in vec2 a_uv;
layout (location = 2) in vec3 a_normal;
out vec2 vtf_tex_coord;
out vec4 vtf_projected_tex_coords[MAX_LIGHTS];
out vec3 vtf_normal;
out vec3 vtf_frag_pos;
uniform mat4 u_model;
uniform mat4 u_view;
uniform mat4 u_projection;
uniform LightInfo u_lights[MAX_LIGHTS];
uniform int u_present_lights;
void main() {
vec4 world_pos = u_model * vec4(a_pos, 1.0);
gl_Position = u_projection * u_view * world_pos;
vtf_tex_coord = a_uv;
for (int i = 0; i < u_present_lights; i++) {
vtf_projected_tex_coords[i] = u_lights[i].texture_matrix * world_pos;
}
vtf_normal = mat3(u_model) * a_normal;
vtf_frag_pos = world_pos.xyz / world_pos.w;
}
OpenGLES 2 使用 GLSL ES 100。此處的附錄 A 第 4 節和第 5 節 (p108)介紹了有關索引采樣器的規則。 規則要求支持constant index expression
,這基本上意味着您可以使用硬編碼/常量索引、統一或簡單循環。 您正在使用一個簡單的循環,因此您滿足該條件。
但有一點奇怪。 您的標題提到了 OpenGLES 2,但您的着色器指定了#version 300 es
,它只能在 OpenGLES 3 或更高版本上使用,所以我不太確定那里的情況。
GLSL ES 300 的規范在這里,它對索引采樣器有更嚴格的規則。 在 ES 300 中,規則只是constant integral expressions
。 這排除了使用簡單循環中的索引的可能性。 引用規范:
GLSL ES 1.00 支持通過常量索引表達式對采樣器的 arrays 進行索引。 常量索引表達式是由常量表達式和某些循環索引形成的表達式,為循環結構的子集定義。 這個功能應該包含在 GLSL ES 3.00 中嗎?
解決方案:編號 Arrays 的采樣器只能由常量積分表達式索引。
您可能無法手動展開循環。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.