//agf_include "main_shared_functions_fragment.glsl" //agf_include "main_vertex2fragment.glsl" #ifdef ENABLE_AGFDiffuseMap uniform sampler2D diffuse_texture; uniform mat4 diffuse_texture_matrix; #endif #ifdef ENABLE_AGFSpecularColorMap uniform sampler2D specular_intensity_texture; uniform mat4 specular_intensity_texture_matrix; #endif #ifdef ENABLE_AGFSpecularExponentMap uniform sampler2D specular_exponent_texture; uniform mat4 specular_exponent_texture_matrix; #endif #ifdef ENABLE_AGFNormalMap uniform sampler2D normal_map_texture; uniform mat4 normal_map_texture_matrix; #endif #ifdef ENABLE_AGFBumpMap uniform sampler2D bump_gradient_texture; uniform mat4 bump_gradient_texture_matrix; uniform vec4 bumpTextureNormalizer; #endif uniform float bumpStrength; #ifdef ENABLE_ROUGHNESS uniform sampler2D roughness_texture; uniform mat4 roughness_texture_matrix; uniform vec4 roughness; #endif #if NUMBER_OF_ACTIVE_INFINITE_LIGHTS > 0 uniform InfiniteLight infiniteLights[NUMBER_OF_ACTIVE_INFINITE_LIGHTS]; #endif #if NUMBER_OF_ACTIVE_SPOT_LIGHTS > 0 uniform SpotLight spotLights[NUMBER_OF_ACTIVE_SPOT_LIGHTS]; #endif #if NUMBER_OF_ACTIVE_POINT_LIGHTS > 0 uniform PointLight pointLights[NUMBER_OF_ACTIVE_POINT_LIGHTS]; #endif #ifdef ENABLE_IBL uniform mat4 sphericalHarmonicMatrixRed; uniform mat4 sphericalHarmonicMatrixGreen; uniform mat4 sphericalHarmonicMatrixBlue; uniform mat4 sphericalHarmonicsTransformationMatrix; #endif #ifdef ENABLE_AGFSphereEnvironmentMap uniform sampler2D environment_texture; uniform mat4 environment_texture_matrix; uniform sampler3D discreteShininess3DTex; #endif #ifdef ENABLE_AGFReflectivityMap uniform sampler2D reflectivity_texture; uniform mat4 reflectivity_texture_matrix; #endif #ifdef ENABLE_AGFSelfIlluminationMap uniform sampler2D self_illumination_texture; uniform mat4 self_illumination_texture_matrix; uniform vec4 self_illumination_texture_range; #endif #ifdef ENABLE_AGFOpacityMap uniform sampler2D object_opacity_texture; uniform mat4 object_opacity_texture_matrix; #endif uniform Material material; uniform vec4 unscaledIBLColor; uniform mat4 fmodelViewCamera; uniform mat4 iEyeToWorldMatrix; uniform mat4 iEyeToNormalizedBBOXMatrix; uniform mat4 reflectionTransformationMatrix; uniform vec4 environmentColor; uniform vec4 iGlobalAmbientColor; uniform vec4 clippingPlane; uniform vec4 extraReflectionClippingPlane; uniform vec4 refraction_flag; //First component is refraction_flag, second component is piggybacked transparency threshold uniform vec4 useVertexForBase; uniform sampler2D background_texture; uniform mat4 background_texture_matrix; uniform mat4 refractionTransformationMatrix; uniform vec4 bumpNormalPreviewFlags; //[0] - normal map strength (1/0), [1] - bump map extra strength. Used in print preview; #ifdef HAS_VOLUME_BUMP_NOISE uniform sampler3D volumeNoiseTexture; uniform vec4 volumeNoiseBumpParams; #endif uniform vec4 agf_bump_2_params; uniform vec2 agf_force_flat_shading; //First elem forces flat shading, second piggybacked flag for forcing parallel projection reflection void main() { //########################################## CLIPPING PLANES ################################################################################ float clipSign = dot(clippingPlane.xyz, vertOut_vPosition.xyz)+clippingPlane.w; if (clipSign < 0.0) discard; float extraClipSign = dot(extraReflectionClippingPlane.xyz, vertOut_vPosition.xyz)+extraReflectionClippingPlane.w; if (extraClipSign < 0.0) discard; //########################################## END OF CLIPPING PLANES ################################################################################ vec4 UV = vertOut_fTexCoord0; vec3 materialSpecularColor = material.Ks.rgb; vec3 newNormal = normalize(vertOut_vNormal); vec4 texLookup = vec4(0.0, 0.0, 0.0, 0.0); //Temporary variable, to use in all the texture Lookups //########################################## OPACITY MANAGEMENT ################################################################################ float finalOpacity = 0.0; float opacity=material.opacity; #ifdef ENABLE_AGFOpacityMap texLookup = xformTex2D(object_opacity_texture, UV, object_opacity_texture_matrix); #ifdef USE_ALPHA_FOR_OPACITY_MAP opacity = texLookup.a*material.opacity; #else vec3 materialOpacity3 = vec3(material.opacity, material.opacity, material.opacity); //Blending base opacity value with the one in the opacity map. vec3 perColorOpacity = mix(materialOpacity3, texLookup.rgb, texLookup.a); //We have got to choose _SINGLE_ opacity value for GL framebuffer //We are choosing maximum of the 3 float rg_maxopacity = max (perColorOpacity.r, perColorOpacity.g); opacity = max (rg_maxopacity, perColorOpacity.b); #endif #endif finalOpacity = opacity; if (refraction_flag[2]>0.5) { finalOpacity = material.opacity; } else { if (refraction_flag[1]>=0.0) { if (finalOpacity < refraction_flag[1]) discard; else finalOpacity = 1.0; } } if (finalOpacity == 0.0) { discard; } if (useVertexForBase[2] > 0.5) //Stochastic transparency { float heisenbergOpacity = rand(gl_FragCoord.xy+vertOut_vPosition.zz); float testOpacity = finalOpacity; if (testOpacity < 0.05) { testOpacity = 0.1*finalOpacity; } if (heisenbergOpacity > testOpacity) { discard; } finalOpacity = 1.0; } //########################################## END OF OPACITY MANAGEMENT ################################################################################ vec4 finalColor = vec4(0.0, 0.0, 0.0, 0.0); vec3 materialBaseColor = material.Kd.rgb; if (useVertexForBase[0]>0.5) { materialBaseColor = vertOut_Color.rgb; } vec3 materialDiffuseColor = materialBaseColor; #ifdef ENABLE_AGFSpecularColorMap texLookup = xformTex2D(specular_intensity_texture, UV, specular_intensity_texture_matrix); float specAlpha = texLookup.a*material.le_params[1]; materialSpecularColor = mix(material.Ks.rgb, texLookup.rgb, specAlpha); #endif #ifdef ENABLE_AGFDiffuseMap texLookup = xformTex2D(diffuse_texture, UV, diffuse_texture_matrix); materialDiffuseColor = mix(materialBaseColor, texLookup.rgb, texLookup.a); #endif if (refraction_flag[3]>0.5) { if (vertOut_Color.r > 0.0 || vertOut_Color.g > 0.0 || vertOut_Color.b > 0.0) materialDiffuseColor = vertOut_Color; //Show Repair Color } vec3 diffuseColor = materialDiffuseColor; vec3 specularColor = vec3(0, 0, 0); vec4 geomPointInEyeSpace = vec4(vertOut_vEye, 1.0); if (agf_force_flat_shading[0]>0.5) { vec3 _zero_offsetPointEyeSpace = geomPointInEyeSpace.xyz; vec3 _zero_dxPES = dFdx(_zero_offsetPointEyeSpace); vec3 _zero_dyPES = dFdy(_zero_offsetPointEyeSpace); vec3 _zero_slopeNormal = cross(_zero_dxPES, _zero_dyPES); vec3 flatNormal = normalize(_zero_slopeNormal); if (dot(flatNormal, newNormal)<0.0); flatNormal = -flatNormal; newNormal = flatNormal; } //###################################################### NORMAL MAP/BUMP MAP CALCULATION (NORMAL ALTERATION) ############################################## //Tangential basis. Needs to be there for bump maps and/or tangent-space normal maps vec3 _t = normalize(vertOut_t); vec3 _n = normalize(vertOut_n); vec3 _b = normalize(vertOut_b); #ifdef ENABLE_AGFNormalMap //We will make sure that normal mapping and bump mapping cannot be enabled simultaneously //vec4 normalMapLookup = tex2D(normal_map_texture, interpolant.fTexCoord0.xy); vec4 normalMapLookup = xformTex2D(normal_map_texture, UV, normal_map_texture_matrix); normalMapLookup.xyz = (normalMapLookup.xyz-vec3(0.49803921568, 0.49803921568, 0.49803921568))*2.00787401577; float normalMapAlpha = normalMapLookup.a*bumpNormalPreviewFlags[1]; normalMapLookup.a = 0.0; //Normal maps are now tangential vec3 tangentSpaceNormal = normalMapLookup.xyz; vec3 eyeSpaceNormal; eyeSpaceNormal.x = _t.x * tangentSpaceNormal.x + _b.x * tangentSpaceNormal.y + _n.x * tangentSpaceNormal.z; eyeSpaceNormal.y = _t.y * tangentSpaceNormal.x + _b.y * tangentSpaceNormal.y + _n.y * tangentSpaceNormal.z; eyeSpaceNormal.z = _t.z * tangentSpaceNormal.x + _b.z * tangentSpaceNormal.y + _n.z * tangentSpaceNormal.z; if (dot(tangentSpaceNormal, tangentSpaceNormal)<2.5)//White color in normal maps disables it { newNormal = mix(newNormal, normalize(eyeSpaceNormal), normalMapAlpha); } #endif vec3 bumpGradient=vec3(0.0, 0.0, 0.0); #ifdef ENABLE_AGFBumpMap //vec4 bumpLookup = tex2D(bump_gradient_texture, interpolant.fTexCoord0.xy); vec4 bumpLookup = xformTex2D(bump_gradient_texture, UV, bump_gradient_texture_matrix); #ifdef AGF_BUMP_2 float offset = 0.0; float fMaxOffset = agf_bump_2_params[0]; float fMinOffset = agf_bump_2_params[1]; offset = mix(fMinOffset, fMaxOffset, bumpLookup.x); vec3 offsetPointEyeSpace = geomPointInEyeSpace.xyz-normalize(newNormal)*offset*bumpLookup.a*bumpNormalPreviewFlags[0]; vec3 zero_offsetPointEyeSpace = geomPointInEyeSpace.xyz; vec3 dxPES = dFdx(offsetPointEyeSpace)/length(dFdx(zero_offsetPointEyeSpace)); vec3 dyPES = dFdy(offsetPointEyeSpace)/length(dFdy(zero_offsetPointEyeSpace)); vec3 slopeNormal = cross(dxPES, dyPES); vec3 zero_dxPES = dFdx(zero_offsetPointEyeSpace)/length(dFdx(zero_offsetPointEyeSpace)); vec3 zero_dyPES = dFdy(zero_offsetPointEyeSpace)/length(dFdx(zero_offsetPointEyeSpace)); vec3 zero_slopeNormal = cross(zero_dxPES, zero_dyPES); vec3 normalDelta = slopeNormal-zero_slopeNormal; newNormal = normalize(newNormal+normalDelta); bumpGradient = vec3(0.0, 0.0, 0.0); #else float x0,x1,y0,y1; x0 = xformTex2DOffset(bump_gradient_texture, UV, bump_gradient_texture_matrix, -bumpTextureNormalizer*vec4(1.0, 0.0, 0.0, 0.0)).r; x1 = xformTex2DOffset(bump_gradient_texture, UV, bump_gradient_texture_matrix, +bumpTextureNormalizer*vec4(1.0, 0.0, 0.0, 0.0)).r; y0 = xformTex2DOffset(bump_gradient_texture, UV, bump_gradient_texture_matrix, -bumpTextureNormalizer*vec4(0.0, 1.0, 0.0, 0.0)).r; y1 = xformTex2DOffset(bump_gradient_texture, UV, bump_gradient_texture_matrix, +bumpTextureNormalizer*vec4(0.0, 1.0, 0.0, 0.0)).r; bumpGradient.xyz = vec3(-(x1-x0)*unscaledIBLColor.a, -(y1-y0)*unscaledIBLColor.a, 0); bumpGradient.xyz = bumpGradient.xyz*(bumpStrength*2.0*bumpLookup.a*bumpNormalPreviewFlags[0]); #endif #endif vec2 noiseBumpGradient = vec2(0.0, 0.0); #ifdef HAS_VOLUME_BUMP_NOISE //NoiseBump vec4 geomPointInBBOXSpace = iEyeToNormalizedBBOXMatrix*geomPointInEyeSpace; vec4 params; params.x = volumeNoiseBumpParams[0]; params.y = volumeNoiseBumpParams[1]; params.z = 3.0; params.w = 0.0; float duValue = PerlinNoise3D(volumeNoiseTexture, volumeNoiseBumpParams[2]*geomPointInBBOXSpace.xyz, params); float dvValue = PerlinNoise3D(volumeNoiseTexture, volumeNoiseBumpParams[2]*geomPointInBBOXSpace.xyz+vec3(0.7, 0.7, 0.7), params); noiseBumpGradient = volumeNoiseBumpParams[3]*vec2(duValue-0.5, dvValue-0.5); // if (agf_force_flat_shading[0]>0.5) { _t=vec3(1.0, 0.0, 0.0); _b=vec3(0.0, 1.0, 0.0); } //gl_FragColor = vec4(duValue, dvValue, 1.0, 1.0); //return; #endif bumpGradient.xy = noiseBumpGradient+bumpGradient.xy; vec3 normalDistortionTangentSpace = bumpGradient; //Alpha channel used to modulate bump strength vec3 normalDistortionEyeSpace; normalDistortionEyeSpace.x = _t.x * normalDistortionTangentSpace.x + _b.x * normalDistortionTangentSpace.y; normalDistortionEyeSpace.y = _t.y * normalDistortionTangentSpace.x + _b.y * normalDistortionTangentSpace.y; normalDistortionEyeSpace.z = _t.z * normalDistortionTangentSpace.x + _b.z * normalDistortionTangentSpace.y; newNormal = normalize(newNormal + normalDistortionEyeSpace); //Determine if triangle is front/back facing if (gl_FrontFacing)//back-facing condition check { newNormal = -newNormal; } else { newNormal = newNormal; } //###################################################### END OF NORMAL ALTERATION ############################################## //###################################################### CALCULATION OF THE SPECULAR EXPONENT ################################# float shininess = material.shininess; #ifdef ENABLE_AGFSpecularExponentMap //texLookup = tex2D(specular_exponent_texture, interpolant.fTexCoord0.xy); texLookup = xformTex2D(specular_exponent_texture, UV, specular_exponent_texture_matrix); shininess = mix(material.shininess, (1.0+180.0*texLookup.r), texLookup.a); #endif vec3 materialAdjustedRoughnessSpecularColor = materialSpecularColor; //###################################################### ADJUSTMENT OF THE SPECULAR COLOR BASED ON ROUGHNESS VALUE ############# #ifdef ENABLE_ROUGHNESS float roughnessValue = roughness.r; #ifdef ENABLE_AGFRoughnessMap texLookup = xformTex2D(roughness_texture, UV,roughness_texture_matrix); roughnessValue = mix(roughness.r, texLookup.r, texLookup.a); #endif roughnessValue = roughnessValue*0.5; float roughnessSigma = roughnessValue; float phongSigma = acos(exp(-1.0/(2.0*shininess))); float newSigma = sqrt(phongSigma*phongSigma+roughnessSigma*roughnessSigma); shininess = (-1.0/(2.0*log(cos(newSigma)))); float specColorFadeout = phongSigma/newSigma; float specColorFadeoutSquared = specColorFadeout*specColorFadeout; vec3 specColorFadeout3 = vec3(specColorFadeoutSquared, specColorFadeoutSquared, specColorFadeoutSquared); materialAdjustedRoughnessSpecularColor = materialSpecularColor*specColorFadeout3; #endif //############################################# DIRECT LIGHTING/SHADOWS CALCULATIONS ################################################# vec3 diff = vec3(0.0, 0.0, 0.0); #ifdef ENABLE_LIGHTING vec3 spec = vec3(0.0, 0.0, 0.0); int i=0; vec3 diffNoShadowDummy=vec3(0.0, 0.0, 0.0); float screenSpaceRandomNumber=0.0; #if NUMBER_OF_ACTIVE_INFINITE_LIGHTS > 0 for (i=0;i 0 for (i=0;i 0 for (i=0;i0.5) t_reflect.xyz = reflect(vec3(0, 0, -1), newNormal); //Parallel Projection else t_reflect.xyz = reflect(normalize(vertOut_vPosition.xyz), newNormal); //Perspective Projection t_reflect.w = 0.0; #ifdef ENABLE_AGFSphereEnvironmentMap reflectionVector = (reflectionTransformationMatrix * t_reflect).xyz; texLookup = texSPHERE(environment_texture,environment_texture_matrix, reflectionVector); reflColor.rgb = mix(unscaledIBLColor.rgb, texLookup.rgb, texLookup.a); //reflColor.rgb = vec3(0, 0, 0); float texStep = 1.0/16.0; float texOffset = 1.0/(16.0*2.0); #ifdef ENABLE_ADVANCED_REFRACTION_REFLECTION #ifdef ENABLE_IBL_SPECULAR_HIGHLIGHTS vec3 minShinyColor; vec3 maxShinyColor; vec3 mediumShinyColor; texLookup=texSPHEREMULTI(discreteShininess3DTex, environment_texture_matrix, vec4(1.0/9.0, 1.0/9.0, 2.0*texStep+texOffset, 1.0), reflectionVector); minShinyColor = mix(environmentColor.rgb, texLookup.rgb, texLookup.a); texLookup=texSPHEREMULTI(discreteShininess3DTex, environment_texture_matrix, vec4(1.0/1.0, 1.0/1.0, 0.0*texStep+texOffset, 1.0), reflectionVector); maxShinyColor = mix(environmentColor.rgb, texLookup.rgb, texLookup.a); texLookup=texSPHEREMULTI(discreteShininess3DTex, environment_texture_matrix, vec4(1.0/3.0, 1.0/3.0, 1.0*texStep+texOffset, 1.0), reflectionVector); mediumShinyColor = mix(environmentColor.rgb, texLookup.rgb, texLookup.a); float lt = 0.0; if (shininess<20.0) { lt = shininess/20.0; iblSpecularHighlightsContribution.rgb = mix(minShinyColor, mediumShinyColor, lt); } else { lt = (shininess-20.0)/492.0; iblSpecularHighlightsContribution.rgb = mix(mediumShinyColor, maxShinyColor, lt); } iblSpecularHighlightsContribution.rgb = iblSpecularHighlightsContribution.rgb*materialSpecularColor.rgb*iGlobalAmbientColor.a; iblSpecularHighlightsContribution.a = 0.0; #endif #ifdef ENABLE_ROUGHNESS vec4 color0 = reflColor.rgba; vec4 color1 = texSPHEREMULTI(discreteShininess3DTex, environment_texture_matrix, vec4(1.0, 1.0, 3.0*texStep+texOffset, 1.0), reflectionVector); float t = roughnessValue/0.1; vec4 roughReflectionColor = mix(color0, color1, t); if (roughnessValue>0.1) { float texZ; t = (roughnessValue-0.1)/0.9; texZ = mix(3.0*texStep+texOffset, 12.0*texStep+texOffset, t); roughReflectionColor = texSPHEREMULTI(discreteShininess3DTex, environment_texture_matrix, vec4(1.0/1.0, 1.0, texZ, 1.0), reflectionVector); } reflColor.rgb = roughReflectionColor.rgb; #endif #endif #endif reflColor.a = 0.0; //############################################# ADJUSTING reflColor with REFLECTIVITY VALUE ################################################# vec3 materialReflectivity3 = vec3(material.reflectivity); #ifdef ENABLE_AGFReflectivityMap vec3 reflectivity; texLookup = xformTex2D(reflectivity_texture, UV,reflectivity_texture_matrix); reflectivity = mix(materialReflectivity3, texLookup.rgb, texLookup.a); //Default reflectivity is non-reflective, for now reflColor.rgb = reflColor.rgb*reflectivity; #else reflColor.rgb = reflColor.rgb*materialReflectivity3; #endif if (material.selfillum.a < 1.5) { //Do not add reflections for lighting-only mode finalColor = finalColor + reflColor + iblSpecularHighlightsContribution; } //########################################## ADDING SELF-ILLUMINATION ######################################################################## #ifdef ENABLE_AGFSelfIlluminationMap vec4 selfIlluminationColor; selfIlluminationColor = xformTex2D(self_illumination_texture, UV, self_illumination_texture_matrix).rgba; vec3 rescaledSelfIlluminationColor; rescaledSelfIlluminationColor.r = mix(self_illumination_texture_range[0],self_illumination_texture_range[1], selfIlluminationColor.r); rescaledSelfIlluminationColor.g = mix(self_illumination_texture_range[0],self_illumination_texture_range[1], selfIlluminationColor.g); rescaledSelfIlluminationColor.b = mix(self_illumination_texture_range[0],self_illumination_texture_range[1], selfIlluminationColor.b); vec3 blendedSelfIlluminationColor = mix(material.selfillum.rgb,rescaledSelfIlluminationColor.rgb, selfIlluminationColor.a); finalColor.rgb = finalColor.rgb + blendedSelfIlluminationColor; #else finalColor.rgb = finalColor.rgb + material.selfillum.rgb; #endif //float opacity = mainColor.a; //########################################## REFRACTION ##################################################################################### #ifdef ENABLE_ADVANCED_REFRACTION_REFLECTION if (refraction_flag[0]>0.5) { vec3 refractedRay; vec4 t_refract; t_refract.xyz = refract(normalize(vertOut_vPosition.xyz), newNormal, 1.0/material.ior); t_refract.w = 0.0; refractedRay = (refractionTransformationMatrix * t_refract).xyz; vec4 refractedColor; refractedColor = texSPHERE(background_texture,background_texture_matrix, refractedRay); finalColor.rgb = mix(refractedColor.rgb, finalColor.rgb, opacity); finalColor.a = refractedColor.a; } #endif //########################################## FINAL PROCESSING ################################################################################ finalColor.a = finalOpacity; #ifdef ENABLE_ALPHA_PREMULTIPLY finalColor.rgb = finalColor.rgb*finalColor.a; #endif #if 0 //Testing the noise function vec4 geomPointInEyeSpace = vec4(vertOut_vEye, 1.0); vec4 geomPointInBBOXSpace = iEyeToNormalizedBBOXMatrix*geomPointInEyeSpace; vec3 params; params.x = 2.0;//material.reflectivity*4.0; params.y = 1.8;//material.opacity*4.0; params.z = 3.0; float noiseValue = PerlinNoise3D(volumeNoiseTexture, 5.0*geomPointInBBOXSpace.xyz, params); finalColor.rgb = vec3(noiseValue, noiseValue, noiseValue); finalColor.a = 1.0; #endif // float noiseTest = crand(gl_FragCoord.xy); // finalColor.rgb = vec3(noiseTest, noiseTest, noiseTest); #ifdef FORCE_DIFFUSE_NO_SHADOWS gl_FragColor.rgb = diffuseColor.rgb; gl_FragColor.a = 1.0; #else gl_FragColor = finalColor; #endif }