/* clang-format off */
#[modes]
mode_default =
mode_copy = #define MODE_DIRECT_WRITE
#[specializations]
#[vertex]
layout(location = 0) in highp vec2 vertex_attrib;
/* clang-format on */
out highp vec2 uv_interp;
void main() {
uv_interp = vertex_attrib;
gl_Position = vec4(uv_interp, 0.0, 1.0);
}
/* clang-format off */
#[fragment]
#define M_PI 3.14159265359
uniform samplerCube source_cube; //texunit:0
/* clang-format on */
uniform int face_id;
#ifndef MODE_DIRECT_WRITE
uniform uint sample_count;
uniform vec4 sample_directions_mip[MAX_SAMPLE_COUNT];
uniform float weight;
#endif
in highp vec2 uv_interp;
layout(location = 0) out vec4 frag_color;
#define M_PI 3.14159265359
// Don't include tonemap_inc.glsl because all we want is these functions, we don't want the uniforms
vec3 linear_to_srgb(vec3 color) {
return max(vec3(1.055) * pow(color, vec3(0.416666667)) - vec3(0.055), vec3(0.0));
}
vec3 srgb_to_linear(vec3 color) {
return color * (color * (color * 0.305306011 + 0.682171111) + 0.012522878);
}
vec3 texelCoordToVec(vec2 uv, int faceID) {
mat3 faceUvVectors[6];
// -x
faceUvVectors[1][0] = vec3(0.0, 0.0, 1.0); // u -> +z
faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[1][2] = vec3(-1.0, 0.0, 0.0); // -x face
// +x
faceUvVectors[0][0] = vec3(0.0, 0.0, -1.0); // u -> -z
faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[0][2] = vec3(1.0, 0.0, 0.0); // +x face
// -y
faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[3][1] = vec3(0.0, 0.0, -1.0); // v -> -z
faceUvVectors[3][2] = vec3(0.0, -1.0, 0.0); // -y face
// +y
faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[2][1] = vec3(0.0, 0.0, 1.0); // v -> +z
faceUvVectors[2][2] = vec3(0.0, 1.0, 0.0); // +y face
// -z
faceUvVectors[5][0] = vec3(-1.0, 0.0, 0.0); // u -> -x
faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[5][2] = vec3(0.0, 0.0, -1.0); // -z face
// +z
faceUvVectors[4][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[4][2] = vec3(0.0, 0.0, 1.0); // +z face
// out = u * s_faceUv[0] + v * s_faceUv[1] + s_faceUv[2].
vec3 result = (faceUvVectors[faceID][0] * uv.x) + (faceUvVectors[faceID][1] * uv.y) + faceUvVectors[faceID][2];
return normalize(result);
}
void main() {
vec3 color = vec3(0.0);
vec2 uv = uv_interp;
vec3 N = texelCoordToVec(uv, face_id);
#ifdef MODE_DIRECT_WRITE
frag_color = vec4(textureLod(source_cube, N, 0.0).rgb, 1.0);
#else
vec4 sum = vec4(0.0);
vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
mat3 T;
T[0] = normalize(cross(UpVector, N));
T[1] = cross(N, T[0]);
T[2] = N;
for (uint sample_num = 0u; sample_num < sample_count; sample_num++) {
vec4 sample_direction_mip = sample_directions_mip[sample_num];
vec3 L = T * sample_direction_mip.xyz;
vec3 val = textureLod(source_cube, L, sample_direction_mip.w).rgb;
// Mix using linear
val = srgb_to_linear(val);
sum.rgb += val * sample_direction_mip.z;
}
sum /= weight;
sum.rgb = linear_to_srgb(sum.rgb);
frag_color = vec4(sum.rgb, 1.0);
#endif
}