mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	* Add ShaderLab language * Update HLSL and ShaderLab grammars to latest version * Add .shader extension back to GLSL language * Add sample GLSL .shader files Note that these are copies of existing GLSL samples, renamed to have the .shader extension.
		
			
				
	
	
		
			161 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			GLSL
		
	
	
	
	
	
			
		
		
	
	
			161 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			GLSL
		
	
	
	
	
	
#version 120
 | 
						|
 | 
						|
/*
 | 
						|
  Original Lens Distortion Algorithm from SSontech (Syntheyes)
 | 
						|
  http://www.ssontech.com/content/lensalg.htm
 | 
						|
  
 | 
						|
  r2 is radius squared.
 | 
						|
  
 | 
						|
  r2 = image_aspect*image_aspect*u*u + v*v
 | 
						|
  f = 1 + r2*(k + kcube*sqrt(r2))
 | 
						|
  u' = f*u
 | 
						|
  v' = f*v
 | 
						|
 | 
						|
*/
 | 
						|
 | 
						|
// Controls
 | 
						|
uniform float kCoeff, kCube, uShift, vShift;
 | 
						|
uniform float chroma_red, chroma_green, chroma_blue;
 | 
						|
uniform bool apply_disto;
 | 
						|
 | 
						|
// Uniform inputs
 | 
						|
uniform sampler2D input1;
 | 
						|
uniform float adsk_input1_w, adsk_input1_h, adsk_input1_aspect, adsk_input1_frameratio;
 | 
						|
uniform float adsk_result_w, adsk_result_h;
 | 
						|
 | 
						|
float distortion_f(float r) {
 | 
						|
    float f = 1 + (r*r)*(kCoeff + kCube * r);
 | 
						|
    return f;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
float inverse_f(float r)
 | 
						|
{
 | 
						|
    
 | 
						|
    // Build a lookup table on the radius, as a fixed-size table.
 | 
						|
    // We will use a vec3 since we will store the multipled number in the Z coordinate.
 | 
						|
    // So to recap: x will be the radius, y will be the f(x) distortion, and Z will be x * y;
 | 
						|
    vec3[48] lut;
 | 
						|
    
 | 
						|
    // Since out LUT is shader-global check if it's been computed alrite
 | 
						|
    // Flame has no overflow bbox so we can safely max out at the image edge, plus some cushion
 | 
						|
    float max_r = sqrt((adsk_input1_frameratio * adsk_input1_frameratio) + 1) + 0.1;
 | 
						|
    float incr = max_r / 48;
 | 
						|
    float lut_r = 0;
 | 
						|
    float f;
 | 
						|
    for(int i=0; i < 48; i++) {
 | 
						|
        f = distortion_f(lut_r);
 | 
						|
        lut[i] = vec3(lut_r, f, lut_r * f);
 | 
						|
        lut_r += incr;
 | 
						|
    }
 | 
						|
    
 | 
						|
    float t;
 | 
						|
    // Now find the nehgbouring elements
 | 
						|
    // only iterate to 46 since we will need
 | 
						|
    // 47 as i+1
 | 
						|
    for(int i=0; i < 47; i++) {
 | 
						|
        if(lut[i].z < r && lut[i+1].z > r) {
 | 
						|
            // BAM! our value is between these two segments
 | 
						|
            // get the T interpolant and mix
 | 
						|
            t = (r - lut[i].z) / (lut[i+1].z - lut[i]).z;
 | 
						|
            return mix(lut[i].y, lut[i+1].y, t );
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
float aberrate(float f, float chroma)
 | 
						|
{
 | 
						|
   return f + (f * chroma);
 | 
						|
}
 | 
						|
 | 
						|
vec3 chromaticize_and_invert(float f)
 | 
						|
{
 | 
						|
   vec3 rgb_f = vec3(aberrate(f, chroma_red), aberrate(f, chroma_green), aberrate(f, chroma_blue));
 | 
						|
   // We need to DIVIDE by F when we redistort, and x / y == x * (1 / y)
 | 
						|
   if(apply_disto) {
 | 
						|
      rgb_f = 1 / rgb_f;
 | 
						|
   }
 | 
						|
   return rgb_f;
 | 
						|
}
 | 
						|
 | 
						|
void main(void)
 | 
						|
{
 | 
						|
   vec2 px, uv;
 | 
						|
   float f = 1;
 | 
						|
   float r = 1;
 | 
						|
   
 | 
						|
   px = gl_FragCoord.xy;
 | 
						|
   
 | 
						|
   // Make sure we are still centered
 | 
						|
   px.x -= (adsk_result_w - adsk_input1_w) / 2;
 | 
						|
   px.y -= (adsk_result_h - adsk_input1_h) / 2;
 | 
						|
   
 | 
						|
   // Push the destination coordinates into the [0..1] range
 | 
						|
   uv.x = px.x / adsk_input1_w;
 | 
						|
   uv.y = px.y / adsk_input1_h;
 | 
						|
   
 | 
						|
       
 | 
						|
   // And to Syntheyes UV which are [1..-1] on both X and Y
 | 
						|
   uv.x = (uv.x *2 ) - 1;
 | 
						|
   uv.y = (uv.y *2 ) - 1;
 | 
						|
   
 | 
						|
   // Add UV shifts
 | 
						|
   uv.x += uShift;
 | 
						|
   uv.y += vShift;
 | 
						|
   
 | 
						|
   // Make the X value the aspect value, so that the X coordinates go to [-aspect..aspect]
 | 
						|
   uv.x = uv.x * adsk_input1_frameratio;
 | 
						|
   
 | 
						|
   // Compute the radius
 | 
						|
   r = sqrt(uv.x*uv.x + uv.y*uv.y);
 | 
						|
   
 | 
						|
   // If we are redistorting, account for the oversize plate in the input, assume that
 | 
						|
   // the input aspect is the same
 | 
						|
   if(apply_disto) {
 | 
						|
       r = r / (float(adsk_input1_w) / float(adsk_result_w));
 | 
						|
   }
 | 
						|
   
 | 
						|
   // Apply or remove disto, per channel honoring chromatic aberration
 | 
						|
   if(apply_disto) {
 | 
						|
      f = inverse_f(r);
 | 
						|
   } else {
 | 
						|
      f = distortion_f(r);
 | 
						|
   }
 | 
						|
   
 | 
						|
   vec2[3] rgb_uvs = vec2[](uv, uv, uv);
 | 
						|
   
 | 
						|
   // Compute distortions per component
 | 
						|
   vec3 rgb_f = chromaticize_and_invert(f);
 | 
						|
   
 | 
						|
   // Apply the disto coefficients, per component
 | 
						|
   rgb_uvs[0] = rgb_uvs[0] * rgb_f.rr;
 | 
						|
   rgb_uvs[1] = rgb_uvs[1] * rgb_f.gg;
 | 
						|
   rgb_uvs[2] = rgb_uvs[2] * rgb_f.bb;
 | 
						|
   
 | 
						|
   // Convert all the UVs back to the texture space, per color component
 | 
						|
   for(int i=0; i < 3; i++) {
 | 
						|
       uv = rgb_uvs[i];
 | 
						|
       
 | 
						|
       // Back from [-aspect..aspect] to [-1..1]
 | 
						|
       uv.x = uv.x / adsk_input1_frameratio;
 | 
						|
       
 | 
						|
       // Remove UV shifts
 | 
						|
       uv.x -= uShift;
 | 
						|
       uv.y -= vShift;
 | 
						|
       
 | 
						|
       // Back to OGL UV
 | 
						|
       uv.x = (uv.x + 1) / 2;
 | 
						|
       uv.y = (uv.y + 1) / 2;
 | 
						|
       
 | 
						|
       rgb_uvs[i] = uv;
 | 
						|
   }
 | 
						|
   
 | 
						|
   // Sample the input plate, per component
 | 
						|
   vec4 sampled;
 | 
						|
   sampled.r = texture2D(input1, rgb_uvs[0]).r;
 | 
						|
   sampled.g = texture2D(input1, rgb_uvs[1]).g;
 | 
						|
   sampled.b = texture2D(input1, rgb_uvs[2]).b;
 | 
						|
   
 | 
						|
   // and assign to the output
 | 
						|
   gl_FragColor.rgba = vec4(sampled.rgb, 1.0 );
 | 
						|
} |