#version 300 es precision highp float; #ifndef NORMAL_MAP #define NORMAL_MAP 0 #endif #ifndef PARALLAX #define PARALLAX 0 #endif in vec3 position; in vec2 textcoord; in vec3 normal; in vec3 tangent; in vec3 bitangent; uniform mat4 world; uniform mat4 view; uniform mat4 viewProjection; uniform mat4 worldInverseTranspose; uniform float normals; out vec2 v_textcoord; out vec4 v_normal; out vec4 v_tangent; out vec4 v_binormal; out vec2 v_offset; out vec4 v_worldposition; out vec4 v_position; out float v_depth; out vec3 v_view; //mat3 transpose(mat3 matrix) { // // return mat3( matrix[0].x, matrix[1].x, matrix[2].x, // matrix[0].y, matrix[1].y, matrix[2].y, // matrix[0].z, matrix[1].z, matrix[2].z ); // //} void main(void) { v_textcoord = textcoord; v_normal = normalize(worldInverseTranspose * vec4(normal, 0.0)); #if NORMAL_MAP == 1 v_tangent = normalize(worldInverseTranspose * vec4(tangent, 0.0) ); v_binormal = normalize(worldInverseTranspose * vec4(bitangent, 0.0) ); //v_binormal = vec4(cross(v_normal.xyz, v_tangent.xyz), 0.0); #endif #if PARALLAX == 1 const float height_map_range = 0.32; vec3 vs_normal = ( view * v_normal ).xyz; vec3 vs_tangent = ( view * v_tangent ).xyz; vec3 vs_bitangent = ( view * vec4(v_binormal, 0.0) ).xyz; //vec3 vs_bitangent = bitangent; vec4 a = view * vec4(position, 1.0); v_view = a.xyz; mat3 tbn = mat3( normalize(vs_tangent), normalize(vs_bitangent), normalize(vs_normal) ); mat3 vs_to_ts = transpose( tbn ); vec3 ts_view = vs_to_ts * v_view; v_offset = (ts_view.xy / ts_view.z) * height_map_range; #endif v_worldposition = world * vec4(position, 1.0); v_position = viewProjection * vec4(position, 1.0); v_depth = v_position.z; gl_Position = v_position; } // #keplerEngine - Split #version 300 es precision highp float; #define PI 3.14159265358979323846 layout(location = 0) out vec4 deferred_diffuse_roughness; layout(location = 1) out vec4 deferred_normal_depth; layout(location = 2) out vec4 deferred_position_material_ID; layout(location = 3) out vec4 tangent; //layout(location = 3) out vec4 deferred_material_1; in vec2 v_textcoord; in vec4 v_normal; in vec4 v_tangent; in vec4 v_binormal; in vec4 v_worldposition; in vec4 v_position; in float v_depth; in vec2 v_offset; in vec3 v_view; const float gamma = 2.2; //pbr uniform samplerCube reflectionSampler; uniform vec3 cameraPosition; uniform vec3 lightGeometry; uniform float clearCoat; uniform vec3 clearCoatColor; uniform float clearCoatThickness; uniform float clearCoatRoughness; uniform float clearCoatIOR; uniform float anisotropy; uniform vec3 lightDirection; uniform vec3 lightColor; uniform float lightIntensity; uniform float environmentLuminance; uniform float v_metallic; uniform float v_reflectance; uniform float lightType; uniform vec3 lightPosition; #define ANISOTROPY 0 #define USE_IES_PROFILE 0 #define TRANSPARENT_MATERIAL 0 #define TRANSLUCENT_MATERIAL 0 #define CUBEMAP_EDGE_FIXUP 0 struct PixelParams { vec3 diffuseColor; vec3 f0; float roughness; float clearCoatRoughness; float ao; float eta; float refracted_NoV; }; const float PackUpscale = 256. / 255.; // fraction -> 0..1 (including 1) const float UnpackDownscale = 255. / 256.; // 0..1 -> fraction (excluding 1) const vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. ); const vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. ); const float ShiftRight8 = 1. / 256.; vec4 packDepthToRGBA( const in float v ) { vec4 r = vec4( fract( v * PackFactors ), v ); r.yzw -= r.xyz * ShiftRight8; // tidy overflow return r * PackUpscale; } float unpackRGBAToDepth( const in vec4 v ) { return dot( v, UnpackFactors ); } float D_GGX(float NoH, float a) { float a2 = a * a; float f = (NoH * a2 - NoH) * NoH + 1.0; return a2 / (PI * f * f); } float D_GGX_Anisotropy(float NoH, vec3 h, vec3 x, vec3 y, float ax, float ay) { float XoH = dot(x, h); float YoH = dot(y, h); float d = XoH * XoH * (ax * ax) + YoH * YoH * (ay * ay) + NoH * NoH; return (ax * ay) / (PI * d * d); } vec3 F_Schlick(float VoH, vec3 f0, float f90) { return f0 + (vec3(f90) - f0) * pow(1.0 - VoH, 5.0); } // Smith-GGX correlated for microfacets height float V_SmithGGXCorrelated(float NoV, float NoL, float a) { float a2 = a * a; float GGXL = NoV * sqrt((-NoL * a2 + NoL) * NoL + a2); float GGXV = NoL * sqrt((-NoV * a2 + NoV) * NoV + a2); // approximation // float GGXL = NoV * (NoL * (1.0 - a) + a); // float GGXV = NoL * (NoV * (1.0 - a) + a); return 0.5 / (GGXV + GGXL); } float Fd_Lambert() { return 1.0 / PI; } float F_Schlick_Scalar(float VoH, float f0, float f90) { return f0 + (f90 - f0) * pow(1.0 - VoH, 5.0); } float square(float v) { return v * v; } vec3 irradianceSH(vec3 n) { //vec3 sphericalHarmonics[8] = // return // sphericalHarmonics[0] // + sphericalHarmonics[1] * (n.y) // + sphericalHarmonics[2] * (n.z) // + sphericalHarmonics[3] * (n.x) // + sphericalHarmonics[4] * (n.y * n.x) // + sphericalHarmonics[5] * (n.y * n.z) // + sphericalHarmonics[6] * (3.0 * n.z * n.z - 1.0) /// + sphericalHarmonics[7] * (n.z * n.x) // + sphericalHarmonics[8] * (n.x * n.x - n.y * n.y); return vec3(0.754553530212464, 0.748541695286661, 0.790922541330174) + vec3(-0.083855089181764, 0.092536341322488, 0.322767327275582) * (n.y) + vec3(0.308154551673257, 0.366799355358085, 0.466705760819624) * (n.z) + vec3(-0.188887618191928, -0.277403749518126, -0.377844811540716) * (n.x) + vec3(-0.252782448589491, -0.316051613736677, -0.396141020484574) * (n.y * n.x) + vec3(0.071362454444021, 0.159789075773366, 0.29059362717571) * (n.y * n.z) + vec3(-0.031040420617065, -0.031141089772695, -0.031044001883204) * (3.0 * n.z * n.z - 1.0) + vec3(-0.161001896026477, -0.203649521035777, -0.246641086569566) * (n.z * n.x) + vec3(0.045710934605387, 0.048121779682969, 0.046326375668417) * (n.x * n.x - n.y * n.y); } vec2 prefilteredDFGKaris(float NoV, float roughness) { // see https://www.unrealengine.com/blog/physically-based-shading-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; } float sRGBtoLinear(float c) { return (c <= 0.04045) ? c / 12.92 : pow((c + 0.055) / 1.055, 2.4); } vec3 sRGBtoLinear(vec3 c) { return vec3(sRGBtoLinear(c.r), sRGBtoLinear(c.g), sRGBtoLinear(c.b)); } vec3 decodeEnvironmentMap(vec4 c) { return c.rgb; return sRGBtoLinear(c.rgb); //;sRGBtoLinear(c.rgb) ; } //#if TEXTURED_MATERIAL == 1 //float getMaterialAmbientOcclusion() { // return texture(aoMap, outUV).r; //} //#else float getMaterialAmbientOcclusion() { return 1.0; } //#endif float getSquareFalloffAttenuation(float distanceSquare) { float factor = distanceSquare * lightGeometry.x; float smoothFactor = max(1.0 - factor * factor, 0.0); // we would normally divide by the square distance here // but we do it at the call site return smoothFactor * smoothFactor; } //#if USE_IES_PROFILE == 1 //float getPhotometricAttenuation(vec3 lightToPos, vec3 lightDir) { // float cosTheta = dot(lightToPos, lightDir); // float angle = acos(cosTheta) * (1.0 / PI); // return textureLodEXT(reflectionSampler, vec2(angle, 0.0), 0.0).r; //} //#else float getPhotometricAttenuation(vec3 lightToPos, vec3 lightDir) { return 1.0; } //#endif float getAngleAttenuation(vec3 l, vec3 lightDir) { float cd = dot(lightDir, l); float attenuation = clamp(cd * lightGeometry.y + lightGeometry.z, 0.0, 1.0); return attenuation * attenuation; } vec3 beerLambert(float NoV, float NoL, vec3 alpha, float d) { return exp(alpha * -(d * ((NoL + NoV) / max(NoL * NoV, 1e-3)))); } vec3 evaluateLight(vec3 n, vec3 v, PixelParams params, vec3 outWorldPosition, vec3 outWorldTangent, float shadow) { vec3 l; float NoL; float energy; float attenuation; vec3 lightDir = normalize(lightDirection); float linearRoughness = params.roughness * params.roughness; vec3 r = reflect(-v, n); if (lightType == 1.0) { l = -lightDir; // Disc area light vec3 sunDir = -lightDir; float e = sin(radians(0.53)); float d = cos(radians(0.53)); float DoR = dot(sunDir, r); vec3 s = r - DoR * sunDir; l = DoR < d ? normalize(d * sunDir + normalize(s) * e) : r; NoL = dot(n, l); energy = 1.0; attenuation = 1.0; } else if (lightType == 0.0) { vec3 posToLight = lightPosition - outWorldPosition; float distanceSquare = dot(posToLight, posToLight); l = normalize(posToLight); NoL = dot(n, l); energy = 50.0; attenuation = getSquareFalloffAttenuation(distanceSquare); attenuation *= 1.0 / max(distanceSquare, 1e-4); attenuation *= getPhotometricAttenuation(-l, lightDir); // if (lightGeometry.w >= 1.0) { // attenuation *= getAngleAttenuation(l, -lightDir); // } } vec3 h = normalize(v + l); NoL = clamp(NoL, 0.0, 1.0); float NoV = abs(dot(n, v)) + 1e-5; float NoH = clamp(dot(n, h), 0.0, 1.0); float LoH = clamp(dot(l, h), 0.0, 1.0); // specular BRDF #if ANISOTROPY == 1 vec3 t = normalize(v_tangent.xyz); vec3 b = normalize(cross(t, n)); float aspect = inversesqrt(1.0 - anisotropy * 0.9); float ax = 1.0 / (linearRoughness * aspect); float ay = aspect / linearRoughness; float D = D_GGX_Anisotropy(NoH, h, t, b, ax, ay); #else float D = D_GGX(NoH, linearRoughness); #endif vec3 F = F_Schlick(LoH, params.f0, clamp(dot(params.f0, vec3(50.0 * 0.33)), 0.0, 1.0)); float V = V_SmithGGXCorrelated(NoV, NoL, linearRoughness); vec3 Fr = (D * V) * F; // diffuse BRDF vec3 Fd = params.diffuseColor * Fd_Lambert();// * 3.6 // clear coat float linearClearCoatRoughness = params.clearCoatRoughness * params.clearCoatRoughness; float Dcc = D_GGX(NoH, linearClearCoatRoughness); float Fcc = F_Schlick_Scalar(LoH, 0.04, 1.0) * clearCoat; float Vcc = V_SmithGGXCorrelated(NoV, NoL, linearClearCoatRoughness); float FrCC = Dcc * Vcc * Fcc; vec3 refracted_l = -refract(l, n, params.eta); float refracted_NoL = clamp(dot(n, refracted_l), 0.0, 1.0); vec3 clearCoatAbsorption = mix(vec3(1.0), beerLambert(params.refracted_NoV, refracted_NoL, clearCoatColor, clearCoatThickness), clearCoat); // direct contribution vec3 color = (attenuation * NoL) * lightColor * lightIntensity * energy * ((Fd + Fr) * (1.0 - Fcc) * clearCoatAbsorption + FrCC); #if TRANSLUCENT_MATERIAL == 1 vec3 tL = l + n * translucencyDistortion; float tD = exp2(clamp(dot(v, -tL), 0.0, 1.0) * translucencyPower - translucencyPower) * translucencyScale; vec3 tT = attenuation * lightIntensity * (tD + translucencyAmbient) * texture(translucencyThicknessMap, outUV).r; color.rgb += Fd * lightColor * tT; #endif // micro-shadowing float aperture = 2.0 * params.ao * params.ao * shadow; float microShadow = clamp(abs(dot(l, n)) + aperture - 1.0, 0.0, 1.0); color.rgb *= microShadow; return color; } vec3 fixCubemapLookup(vec3 v, float lod) { vec3 r = abs(v); float M = max(max(v.x, v.y), v.z); float scale = 1.0 - exp2(lod) * (1.0 / 256.0); if (v.x != M) v.x *= scale; if (v.y != M) v.y *= scale; if (v.z != M) v.z *= scale; return v; } vec3 evaluateSpecularIBL(vec3 r, float roughness) { float lod = 5.0 * roughness; r = fixCubemapLookup(r, lod); return decodeEnvironmentMap( texture(reflectionSampler, r, lod) ); //, lod } float computeSpecularAO(float NoV, float ao, float roughness) { return clamp(pow(NoV + ao, exp2(-16.0 * roughness - 1.0)) - 1.0 + ao, 0.0, 1.0); } vec3 getSpecularDominantDirection(vec3 n, vec3 r, float roughness) { float s = 1.0 - roughness; return mix(n, r, s * (sqrt(s) + roughness)); } vec3 evaluateIBL(vec3 n, vec3 v, PixelParams params) { float NoV = max(dot(n, v), 0.0); #if ANISOTROPY == 1 vec3 t = normalize(v_tangent.xyz); vec3 b = normalize(cross(t, n)); vec3 anisotropicTangent = cross(-v, b); vec3 anisotropicNormal = cross(anisotropicTangent, b); vec3 bentNormal = normalize(mix(n, anisotropicNormal, anisotropy)); vec3 r = reflect(v, bentNormal); #else vec3 r = reflect(-v, n);// vec3 r = reflect(-v, n); r = getSpecularDominantDirection(n, r, params.roughness * params.roughness); #endif float NoR = max(dot(r, n), 0.0); // specular indirect vec3 indirectSpecular = evaluateSpecularIBL(reflect(v, n), params.roughness); // horizon occlusion, can be removed for performance float horizon = min(1.0 + NoR, 1.0); indirectSpecular *= horizon * horizon; vec2 env = prefilteredDFGKaris(NoV, params.roughness); // we should multiply env.y by f90 for more accurate results vec3 specularColor = params.f0 * env.x + env.y * (1.0 - clearCoat) * clamp(dot(params.f0, vec3(50.0 * 0.33)), 0.0, 1.0); // diffuse indirect vec3 indirectDiffuse = max(irradianceSH(n), 0.0) * Fd_Lambert(); // ambient occlusion float aoFade = clamp(dot(normalize(n), v), 0.0, 1.0); float ao = mix(1.0, params.ao, aoFade); indirectDiffuse *= ao; //indirectDiffuse *= 4.0; // TODO: Not really useful without SSAO/HBAO/etc. indirectSpecular *= computeSpecularAO(NoV, ao, params.roughness); // clear coat float Fcc = F_Schlick_Scalar(NoV, 0.04, 1.0) * 0.2; #if ANISOTROPY == 1 // We used the bent normal for the base layer r = reflect(-v, n); #endif vec3 indirectClearCoatSpecular = evaluateSpecularIBL(reflect(v, n), params.clearCoatRoughness); vec3 clearCoatAbsorption = mix(vec3(1.0), beerLambert(params.refracted_NoV, params.refracted_NoV, clearCoatColor, clearCoatThickness), clearCoat); // indirect contribution vec3 color = (params.diffuseColor * indirectDiffuse + indirectSpecular * specularColor)//kaj params.diffuseColor * indirectDiffuse * (1.0 - Fcc) * clearCoatAbsorption + indirectClearCoatSpecular * Fcc; #if TRANSLUCENT_MATERIAL == 1 indirectDiffuse = max(irradianceSH(-v), 0.0) * Fd_Lambert(); vec3 tL = -v + n * translucencyDistortion; float tD = pow(clamp(dot(v, -tL), 0.0, 1.0), translucencyPower) * translucencyScale; vec3 tT = (tD + translucencyAmbient) * texture(translucencyThicknessMap, outUV).r; color.rgb += params.diffuseColor * indirectDiffuse * tT; #endif return color; } vec3 getNormal(vec3 n) { return normalize(n); } vec4 surfaceShading(vec3 baseColor, vec3 outWorldNormal, vec3 outWorldPosition, float metallic, float roughness, float reflectance, float ambientOcclusion, vec3 tangent, float shadow) { vec3 diffuseColor = (1.0 - metallic) * baseColor.rgb; // Geometric AA vec3 wn = normalize(outWorldNormal); vec3 ndFdx = dFdx(wn); vec3 ndFdy = dFdy(wn); float geometricRoughness = pow(max(dot(ndFdx, ndFdx), dot(ndFdy, ndFdy)), 0.333); float effectiveRoughness = max(roughness, geometricRoughness); // Fresnel specular reflectance at normal incidence vec3 f0 = 0.16 * reflectance * reflectance * (1.0 - metallic) + baseColor.rgb * metallic; float alpha = 1.0; #if TRANSPARENT_MATERIAL == 1 // float reflectivity = max(max(f0.r, f0.g), f0.b); // alpha = reflectivity + baseColor.a * (1.0 - reflectivity); // diffuseColor *= baseColor.a; #endif vec3 v = normalize(cameraPosition - outWorldPosition); vec3 n = getNormal(outWorldNormal); PixelParams params; params.diffuseColor = diffuseColor; params.f0 = f0; params.roughness = effectiveRoughness; params.clearCoatRoughness = max(mix(0.089, 0.6, clearCoatRoughness), geometricRoughness); //max(mix(0.089, 0.6, clearCoatRoughness), geometricRoughness); params.ao = ambientOcclusion; params.eta = 1.0 / clearCoatIOR; vec3 refracted_v = -refract(v, n, params.eta); params.refracted_NoV = clamp(dot(n, refracted_v), 0.0, 1.0); // indirect lighting vec3 color = evaluateIBL(n, v, params); color *= environmentLuminance; // direct lighting color += evaluateLight(n, v, params, outWorldPosition, tangent, shadow); return vec4(color, alpha); } #ifndef NORMAL_MAP #define NORMAL_MAP 0 #endif #ifndef TEXTURE #define TEXTURE 0 #endif #ifndef ROUGHNESS_MAP #define ROUGHNESS_MAP 0 #endif #ifndef PARALLAX #define PARALLAX 0 #endif precision highp float; uniform sampler2D diffuseSampler; uniform sampler2D normalSampler; uniform sampler2D roughnessSampler; uniform sampler2D heightSampler; uniform sampler2D shadowNoiseSampler; uniform sampler2D shadowDepthSampler; uniform float normals; uniform float far; uniform float roughness; uniform float metallic; uniform float alpha; uniform float shadingModelID; uniform vec3 diffuseColor; uniform float attenuation; uniform float SourceRadius; uniform float SourceLength; uniform float specular; uniform float mode; uniform float uvMultiplier; uniform float render_type; uniform float shadowBias; uniform mat4 lightViewProjection; uniform vec2 screenSize; //reflect(v, n) vec3 sampleReflection( vec3 r ) { return texture(reflectionSampler, r).xyz; } vec3 lumaBasedReinhardToneMapping(vec3 color) { float gamma = 2.2; float luma = dot(color, vec3(0.2126, 0.7152, 0.0722)); float toneMappedLuma = luma / (1.0 + luma); color *= toneMappedLuma / luma; color = pow(color, vec3(1. / gamma)); return color; } vec3 HDR_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 tonemap(const vec3 x) { return HDR_ACES(x); } float linearToSRGB(float c) { return (c <= 0.0031308) ? c * 12.92 : (pow(abs(c), 1.0 / 2.4) * 1.055) - 0.055; } vec3 linearToSRGB(vec3 c) { return vec3(linearToSRGB(c.r), linearToSRGB(c.g), linearToSRGB(c.b)); } float DecodeFloatRGBA( vec4 rgba ) { return (rgba).x; //return dot( rgba, vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 160581375.0) ); } float shadow_sample(sampler2D depthMap, vec2 coord) { return texture(depthMap, coord).x;//DecodeFloatRGBA() ; } vec2 DoubleSampleRotated(sampler2D depthMap, vec4 p, vec4 rotMatr, vec4 kernel) { vec4 rotatedOff; rotatedOff = rotMatr.xyzw * kernel.xxww + rotMatr.zwxy * kernel.yyzz; vec4 fetchPos = p.xyxy + rotatedOff;// + rotatedOff vec2 result; result.x = shadow_sample(depthMap, fetchPos.xy); result.y = shadow_sample(depthMap, fetchPos.zw); return result; } float PCF(sampler2D depthMap, vec4 p, vec2 randDirTC, float depth) { vec2 kernelRadius = vec2(4.0); vec4 irreg_kernel_2d[8]; irreg_kernel_2d[0] = vec4(-0.556641,-0.037109,-0.654297, 0.111328); irreg_kernel_2d[1] = vec4(0.173828,0.111328,0.064453, -0.359375); irreg_kernel_2d[2] = vec4(0.001953,0.082031,-0.060547, 0.078125); irreg_kernel_2d[3] = vec4(0.220703,-0.359375,-0.062500, 0.001953); irreg_kernel_2d[4] = vec4(0.242188,0.126953,-0.250000, -0.140625); irreg_kernel_2d[5] = vec4(0.070313,-0.025391,0.148438, 0.082031); irreg_kernel_2d[6] = vec4(-0.078125,0.013672,-0.314453, 0.013672); irreg_kernel_2d[7] = vec4(0.117188,-0.140625,-0.199219, 0.117188); vec2 vInvShadowMapWH = vec2(1.0 / 2048.0); const int kernelSize = 8; mediump float P_Z = depth; // p.z; vec4 p0 = vec4(p.xyz, 1.0); mediump vec2 rotScale = vec2(kernelRadius.y * 2.0); float shadowTest = 0.0; #define KERNEL_STEP_SIZE 2 vec2 rotSample = 2.0 * texture(shadowDepthSampler, randDirTC.xy).xy - 1.0; rotSample.xy = normalize(rotSample.xy); rotSample.xy *= (kernelRadius.xy * vInvShadowMapWH.xy); vec4 rot = vec4(rotSample.x, -rotSample.y, rotSample.y, rotSample.x); const int kernelOffset = 0; for(int i=kernelOffset; i shadowDepth) { sum += 1.0; } else { sum += 0.0; } // } return sum; } float linestep(float min, float max, float value) { return clamp((value - min) / (max - min), 0., 1.); } float reduceBleeding(float p_max, float amount) { return linestep(amount, 1.0, p_max); } float ChebyshevUpperBound(vec2 moments, float distance) { if (distance <= moments.x) return 1.0; float g_minVariance = .00007; float variance = moments.y - (moments.x*moments.x); variance = max(variance,g_minVariance); float d = distance - moments.x; float p_max = variance / (variance + d*d); return reduceBleeding(p_max, .725); } float calculateShadowOcclusion( vec3 worldPosition, vec2 uv ) { vec4 projCoords = lightViewProjection * vec4(worldPosition, 1.0) ; float shadowDepth = length( lightPosition - worldPosition ); projCoords.xy /= projCoords.w; projCoords = 0.49 * projCoords + 0.5; vec4 moments = texture( shadowDepthSampler, projCoords.xy ); mediump vec2 randomSample = texture(shadowNoiseSampler, vec2(1024.) * uv / 64.0).xy * 2.0 - 1.0; float outFrustum = 0.0; if(projCoords.x < 0.0 || projCoords.x > 1.0) { return 1.0; } if(projCoords.y < 0.0 || projCoords.y > 1.0) { return 1.0; } if(projCoords.z < 1.0) { return 1.0; } //return ChebyshevUpperBound(moments.xy, shadowDepth); //if(uv.x < .5) //return DecodeFloatRGBA( texture(shadowDepthSampler, projCoords.xy ) ) / 10.0; //else //return shadowDepth; //return moments.x; //return projCoords.x; //return texture( shadowDepthSampler, uv ).x;//projCoords.xy //return poissonPCFmultitap(projCoords, shadowDepth, uv); //return PCF(sampler2D depthMap, vec4 p, vec2 randDirTC); return PCF( shadowDepthSampler, projCoords, randomSample, shadowDepth ); //return 1.0 - ChebyshevUpperBound(moments.xy, shadowDepth); // return smoothShadow(projCoords, shadowDepth,uv); } void main() { vec2 textureCoordinate = v_textcoord; vec3 normal; #if NORMAL_MAP == 1 vec4 normalMap = texture(normalSampler, textureCoordinate * uvMultiplier) * 2.0 - 1.0; normal = normalize((v_tangent.xyz * normalMap.x) + (v_binormal.xyz * normalMap.y) + (v_normal.xyz * normalMap.z)); mat3 tangentToWorld = transpose(mat3( v_tangent.xyz , v_binormal.xyz , v_normal.xyz)); normal = normalMap.xyz * tangentToWorld; #else normal = v_normal.xyz; #endif #if PARALLAX == 1 const float max_samples = 30.0; const float min_samples = 8.0; vec3 view = normalize(v_view); float num_steps = mix(max_samples, min_samples, dot(view, normal)); float current_height = 0.0; float step_size = 1.0 / float(num_steps); float prev_height = 1.0; float step_index = 0.0; vec2 tex_offset_per_step = step_size * v_offset; vec2 tex_current_offset = v_textcoord; float current_bound = 1.0; float parallax_amount = 0.0; vec2 pt1 = vec2(0.0); vec2 pt2 = vec2(0.0); vec2 tex_offset = vec2(0.0); for(int x = 0; x < 30; x++) { if(step_index < num_steps) { tex_current_offset -= tex_offset_per_step; current_height = texture(heightSampler, tex_current_offset).r; //, dx, dy current_bound -= step_size; if(current_height > current_bound) { pt1 = vec2(current_bound, current_height); pt2 = vec2(current_bound + step_size, prev_height); tex_offset = tex_current_offset - tex_offset_per_step; step_index = num_steps + 1.0; } else { step_index++; prev_height = current_height; } } } float delta1 = pt1.x - pt1.y; float delta2 = pt2.x - pt2.y; float denominator = delta2 - delta1; if(denominator == 0.0) { parallax_amount = 0.0; } else { parallax_amount = (pt1.x * delta2 - pt2.x * delta1) / denominator; } vec2 parallax_offset = v_offset * (1.0 - parallax_amount); textureCoordinate.xy -= parallax_offset; #endif float gamma = 1.4; vec3 baseColor; vec4 diffuseMap; #if TEXTURE == 1 diffuseMap = ( texture(diffuseSampler, textureCoordinate * uvMultiplier));//toLinear baseColor = diffuseMap.rgb; #else baseColor = diffuseColor; #endif float f_roughness = roughness; #if ROUGHNESS_MAP == 1 f_roughness = texture(roughnessSampler, textureCoordinate).x; #endif vec3 diffuse = baseColor ; // float opacity = 1.0; float metallic = v_metallic / 2.0; float reflectance = v_reflectance / 2.0; vec3 viewDir = (cameraPosition - v_worldposition.xyz); vec3 reflectionVector = reflect(-viewDir.xyz, normalize(normal.xyz)); vec3 reflectionSample = sampleReflection( reflectionVector ); if(render_type == 0.0) { float shadow = calculateShadowOcclusion( v_worldposition.xyz, textureCoordinate ); vec4 pbr = surfaceShading(sRGBtoLinear(diffuse), normal, v_worldposition.xyz, metallic, f_roughness, reflectance, 1.0, v_tangent.xyz, shadow); float exposure = 1.7; pbr.rgb *= exposure; deferred_diffuse_roughness = vec4(linearToSRGB(tonemap(pbr.rgb)), 1.0); if(shadingModelID == 100.0) { deferred_diffuse_roughness = vec4(reflectionSample, 1.0); } //if(textureCoordinate.x > .5) //deferred_diffuse_roughness = vec4(vec3(shadow), 1.0); } else { deferred_diffuse_roughness = vec4( (diffuse), f_roughness); // //f_roughness kaj niet vergeten!!! deferred_normal_depth = vec4(normalize(normal), v_depth); deferred_position_material_ID = vec4(v_worldposition.xyz, float( shadingModelID ) ); } }