HEX
Server: LiteSpeed
System: Linux houston.panomity.com 6.8.0-100-generic #100-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan 13 16:40:06 UTC 2026 x86_64
User: nudepix (1011)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /home/panomity.de/vr.panomity.com/plugins/postprocessing_multipass_blur.js
/*
	krpano WebGL Post-Processing Plugin - Multi-Pass-Blur
	1.19


	A simple post-processing sharping effect as example.


	The krpano WebGL API:

	* krpano.webGL
	  - an object with all WebGL related stuff
	  - when the object is null, then there is no WebGL support

	* krpano.webGL.canvas
	  - the <canvas> element for the WebGL rendering

	* krpano.webGL.context
	  - the WebGL rendering context

	* shader = krpano.webGL.createPostProcessingShader(fragment_shader_source, uniforms)
	  - create a krpano post processing shader
	  - a WebGL GLSL fragment shader
	  - parameters:
	    - fragment_shader_source
	      - a GLSL shader source code as string
	      - the shaders code needs to have:
	        - a 'sm' named sampler2D - this will be the current screen as input texture
	        - a 'tx' named vec2 varying - this will be the current texture coordinate
	        - optionally a 'sz' vec2 uniform - this will contain the screen size
	    - uniforms
	      - a comma separated list of the uniform names used in the shader
	      - the 'uniform location' will be automatically stored at the returned
	        shader object with the same name
	  - return:
	    - a krpano shader object
	    - can be added to the 'ppShaderArray' Array
	    - or used for 'useShader'
	
	* krpano.webGL.ppShaderArray
	  - an Array of post-processing shaders
	  - here custom shaders can be added, inserted or removed
	  - the shaders will be processed by the order in that Array
	  
	* krpano.webGL.useShader(shader)
	  - select/activate the shader for interfacing
	  - e.g. for setting uniform values
	  - NOTE - after usage useShader(null) needs be called to restore
	    the previous shader! IMPORTANT!

	* krpano.webGL.deleteShader(shader)
	  - delete a shader (free-up the internal WebGL resources) 
*/

var krpanoplugin = function()
{
	var local  = this;

	// internal plugin information
	local.name    = "WebGL Post-Processing Plugin (Multi-Pass-Blur)";
	local.version = "1.19";

	var krpano = null;
	var plugin = null;
	
	// krpano WebGL pixel shaders
	var shader_passes = 6;		// the more the higher the quality at larger blur settings - need to be a multiple of 2
	var shaders = null;

	// xml attributes
	var xml_blur = 1.0;


	function get_shader_src()
	{
		return ""+
			"precision mediump float;"+
			"uniform sampler2D sm;"+			// sm = the screen as input texture sampler
			"uniform vec2 sz;"+					// sz = screen size in pixels (sz.x = width, sz.y = height)
			"uniform float blur;"+				// a custom uniform
			"uniform vec2 dir;"+				// a custom uniform
			"varying vec2 tx;"+					// tx = the texture coordinates (0.0,0.0 to 1.0,1.0)
			"void main()"+
			"{"+
				"float hblur  = dir.x * blur / sz.x;"+
				"float vblur  = dir.y * blur / sz.y;"+
				"vec4 sum = vec4(0.0);"+
				"sum += texture2D(sm, vec2(tx.x - 4.0*hblur, tx.y - 4.0*vblur)) * 0.0162162162;"+
				"sum += texture2D(sm, vec2(tx.x - 3.0*hblur, tx.y - 3.0*vblur)) * 0.0540540541;"+
				"sum += texture2D(sm, vec2(tx.x - 2.0*hblur, tx.y - 2.0*vblur)) * 0.1216216216;"+
				"sum += texture2D(sm, vec2(tx.x - 1.0*hblur, tx.y - 1.0*vblur)) * 0.1945945946;"+
				"sum += texture2D(sm, vec2(tx.x,             tx.y)            ) * 0.2270270270;"+
				"sum += texture2D(sm, vec2(tx.x + 1.0*hblur, tx.y + 1.0*vblur)) * 0.1945945946;"+
				"sum += texture2D(sm, vec2(tx.x + 2.0*hblur, tx.y + 2.0*vblur)) * 0.1216216216;"+
				"sum += texture2D(sm, vec2(tx.x + 3.0*hblur, tx.y + 3.0*vblur)) * 0.0540540541;"+
				"sum += texture2D(sm, vec2(tx.x + 4.0*hblur, tx.y + 4.0*vblur)) * 0.0162162162;"+
				"gl_FragColor = vec4(sum.rgb, 1.0);"+
			"}";
	}
	


	// plugin entry point
	local.registerplugin = function(krpanointerface, pluginpath, pluginobject)
	{
		krpano = krpanointerface;
		plugin = pluginobject;

		if (krpano.version < "1.19" || krpano.build < "2016-04-01")
		{
			krpano.trace(3, local.name+" - too old krpano version (min. 1.19)");
			return;
		}

		// check for WebGL support
		if (krpano.webGL)
		{
			shaders = new Array(shader_passes);
			
			// create a custom shader with custom 'blur' and 'dir' uniforms and
			// a 'sz' uniform (a krpano internal uniform for the screen size)
			for (var i=0; i < shader_passes; i++)
			{
				shaders[i] = krpano.webGL.createPostProcessingShader( get_shader_src(), "blur,dir,sz");
			
				if (shaders[i])
				{
					// add the shaders as last ones to an Array of krpano post-processing shaders
					krpano.webGL.ppShaderArray.push( shaders[i] );
				}
			}
			
			// add plugin attributes (will automatically also call the 'set' callback to init the value)
			plugin.registerattribute("blur", xml_blur, api_blur_set, api_blur_get);
		}
	}


	function remove_shader_from_krpano()
	{
		// get the Array of krpano post-processing shader
		var ppShaderArray = krpano.webGL.ppShaderArray;

		// look for the own-added shader and remove it
		for (var i=0; i<ppShaderArray.length; i++)
		for (var j=0; j<shader_passes; j++)
		{
			if ( ppShaderArray[i] === shaders[j] )
			{
				ppShaderArray.splice(i,1);
				shaders[j] = null;
			}
		}
	}


	local.unloadplugin = function()
	{
		if (shaders)
		{
			for (var i=0; i<shader_passes; i++)
			{
				krpano.webGL.deleteShader(shaders[i]);
			}
			
			remove_shader_from_krpano();
			
			shaders = null;
		}

		krpano = null;
		plugin = null;
	}


	function api_blur_set(value)
	{
		// convert to number
		value = Number(value);

		// is a valid number?
		if ( !isNaN(value) )
		{
			xml_blur = value;

			// update the shader uniform
			api_blur_update();
		}
	}


	function api_blur_get()
	{
		return xml_blur;
	}


	function api_blur_update()
	{
		// update the shader
		if (shaders)
		{
			for (var i=0; i<shader_passes; i++)
			{
				// select/activate the shader for interfacing
				krpano.webGL.useShader(shaders[i]);
				
				var pass_blur = (((i >> 1)+1) / (shader_passes/2.0)) * xml_blur;
				var pass_dir = (i & 1) == 0 ? 1.0 : 0.0;
	
				// set/update the value for the 'blur' uniform
				krpano.webGL.context.uniform1f(shaders[i].blur, pass_blur);
				krpano.webGL.context.uniform2f(shaders[i].dir, pass_dir, 1.0 - pass_dir);
			}

			// restore
			krpano.webGL.useShader(null);
			
			// need a redraw
			krpano.view.haschanged = true;
		}
	}
}