/*
 * Copyright 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <GLES3/gl3.h>
#include <math/vec2.h>
#include <math/vec3.h>
#include <math/vec4.h>

static const char* VERTEX_SHADER = R"SHADER__(#version 300 es
precision highp float;

layout(location = 0) in vec4 mesh_position;

void main() {
    gl_Position = mesh_position;
}
)SHADER__";

static const char* FRAGMENT_SHADER = R"SHADER__(#version 300 es
precision highp float;

layout(location = 0) uniform vec4 resolution;
layout(location = 1) uniform float time;
layout(location = 2) uniform vec3[4] SPHERICAL_HARMONICS;

layout(location = 0) out vec4 fragColor;

#define saturate(x) clamp(x, 0.0, 1.0)
#define PI 3.14159265359

//------------------------------------------------------------------------------
// Distance field functions
//------------------------------------------------------------------------------

float sdPlane(in vec3 p) {
    return p.y;
}

float sdSphere(in vec3 p, float s) {
    return length(p) - s;
}

float sdTorus(in vec3 p, in vec2 t) {
    return length(vec2(length(p.xz) - t.x, p.y)) - t.y;
}

vec2 opUnion(vec2 d1, vec2 d2) {
    return d1.x < d2.x ? d1 : d2;
}

vec2 scene(in vec3 position) {
    vec2 scene = opUnion(
          vec2(sdPlane(position), 1.0),
          vec2(sdSphere(position - vec3(0.0, 0.4, 0.0), 0.4), 12.0)
    );
    return scene;
}

//------------------------------------------------------------------------------
// Ray casting
//------------------------------------------------------------------------------

float shadow(in vec3 origin, in vec3 direction, in float tmin, in float tmax) {
    float hit = 1.0;

    for (float t = tmin; t < tmax; ) {
        float h = scene(origin + direction * t).x;
        if (h < 0.001) return 0.0;
        t += h;
        hit = min(hit, 10.0 * h / t);
    }

    return clamp(hit, 0.0, 1.0);
}

vec2 traceRay(in vec3 origin, in vec3 direction) {
    float tmin = 0.02;
    float tmax = 20.0;

    float material = -1.0;
    float t = tmin;

    for ( ; t < tmax; ) {
        vec2 hit = scene(origin + direction * t);
        if (hit.x < 0.002 || t > tmax) break;
        t += hit.x;
        material = hit.y;
    }

    if (t > tmax) {
        material = -1.0;
    }

    return vec2(t, material);
}

vec3 normal(in vec3 position) {
    vec3 epsilon = vec3(0.001, 0.0, 0.0);
    vec3 n = vec3(
          scene(position + epsilon.xyy).x - scene(position - epsilon.xyy).x,
          scene(position + epsilon.yxy).x - scene(position - epsilon.yxy).x,
          scene(position + epsilon.yyx).x - scene(position - epsilon.yyx).x);
    return normalize(n);
}

//------------------------------------------------------------------------------
// BRDF
//------------------------------------------------------------------------------

float pow5(float x) {
    float x2 = x * x;
    return x2 * x2 * x;
}

float D_GGX(float linearRoughness, float NoH, const vec3 h) {
    // Walter et al. 2007, "Microfacet Models for Refraction through Rough Surfaces"
    float oneMinusNoHSquared = 1.0 - NoH * NoH;
    float a = NoH * linearRoughness;
    float k = linearRoughness / (oneMinusNoHSquared + a * a);
    float d = k * k * (1.0 / PI);
    return d;
}

float V_SmithGGXCorrelated(float linearRoughness, float NoV, float NoL) {
    // Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs"
    float a2 = linearRoughness * linearRoughness;
    float GGXV = NoL * sqrt((NoV - a2 * NoV) * NoV + a2);
    float GGXL = NoV * sqrt((NoL - a2 * NoL) * NoL + a2);
    return 0.5 / (GGXV + GGXL);
}

vec3 F_Schlick(const vec3 f0, float VoH) {
    // Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering"
    return f0 + (vec3(1.0) - f0) * pow5(1.0 - VoH);
}

float F_Schlick(float f0, float f90, float VoH) {
    return f0 + (f90 - f0) * pow5(1.0 - VoH);
}

float Fd_Burley(float linearRoughness, float NoV, float NoL, float LoH) {
    // Burley 2012, "Physically-Based Shading at Disney"
    float f90 = 0.5 + 2.0 * linearRoughness * LoH * LoH;
    float lightScatter = F_Schlick(1.0, f90, NoL);
    float viewScatter  = F_Schlick(1.0, f90, NoV);
    return lightScatter * viewScatter * (1.0 / PI);
}

float Fd_Lambert() {
    return 1.0 / PI;
}

//------------------------------------------------------------------------------
// Indirect lighting
//------------------------------------------------------------------------------

vec3 Irradiance_SphericalHarmonics(const vec3 n) {
    return max(
          SPHERICAL_HARMONICS[0]
        + SPHERICAL_HARMONICS[1] * (n.y)
        + SPHERICAL_HARMONICS[2] * (n.z)
        + SPHERICAL_HARMONICS[3] * (n.x)
        , 0.0);
}

vec2 PrefilteredDFG_Karis(float roughness, float NoV) {
    // Karis 2014, "Physically Based Material on Mobile"
    const vec4 c0 = vec4(-1.0, -0.0275, -0.572,  0.022);
    const vec4 c1 = vec4( 1.0,  0.0425,  1.040, -0.040);

    vec4 r = roughness * c0 + c1;
    float a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;

    return vec2(-1.04, 1.04) * a004 + r.zw;
}

//------------------------------------------------------------------------------
// Tone mapping and transfer functions
//------------------------------------------------------------------------------

vec3 Tonemap_ACES(const vec3 x) {
    // Narkowicz 2015, "ACES Filmic Tone Mapping Curve"
    const float a = 2.51;
    const float b = 0.03;
    const float c = 2.43;
    const float d = 0.59;
    const float e = 0.14;
    return (x * (a * x + b)) / (x * (c * x + d) + e);
}

vec3 OECF_sRGBFast(const vec3 linear) {
    return pow(linear, vec3(1.0 / 2.2));
}

//------------------------------------------------------------------------------
// Rendering
//------------------------------------------------------------------------------

vec3 render(in vec3 origin, in vec3 direction, out float distance) {
    // Sky gradient
    vec3 color = vec3(0.65, 0.85, 1.0) + direction.y * 0.72;

    // (distance, material)
    vec2 hit = traceRay(origin, direction);
    distance = hit.x;
    float material = hit.y;

    // We've hit something in the scene
    if (material > 0.0) {
        vec3 position = origin + distance * direction;

        vec3 v = normalize(-direction);
        vec3 n = normal(position);
        vec3 l = normalize(vec3(0.6, 0.7, -0.7));
        vec3 h = normalize(v + l);
        vec3 r = normalize(reflect(direction, n));

        float NoV = abs(dot(n, v)) + 1e-5;
        float NoL = saturate(dot(n, l));
        float NoH = saturate(dot(n, h));
        float LoH = saturate(dot(l, h));

        vec3 baseColor = vec3(0.0);
        float roughness = 0.0;
        float metallic = 0.0;

        float intensity = 2.0;
        float indirectIntensity = 0.64;

        if (material < 4.0)  {
            // Checkerboard floor
            float f = mod(floor(6.0 * position.z) + floor(6.0 * position.x), 2.0);
            baseColor = 0.4 + f * vec3(0.6);
            roughness = 0.1;
        } else if (material < 16.0) {
            // Metallic objects
            baseColor = vec3(0.3, 0.0, 0.0);
            roughness = 0.2;
        }

        float linearRoughness = roughness * roughness;
        vec3 diffuseColor = (1.0 - metallic) * baseColor.rgb;
        vec3 f0 = 0.04 * (1.0 - metallic) + baseColor.rgb * metallic;

        float attenuation = shadow(position, l, 0.02, 2.5);

        // specular BRDF
        float D = D_GGX(linearRoughness, NoH, h);
        float V = V_SmithGGXCorrelated(linearRoughness, NoV, NoL);
        vec3  F = F_Schlick(f0, LoH);
        vec3 Fr = (D * V) * F;

        // diffuse BRDF
        vec3 Fd = diffuseColor * Fd_Burley(linearRoughness, NoV, NoL, LoH);

        color = Fd + Fr;
        color *= (intensity * attenuation * NoL) * vec3(0.98, 0.92, 0.89);

        // diffuse indirect
        vec3 indirectDiffuse = Irradiance_SphericalHarmonics(n) * Fd_Lambert();

        vec2 indirectHit = traceRay(position, r);
        vec3 indirectSpecular = vec3(0.65, 0.85, 1.0) + r.y * 0.72;
        if (indirectHit.y > 0.0) {
            if (indirectHit.y < 4.0)  {
                vec3 indirectPosition = position + indirectHit.x * r;
                // Checkerboard floor
                float f = mod(floor(6.0 * indirectPosition.z) + floor(6.0 * indirectPosition.x), 2.0);
                indirectSpecular = 0.4 + f * vec3(0.6);
            } else if (indirectHit.y < 16.0) {
                // Metallic objects
                indirectSpecular = vec3(0.3, 0.0, 0.0);
            }
        }

        // indirect contribution
        vec2 dfg = PrefilteredDFG_Karis(roughness, NoV);
        vec3 specularColor = f0 * dfg.x + dfg.y;
        vec3 ibl = diffuseColor * indirectDiffuse + indirectSpecular * specularColor;

        color += ibl * indirectIntensity;
    }

    return color;
}

//------------------------------------------------------------------------------
// Setup and execution
//------------------------------------------------------------------------------

mat3 setCamera(in vec3 origin, in vec3 target, float rotation) {
    vec3 forward = normalize(target - origin);
    vec3 orientation = vec3(sin(rotation), cos(rotation), 0.0);
    vec3 left = normalize(cross(forward, orientation));
    vec3 up = normalize(cross(left, forward));
    return mat3(left, up, forward);
}

void main() {
    // Normalized coordinates
    vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
    // Aspect ratio
    p.x *= resolution.x / resolution.y;

    // Camera position and "look at"
    vec3 origin = vec3(0.0, 1.0, 0.0);
    vec3 target = vec3(0.0);

    origin.x += 2.0 * cos(time * 0.2);
    origin.z += 2.0 * sin(time * 0.2);

    mat3 toWorld = setCamera(origin, target, 0.0);
    vec3 direction = toWorld * normalize(vec3(p.xy, 2.0));

    // Render scene
    float distance;
    vec3 color = render(origin, direction, distance);

    // Tone mapping
    color = Tonemap_ACES(color);

    // Exponential distance fog
    color = mix(color, 0.8 * vec3(0.7, 0.8, 1.0), 1.0 - exp2(-0.011 * distance * distance));

    // Gamma compression
    color = OECF_sRGBFast(color);

    fragColor = vec4(color, 1.0);
}
)SHADER__";

static const android::vec3 SPHERICAL_HARMONICS[4] =
        {{0.754554516862612, 0.748542953903366, 0.790921515418539},
         {-0.083856548007422, 0.092533500963210, 0.322764661032516},
         {0.308152705331738, 0.366796330467391, 0.466698181299906},
         {-0.188884931542396, -0.277402551592231, -0.377844212327557}};

static const android::vec4 TRIANGLE[3] = {{-1.0f, -1.0f, 1.0f, 1.0f},
                                          {3.0f, -1.0f, 1.0f, 1.0f},
                                          {-1.0f, 3.0f, 1.0f, 1.0f}};
