2018-08-27 07:31:48 +02:00
|
|
|
/* clang-format off */
|
2017-12-04 13:41:34 +01:00
|
|
|
[vertex]
|
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
#ifdef USE_GLES_OVER_GL
|
|
|
|
#define mediump
|
|
|
|
#define highp
|
|
|
|
#else
|
|
|
|
precision mediump float;
|
|
|
|
precision mediump int;
|
|
|
|
#endif
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
attribute highp vec2 vertex; // attrib:0
|
2018-08-27 07:31:48 +02:00
|
|
|
/* clang-format on */
|
2018-02-24 14:48:22 +01:00
|
|
|
attribute highp vec2 uv; // attrib:4
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
varying highp vec2 uv_interp;
|
2017-12-04 13:41:34 +01:00
|
|
|
|
|
|
|
void main() {
|
|
|
|
|
2018-08-24 14:50:59 +02:00
|
|
|
uv_interp = uv;
|
|
|
|
gl_Position = vec4(vertex, 0, 1);
|
2017-12-04 13:41:34 +01:00
|
|
|
}
|
|
|
|
|
2018-08-27 07:31:48 +02:00
|
|
|
/* clang-format off */
|
2017-12-04 13:41:34 +01:00
|
|
|
[fragment]
|
|
|
|
|
2018-08-23 17:08:16 +02:00
|
|
|
#extension GL_ARB_shader_texture_lod : enable
|
|
|
|
|
|
|
|
#ifndef GL_ARB_shader_texture_lod
|
|
|
|
#define texture2DLod(img, coord, lod) texture2D(img, coord)
|
|
|
|
#define textureCubeLod(img, coord, lod) textureCube(img, coord)
|
|
|
|
#endif
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
#ifdef USE_GLES_OVER_GL
|
|
|
|
#define mediump
|
|
|
|
#define highp
|
|
|
|
#else
|
|
|
|
precision mediump float;
|
|
|
|
precision mediump int;
|
|
|
|
#endif
|
2017-12-04 13:41:34 +01:00
|
|
|
|
|
|
|
#ifdef USE_SOURCE_PANORAMA
|
|
|
|
uniform sampler2D source_panorama; //texunit:0
|
2018-02-24 14:48:22 +01:00
|
|
|
#else
|
2017-12-04 13:41:34 +01:00
|
|
|
uniform samplerCube source_cube; //texunit:0
|
|
|
|
#endif
|
2018-08-27 07:31:48 +02:00
|
|
|
/* clang-format on */
|
2017-12-04 13:41:34 +01:00
|
|
|
|
|
|
|
uniform int face_id;
|
|
|
|
uniform float roughness;
|
2018-02-24 14:48:22 +01:00
|
|
|
varying highp vec2 uv_interp;
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
uniform sampler2D radical_inverse_vdc_cache; // texunit:1
|
2017-12-04 13:41:34 +01:00
|
|
|
|
|
|
|
#define M_PI 3.14159265359
|
|
|
|
|
|
|
|
#ifdef LOW_QUALITY
|
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
#define SAMPLE_COUNT 64
|
2017-12-04 13:41:34 +01:00
|
|
|
|
|
|
|
#else
|
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
#define SAMPLE_COUNT 512
|
2017-12-04 13:41:34 +01:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef USE_SOURCE_PANORAMA
|
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
vec4 texturePanorama(sampler2D pano, vec3 normal) {
|
2017-12-04 13:41:34 +01:00
|
|
|
|
|
|
|
vec2 st = vec2(
|
2018-08-24 14:50:59 +02:00
|
|
|
atan(normal.x, normal.z),
|
|
|
|
acos(normal.y));
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-08-24 14:50:59 +02:00
|
|
|
if (st.x < 0.0)
|
|
|
|
st.x += M_PI * 2.0;
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-08-24 14:50:59 +02:00
|
|
|
st /= vec2(M_PI * 2.0, M_PI);
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-08-24 14:50:59 +02:00
|
|
|
return texture2DLod(pano, st, 0.0);
|
2017-12-04 13:41:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
vec3 texelCoordToVec(vec2 uv, int faceID) {
|
|
|
|
mat3 faceUvVectors[6];
|
|
|
|
|
|
|
|
// -x
|
2018-08-24 14:50:59 +02:00
|
|
|
faceUvVectors[0][0] = vec3(0.0, 0.0, 1.0); // u -> +z
|
2018-02-24 14:48:22 +01:00
|
|
|
faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y
|
|
|
|
faceUvVectors[0][2] = vec3(-1.0, 0.0, 0.0); // -x face
|
|
|
|
|
|
|
|
// +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
|
2018-08-24 14:50:59 +02:00
|
|
|
faceUvVectors[1][2] = vec3(1.0, 0.0, 0.0); // +x face
|
2018-02-24 14:48:22 +01:00
|
|
|
|
|
|
|
// -y
|
2018-08-24 14:50:59 +02:00
|
|
|
faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x
|
2018-02-24 14:48:22 +01:00
|
|
|
faceUvVectors[2][1] = vec3(0.0, 0.0, -1.0); // v -> -z
|
|
|
|
faceUvVectors[2][2] = vec3(0.0, -1.0, 0.0); // -y face
|
|
|
|
|
|
|
|
// +y
|
2018-08-24 14:50:59 +02:00
|
|
|
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
|
2018-02-24 14:48:22 +01:00
|
|
|
|
|
|
|
// -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
|
|
|
|
|
|
|
|
// +z
|
2018-08-24 14:50:59 +02:00
|
|
|
faceUvVectors[5][0] = vec3(1.0, 0.0, 0.0); // u -> +x
|
2018-02-24 14:48:22 +01:00
|
|
|
faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y
|
2018-08-24 14:50:59 +02:00
|
|
|
faceUvVectors[5][2] = vec3(0.0, 0.0, 1.0); // +z face
|
2018-02-24 14:48:22 +01:00
|
|
|
|
|
|
|
// 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);
|
2017-12-04 13:41:34 +01:00
|
|
|
}
|
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N) {
|
|
|
|
float a = Roughness * Roughness; // DISNEY'S ROUGHNESS [see Burley'12 siggraph]
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
// Compute distribution direction
|
|
|
|
float Phi = 2.0 * M_PI * Xi.x;
|
2018-08-24 14:50:59 +02:00
|
|
|
float CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a * a - 1.0) * Xi.y));
|
2018-02-24 14:48:22 +01:00
|
|
|
float SinTheta = sqrt(1.0 - CosTheta * CosTheta);
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
// Convert to spherical direction
|
|
|
|
vec3 H;
|
|
|
|
H.x = SinTheta * cos(Phi);
|
|
|
|
H.y = SinTheta * sin(Phi);
|
|
|
|
H.z = CosTheta;
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
|
|
|
|
vec3 TangentX = normalize(cross(UpVector, N));
|
|
|
|
vec3 TangentY = cross(N, TangentX);
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
// Tangent to world space
|
|
|
|
return TangentX * H.x + TangentY * H.y + N * H.z;
|
|
|
|
}
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
float radical_inverse_VdC(int i) {
|
|
|
|
return texture2D(radical_inverse_vdc_cache, vec2(float(i) / 512.0, 0.0)).x;
|
|
|
|
}
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
vec2 Hammersley(int i, int N) {
|
|
|
|
return vec2(float(i) / float(N), radical_inverse_VdC(i));
|
|
|
|
}
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
uniform bool z_flip;
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
void main() {
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
vec3 color = vec3(0.0);
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
vec2 uv = (uv_interp * 2.0) - 1.0;
|
|
|
|
vec3 N = texelCoordToVec(uv, face_id);
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
vec4 sum = vec4(0.0);
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
for (int sample_num = 0; sample_num < SAMPLE_COUNT; sample_num++) {
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
vec2 xi = Hammersley(sample_num, SAMPLE_COUNT);
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
vec3 H = ImportanceSampleGGX(xi, roughness, N);
|
|
|
|
vec3 V = N;
|
2018-09-30 04:47:24 +02:00
|
|
|
vec3 L = (2.0 * dot(V, H) * H - V);
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
float NdotL = clamp(dot(N, L), 0.0, 1.0);
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
if (NdotL > 0.0) {
|
2017-12-04 13:41:34 +01:00
|
|
|
|
|
|
|
#ifdef USE_SOURCE_PANORAMA
|
2018-09-30 04:47:24 +02:00
|
|
|
vec3 val = texturePanorama(source_panorama, L).rgb;
|
2018-02-24 14:48:22 +01:00
|
|
|
#else
|
2018-09-30 16:31:46 +02:00
|
|
|
vec3 val = textureCubeLod(source_cube, L, 0.0).rgb;
|
2017-12-04 13:41:34 +01:00
|
|
|
#endif
|
2018-09-30 04:47:24 +02:00
|
|
|
//mix using Linear, to approximate high end back-end
|
|
|
|
val = mix(pow((val + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), val * (1.0 / 12.92), vec3(lessThan(val, vec3(0.04045))));
|
|
|
|
|
|
|
|
sum.rgb += val * NdotL;
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
sum.a += NdotL;
|
2017-12-04 13:41:34 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
sum /= sum.a;
|
2017-12-04 13:41:34 +01:00
|
|
|
|
2018-09-30 04:47:24 +02:00
|
|
|
vec3 a = vec3(0.055);
|
|
|
|
sum.rgb = mix((vec3(1.0) + a) * pow(sum.rgb, vec3(1.0 / 2.4)) - a, 12.92 * sum.rgb, vec3(lessThan(sum.rgb, vec3(0.0031308))));
|
|
|
|
|
2018-02-24 14:48:22 +01:00
|
|
|
gl_FragColor = vec4(sum.rgb, 1.0);
|
2017-12-04 13:41:34 +01:00
|
|
|
}
|