Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #version 330 core
- out vec4 FragColor;
- in vec3 FragPos; // World space position
- in vec3 Normal; // Normal in world space
- uniform sampler2D bgTexture; // Background texture
- uniform vec3 cameraPos; // Camera position
- uniform vec3 lightPos; // Light position
- uniform mat4 view; // View matrix
- uniform mat4 projection; // Projection matrix
- const float blurRadius = 0.002; // Radius for blurring
- const int blurSamples = 1; // Number of samples for blur
- const vec3 lightColor = vec3(1.0, 1.0, 1.0); // Light color
- const vec3 fresnelColour = vec3(1.0, 1.0, 1.0); // Light color
- const float refractiveIndex = 1.5; // Refractive index, e.g., 1.5 for glass
- vec2 getUV(vec3 fragPos);
- vec2 applyWarp(vec2 uv, vec3 normal);
- vec4 sampleBlurredTexture(sampler2D texture, vec2 uv);
- float calculateFresnel(vec3 fragPos, vec3 normal, vec3 cameraPos);
- vec4 blendWithFresnel(vec4 color, float fresnel);
- vec4 calculateSpecular(vec3 fragPos, vec3 normal, vec3 viewDir);
- float phongShading(vec3 FragPos, vec3 Normal, vec3 cameraPos, vec3 lightPos);
- vec4 calcRefraction();
- void main() {
- // Step 1: Calculate UV coordinates from fragment position
- vec2 uv = getUV(FragPos);
- // vec4 refraction = calcRefraction() * phongShading(FragPos, Normal, cameraPos, lightPos);
- vec4 refraction = calcRefraction();
- // Step 2: Warp the UV based on the surface normal
- // uv = applyWarp(uv, Normal);
- // Step 3: Calculate the refracted ray direction using Snell's law
- vec3 viewDir = normalize(cameraPos - FragPos);
- // Step 4: Sample the background texture using the refracted direction
- // You might need to adjust the UV coordinates here based on your background
- // vec4 bgColor = sampleBlurredTexture(bgTexture, uv);
- // Step 5: Calculate the Fresnel effect
- float fresnel = calculateFresnel(FragPos, Normal, cameraPos);
- // Step 6: Calculate specular
- vec4 specular = calculateSpecular(FragPos, Normal, viewDir);
- // Step 7: Blend specular with Fresnel effect
- vec4 finalColor = mix(refraction * 2, specular, 0.5);
- FragColor = blendWithFresnel(finalColor, fresnel);
- }
- vec2 getUV(vec3 fragPos) {
- vec4 clipSpacePos = projection * view * vec4(fragPos, 1.0);
- vec3 ndc = clipSpacePos.xyz / clipSpacePos.w;
- return ndc.xy * 0.5 + 0.5;
- }
- vec2 applyWarp(vec2 uv, vec3 normal) {
- vec3 norm = normalize(normal);
- vec2 warp = norm.xy * 0.05; // Warp strength based on normal
- return clamp(uv + warp, 0.0, 1.0);
- }
- vec4 sampleBlurredTexture(sampler2D texture, vec2 uv) {
- vec4 color = vec4(0.0);
- float totalWeight = 0.0;
- for (int i = -blurSamples; i <= blurSamples; ++i)
- {
- for (int j = -blurSamples; j <= blurSamples; ++j)
- {
- vec2 offset = vec2(float(i), float(j)) * blurRadius;
- float weight = exp(-(dot(offset, offset) / (2.0 * blurRadius * blurRadius)));
- color += texture2D(texture, uv + offset) * weight;
- totalWeight += weight;
- }
- }
- return color / totalWeight; // Normalize the result
- }
- float calculateFresnel(vec3 fragPos, vec3 normal, vec3 cameraPos) {
- vec3 viewDir = normalize(cameraPos - fragPos);
- float cosTheta = dot(viewDir, normalize(normal));
- return pow(1.0 - cosTheta, 6.0);
- }
- vec4 blendWithFresnel(vec4 color, float fresnel) {
- vec4 fresnelHighlight = vec4(fresnelColour.r, fresnelColour.g, fresnelColour.b, 1.0);
- return mix(color, fresnelHighlight, fresnel);
- }
- vec4 calculateSpecular(vec3 fragPos, vec3 normal, vec3 viewDir) {
- vec3 norm = normalize(normal);
- vec3 lightDir = normalize(lightPos - fragPos);
- vec3 reflectDir = reflect(-lightDir, norm);
- float spec = pow(max(dot(viewDir, reflectDir), 0.0), 50.0);
- vec3 specular = spec * lightColor * 2;
- return vec4(specular, 1.0);
- }
- float phongShading(vec3 FragPos, vec3 Normal, vec3 cameraPos, vec3 lightPos) {
- // Light direction
- vec3 lightDir = normalize(lightPos - FragPos);
- // View direction
- vec3 viewDir = normalize(cameraPos - FragPos);
- // Calculate Diffuse: Lambertian reflection with exaggerated intensity
- float diffuse = max(dot(Normal, lightDir), 0.0);
- // Exaggerate the diffuse lighting for more dramatic effect
- diffuse = pow(diffuse, 2.0); // Cube the diffuse to enhance the effect (can adjust the exponent)
- // Return the enhanced diffuse as Phong shading value
- return diffuse;
- }
- vec4 calcRefraction() {
- // Warps the texture and applies some gaussian blur that tapers off at glancing angles to make the thing look like glass. This is abstract art really, it is not in any way accurate
- // Calculate normalized view vector (eye direction)
- vec3 eyeVector = normalize(FragPos - cameraPos);
- // Normalize the surface normal
- vec3 normal = normalize(Normal);
- // Calculate refraction vector using Snell's law
- float refractiveIndexRatio = 1.0 / 1.5; // Air to glass (or vice versa)
- vec3 faceNormal = normalize(Normal); // Normal for this face
- vec3 refractVec = refract(eyeVector, faceNormal * 10, refractiveIndexRatio);
- // Step 1: Calculate the direction of the camera to the fragment
- vec3 viewDir = normalize(cameraPos - FragPos);
- // Step 2: Compute the texture coordinates based on world position and camera/projection matrices
- vec4 viewPos = view * vec4(FragPos, 1.0); // Transform the world position to view space
- // Map the view space position to clip space
- vec4 clipSpacePos = projection * viewPos;
- // Convert clip space coordinates to normalized device coordinates (NDC)
- vec2 ndc = clipSpacePos.xy / clipSpacePos.w; // NDC in the range [-1, 1]
- // Map NDC to texture space [0, 1]
- vec2 uv = (ndc * 0.5) + 0.5; // Map to [0, 1] range for texture
- // Transform refract vector to screen UV coordinates (assumes screen space mapping)
- vec2 refractedUV = uv + refractVec.xy * 0.1; // Offset UV based on refraction vector
- // Step 3: Adjust blur size based on the dot product between view direction and surface normal
- float dotProduct = max(dot(viewDir, normal), 0.0); // Avoid negative values
- // Map the dot product (cosine of the angle) to blur strength: closer to 0 (glancing) -> less blur
- float blurStrength = -dotProduct * 2 + 1; // Decrease blur for glancing angles
- float blurSize = 0.002 * blurStrength; // Adjust blur size based on the angle
- // Blur kernel size (how many samples around the refraction direction)
- int numSamples = 5;
- float sigma = 1.0; // Standard deviation for Gaussian
- float weightSum = 0.0;
- vec4 blurColor = vec4(0.0);
- for (int i = -numSamples / 2; i <= numSamples / 2; i++) {
- for (int j = -numSamples / 2; j <= numSamples / 2; j++) {
- float distance = float(i * i + j * j);
- float weight = exp(-distance / (2.0 * sigma * sigma)); // Gaussian weight
- vec2 offset = vec2(i, j) * blurSize;
- blurColor += texture(bgTexture, (refractedUV + offset) * 1.1) * weight;
- weightSum += weight;
- }
- }
- blurColor /= weightSum; // Normalize by the sum of weights
- // Step 4: Return the blurred background color
- return blurColor;
- }
Add Comment
Please, Sign In to add comment