From cb34b70df13ad9f7942b0c363edc71cfd417bb21 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Fri, 21 Oct 2016 07:27:13 -0300 Subject: More scene work, can display a skybox --- drivers/gles3/shaders/SCsub | 1 + drivers/gles3/shaders/copy.glsl | 17 +++- drivers/gles3/shaders/cubemap_filter.glsl | 143 ++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+), 3 deletions(-) create mode 100644 drivers/gles3/shaders/cubemap_filter.glsl (limited to 'drivers/gles3/shaders') diff --git a/drivers/gles3/shaders/SCsub b/drivers/gles3/shaders/SCsub index 0fa0e3b73a..afffe10316 100644 --- a/drivers/gles3/shaders/SCsub +++ b/drivers/gles3/shaders/SCsub @@ -5,4 +5,5 @@ if env['BUILDERS'].has_key('GLES3_GLSL'): env.GLES3_GLSL('canvas.glsl'); env.GLES3_GLSL('canvas_shadow.glsl'); env.GLES3_GLSL('scene.glsl'); + env.GLES3_GLSL('cubemap_filter.glsl'); diff --git a/drivers/gles3/shaders/copy.glsl b/drivers/gles3/shaders/copy.glsl index aba280186a..eb58d66431 100644 --- a/drivers/gles3/shaders/copy.glsl +++ b/drivers/gles3/shaders/copy.glsl @@ -33,20 +33,31 @@ void main() { #ifdef USE_CUBEMAP in vec3 cube_interp; -uniform samplerCube source_cube; +uniform samplerCube source_cube; //texunit:0 #else in vec2 uv_interp; -uniform sampler2D source; +uniform sampler2D source; //texunit:0 #endif + +uniform float stuff; + in vec2 uv2_interp; -layout(location = 0) vec4 frag_color; //color:0 +layout(location = 0) out vec4 frag_color; void main() { //vec4 color = color_interp; +#ifdef USE_CUBEMAP + vec4 color = texture( source_cube, normalize(cube_interp) ); + +#else + vec4 color = texture( source, uv_interp ); +#endif + + frag_color = color; } diff --git a/drivers/gles3/shaders/cubemap_filter.glsl b/drivers/gles3/shaders/cubemap_filter.glsl new file mode 100644 index 0000000000..f450f34113 --- /dev/null +++ b/drivers/gles3/shaders/cubemap_filter.glsl @@ -0,0 +1,143 @@ +[vertex] + + +layout(location=0) in highp vec2 vertex; + +layout(location=1) in highp vec2 uv; + +out highp vec2 uv_interp; + +void main() { + + uv_interp=uv; + gl_Position=vec4(vertex,0,1); +} + +[fragment] + + +uniform samplerCube source_cube; //texunit:1 +uniform int face_id; +uniform float roughness; +in highp vec2 uv_interp; + + +layout(location = 0) vec4 frag_color; + + +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); +} + +vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N) +{ + float a = Roughness * Roughness; // DISNEY'S ROUGHNESS [see Burley'12 siggraph] + + // Compute distribution direction + float Phi = 2.0 * M_PI * Xi.x; + float CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y)); + float SinTheta = sqrt(1.0 - CosTheta * CosTheta); + + // Convert to spherical direction + vec3 H; + H.x = SinTheta * cos(Phi); + H.y = SinTheta * sin(Phi); + H.z = CosTheta; + + 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); + + // Tangent to world space + return TangentX * H.x + TangentY * H.y + N * H.z; +} + +// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html +float GGX(float NdotV, float a) +{ + float k = a / 2.0; + return NdotV / (NdotV * (1.0 - k) + k); +} + +// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html +float G_Smith(float a, float nDotV, float nDotL) +{ + return GGX(nDotL, a * a) * GGX(nDotV, a * a); +} + +float radicalInverse_VdC(uint bits) { + bits = (bits << 16u) | (bits >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + return float(bits) * 2.3283064365386963e-10; // / 0x100000000 +} + +vec2 Hammersley(uint i, uint N) { + return vec2(float(i)/float(N), radicalInverse_VdC(i)); +} + +#define SAMPLE_COUNT 1024 + +void main() { + + vec2 uv = (uv_interp * 2.0) - 1.0; + vec3 N = texelCoordToVec(uv, face_id); + + //vec4 color = color_interp; + vec4 sum = vec4(0.0, 0.0, 0.0, 0.0); + + for(int sampleNum = 0; sampleNum < SAMPLE_COUNT; sampleNum++) { + vec2 xi = Hammersley(sampleNum, SAMPLE_COUNT); + vec2 xi = texture2DLod(Texture0, vec2(float(sampleNum) / float(SAMPLE_COUNT), 0.5), 0.0).xy; + + vec3 H = ImportanceSampleGGX( xi, roughness, N ); + vec3 V = N; + vec3 L = normalize(2.0 * dot( V, H ) * H - V); + + float ndotl = max(0.0, dot(N, L)); + vec3 s = textureCubeLod(u_skyCube, H, 0.0).rgb * ndotl; + + sum += vec4(s, 1.0); + } + sum /= sum.w; + + frag_color = vec4(sum.rgb, 1.0); +} + -- cgit v1.2.3