PDA

View Full Version : How to apply shader and render texture to an object


whj
04-23-2010, 12:23 PM
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,


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())