View Single Post
  #1  
Old 04-23-2010, 12:23 PM
whj whj is offline
Member
 
Join Date: Apr 2008
Posts: 60
How to apply shader and render texture to an object

Hello,

I would like to blur the view and apply the blurring vision to an object in the scene. For example, this code tries to render a blur view on a rectangle object in the middle of the gallery. But it blurred the whole scene instead. I don't know how to deal with both shader and render texture at the same time. Can anybody at least explain the concept of pass, setHUD, setBuffer, setOrder....?

Thanks,

Code:
import viz
viz.go()

d = viz.Data()
d.scale = 1.0
d.created = False


def enable(size=512,kernel=10):
	"""Enable fulscreen blurring"""
	if not d.created:
		d.created = True
		d.passes = []

		#Uniforms for shaders
		srcImageUniform = viz.addUniformInt('srcImage',0)
		blurScaleUniform = viz.addUniformFloat('blurScale',1.0)

		blur_source = """
		uniform sampler2D srcImage;
		uniform float blurScale;
		void main(void)
		{
			vec4 color = vec4(0,0,0,0);
			%code%
			color.a = 1.0;
			gl_FragColor = color;
		}"""
		
		#Calculate weight and offsets for blur code
		weights = []
		offsets = []
		mid = float(kernel - 1)
		kernel *= 2
		for i in xrange(0,kernel,2):
			offsets.append( ((i-mid) / 2.0) * (1.0 / size) )
			x = (i - mid) / mid
			weights.append( 0.05 + ((-(x*x) + 1.0) / 4.0) )
			
		#Normalize weights
		total = sum(weights)
		frac = 1.0 / total
		weights = [ frac * x for x in weights]

		#Create blur code for shaders
		horz_blur_code = []
		vert_blur_code = []
		for w,o in zip(weights,offsets):
			horz_blur_code.append('color += ( texture2D( srcImage, gl_TexCoord[0].xy + vec2( %f*blurScale, 0.0 ) ) * %f );'%(o,w))
			vert_blur_code.append('color += ( texture2D( srcImage, gl_TexCoord[0].xy + vec2( 0.0, %f*blurScale ) ) * %f );'%(o,w))
			
		horzBlurShader = viz.addShader(frag=blur_source.replace('%code%','\n'.join( horz_blur_code ) ))
		vertBlurShader = viz.addShader(frag=blur_source.replace('%code%','\n'.join( vert_blur_code ) ))
		
		for eye in [viz.RENDER_LEFT,viz.RENDER_RIGHT]:
			
			#Render textures for ping-ponging
			tex1 = viz.addRenderTexture()
			tex2 = viz.addRenderTexture()
			
			"""
			Pass 1 renders the normal scene to a texture
			"""
			pass1 = viz.addRenderNode(size=[size,size])
			pass1.attachTexture(tex1)
			pass1.setOrder(viz.PRE_RENDER,-5)
			pass1.disable(eye)
			
			"""
			Pass 2 renders the texture from pass 1 onto a quad.
			The quad has a shader attached which blurs the texture horizontally.
			"""
			pass2 = viz.addRenderNode()
			pass2.setHUD(0,200,0,200,renderQuad=True)
			pass2.setSize(size,size)
			pass2.setBuffer(viz.RENDER_FBO)
			pass2.setOrder(viz.PRE_RENDER,-4)
			pass2.attachTexture(tex2)
			pass2.texture(tex1)
			pass2.apply(horzBlurShader)
			pass2.apply(srcImageUniform)
			pass2.apply(blurScaleUniform)
			pass2.disable(eye)
			
			"""
			Pass 3 renders the texture from pass 2 onto a quad.
			The quad has a shader attached which blurs the texture vertically.
			"""
			pass3 = viz.addRenderNode()
			pass3.setHUD(0,200,0,200,renderQuad=True)
			pass3.setSize(size,size)
			pass3.setBuffer(viz.RENDER_FBO)
			pass3.setOrder(viz.PRE_RENDER,-3)
			pass3.attachTexture(tex1)
			pass3.texture(tex2)
			pass3.apply(vertBlurShader)
			pass3.apply(srcImageUniform)
			pass3.apply(blurScaleUniform)
			pass3.disable(eye)
			
			"""
			Pass 4 renders the final blurred texture to the screen
			"""
			pass4 = viz.addRenderNode()
			pass4.setHUD(0,200,0,200,renderQuad=True)
			pass4.setOrder(viz.POST_RENDER,-1)
			pass4.texture(tex1)
			pass4.disable(eye)
			
			#Save render nodes and blur uniform
			d.passes += [pass1,pass2,pass3,pass4]
			
		d.blurUniform = blurScaleUniform
		d.blurUniform.set(d.scale)
	
	[ p.visible(True) for p in d.passes ]
	viz.MainScene.visible(0,viz.WORLD)
	
def disable():
	"""Disable fullscreen blurring"""
	if d.created:
		[ p.visible(False) for p in d.passes ]
	viz.MainScene.visible(1,viz.WORLD)
	


viz.add('gallery.ive')

#Create render texture
renderTexture = viz.addRenderTexture()
	
#Create render node to render texture
renderNode = viz.addRenderNode()
renderNode.attachTexture(renderTexture)
renderNode.setInheritView(True) #False

#Create target for blur vision
target = viz.add( 'box.wrl' )
target.setScale(1,1,0.001)
target.setPosition(0,1,1)
target.color(1,1,1)
target.texture(enable())
Reply With Quote