   return (rParallel * rParallel + rPerpendicuar * rPerpendicuar) / 2.0;
 }
 
+bool Transmit(vec3 wm, vec3 wi, float n, out vec3 wo) {
+  float c = dot(wi, wm);
+  if (c < 0.0) {
+    c = -c;
+    wm = -wm;
+  }
+
+  float root = 1.0f - n * n * (1.0f - c * c);
+  if (root <= 0.0)
+    return false;
+
+  wo = (n * c - sqrt(root)) * wm - n * wi;
+  return true;
+}
 vec3 calcTransmission(vec3 c, float metallic, vec3 N, vec3 H, float roughness, vec3 V, vec3 L, float transmission) {
     float absDotNL = abs(dot(N, L));
     float absDotNV = abs(dot(N, V));

const float specularPower = 32.0;
const float gamma = 2.2;

vec2 getUV(int index) {
    if (index == 1) {
        return outUV;

    float DT = DistributionGGX(N, H, roughness);
    float GT = GeometrySmith(N, V, L, roughness);  

    vec2 Xi = Hammersley(1u, 2u);
    vec3 VH  = ImportanceSampleGGX(Xi, -V, roughness);
    vec3 RV;
    Transmit(VH, -V, 1.0, RV);
    vec4 refractS = projection * view * vec4(outPosition + refract(-V, VH, 1.0), 1.0);
    refractS.xy = refractS.xy / refractS.w;
    refractS.xy = refractS.xy * 0.5 + 0.5;
    vec3 baseColor = texture(colorTexture, refractS.xy).xyz;

    float coef = (absDotHL * absDotHV) / (absDotNL * absDotNV);
    return transmission * baseColor;
}

float sheenDistribution(float sheenRoughness, vec3 N, vec3 H) {
