WorldViz User Forum  

Go Back   WorldViz User Forum > Vizard

Reply
 
Thread Tools Rating: Thread Rating: 11 votes, 5.00 average. Display Modes
  #1  
Old 02-17-2011, 03:37 AM
chris_user chris_user is offline
Member
 
Join Date: Feb 2011
Posts: 20
shadows in mirror

one more problem...

in the attached sample I have the problem that the shadow just appears in the mirror, but no longer on the original object; if mirroring is deactivated it looks like it should, has anybody a clue for me whats going wrong?


object loading and running the scene:

Code:
import viz
import projector
import vizspace

viz.go()

viz.MainView.move([-6,2,0])
viz.MainView.setEuler([90,20,0])


###SPACENAVIGATOR###
def spacemove(e):
    viz.MainView.move(viz.Vector(e.pos)*e.elapsed)
viz.callback(vizspace.TRANSLATE_EVENT,spacemove)

def spacerot(e):
    viz.MainView.setAxisAngle(1,0,0,e.ori[0]*e.elapsed,viz.HEAD_ORI,viz.REL_LOCAL)
    viz.MainView.setAxisAngle(0,1,0,e.ori[1]*e.elapsed,viz.HEAD_ORI,viz.REL_LOCAL)
    viz.MainView.setAxisAngle(0,0,1,e.ori[2]*e.elapsed,viz.HEAD_ORI,viz.REL_LOCAL)
viz.callback(vizspace.ROTATE_EVENT,spacerot)

def spacebuttondown(button):
    print 'Button',button,'pressed'
viz.callback(vizspace.BUTTONDOWN_EVENT,spacebuttondown)

def spacebuttonup(button):
    print 'Button',button,'released'
viz.callback(vizspace.BUTTONUP_EVENT,spacebuttonup)


###OBJECTS###
plane = viz.addTexQuad()
plane.setScale(3,3,3)
plane.setEuler(0,90,90)

ball = viz.add('white_ball.wrl')
ball.setPosition(0,1,0)

ground = viz.add('tut_ground.wrl')
ground.setPosition(0,-.1,0)

###MIRROR###
def addMirror(mirror,mat=None):

	#If mirror matrix is not specifed, get matrix of mirror object
	if mat is None:
		mat = mirror.getMatrix()
		
	#Position of mirror
	pos = viz.Vector(mat.getPosition())
	
	#Direction mirror is pointing
	dir = viz.Vector(mat.getForward())
	dir.normalize()

	#Quaternion rotation of mirrorw
	quat = mat.getQuat()
	
	#Create render texture
	tex = viz.addRenderTexture()
	
	#Create render node for rendering reflection
	lens = viz.addRenderNode(size=[1024,1024])
	lens.attachTexture(tex)
	lens.setInheritView(True,viz.POST_MULT)
	lens.disable(viz.CULL_FACE,op=viz.OP_SET_OVERRIDE)

	#Setup reflection matrix
	rot = viz.Matrix.quat(quat)
	invRot = rot.inverse()
	lens.setMatrix(viz.Matrix.translate(pos*-1.0)*invRot*viz.Matrix.scale(1,1,-1)*rot*viz.Matrix.translate(pos))
	
	#Setup reflection clip plane
	plane = vizmat.Plane(pos=pos,normal=dir)
	dist = plane.distance([0,0,0])
	lens.clipPlane([-dir[0],-dir[1],-dir[2],dist+0.001])

	#Project reflection texture onto mirror
	mirror.texture(tex)
	mirror.texGen(viz.TEXGEN_PROJECT_EYE)


#Use existing painting as mirror and specify the matrix
mirrorsurface = viz.addTexQuad()
mirrorsurface.scale(6.5,3,.1)
mirrorsurface.setPosition([3.66, 1, 0]) #Y,Z,X
#mirrorsurface.alpha(0.1)
mirrorsurface.appearance(viz.TEXMODULATE)
mirrorsurfacerotation = [90,0,0] #rotation around the Z,Y,X axes
mirrorsurface.rotate(mirrorsurfacerotation)
m = viz.Matrix()
m.setPosition(mirrorsurface.getPosition(viz.ABS_GLOBAL))
m.setEuler(mirrorsurfacerotation[0]-180,-mirrorsurfacerotation[1], mirrorsurfacerotation[2]) #Z,X,Y

#Apply mirror settings to mirror object
addMirror(mirrorsurface,m)

#Increase ambient lighting
#viz.MainView.getHeadLight().ambient(.7,.7,.7)

###SHADOW###
#Shadow resolution (power of two)
#Higher values mean sharper shadows, but take more texture memory
SHADOW_RES = 512

#Postion of shadow projector
SHADOW_POS = [0,2,0]

#Controls size of orthographic shadow projector
#Large values mean larger area is covered, but resolution will be diluted
SHADOW_AREA = [10,10]

#Create shadow projector
import Shadow
shadow = Shadow.ShadowProjector(size=SHADOW_RES,pos=SHADOW_POS,area=SHADOW_AREA)

#Add avatar as a shadow caster
shadow.addCaster(ball)

#Add ground as shadow receiver
shadow.addReceiver(plane)
Shadow.py
Code:
import viz
import projector

class ShadowProjector(object):
	def __init__(self,kernel=9,alpha=1,size=256,pos=(0,10,0),euler=(0,90,0),area=[5,5],scene=viz.MainScene):
		
		#Create render texture
		self.shadowTex = viz.addRenderTexture(wrap=viz.CLAMP_TO_BORDER,borderColor=viz.WHITE)
		
		#Create render node to render shadow caster to texture
		self.shadowPass = viz.addRenderNode(scene=scene,size=[size,size],inheritView=False,autoClip=False)
		self.shadowPass.setClearColor(viz.WHITE)
		self.shadowPass.attachTexture(self.shadowTex)
		self.shadowPass.setScene(None)
		
		#Apply shader to render node so everything is black
		code = """
		#define I	%alpha%
		void main()
		{
			gl_FragColor = vec4(I,I,I,1.0);
		}
		"""
		shader = viz.addShader(frag=code.replace('%alpha%',str(1.0-alpha)))
		self.shadowPass.apply(shader,op=viz.OP_SET_OVERRIDE)
		
		#Create projector for projecting shadow texture onto receivers
		self.texProj = projector.add(self.shadowTex,scene=scene,cubemap=False)
		
		#Save all render node passes
		self.passes = [self.shadowPass]
		
		#Setup render nodes to blur shadow texture
		if kernel:
			blur_source = """
			uniform sampler2D srcImage;
			void main(void)
			{
				vec4 color = vec4(0,0,0,0);
				%code%
				color.a = 1.0;
				gl_FragColor = color;
			}"""
			horz_source = 'color += texture2D( srcImage, gl_TexCoord[0].xy + vec2( %f, 0.0 ) ) * %f;'
			vert_source = 'color += texture2D( srcImage, gl_TexCoord[0].xy + vec2( 0.0, %f ) ) * %f;'
			
			#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
			frac = 1.0 / sum(weights)
			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(horz_source%(o,w))
				vert_blur_code.append(vert_source%(o,w))
			
			#Create shaders
			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)))
			srcImageUniform = viz.addUniformInt('srcImage',0)
			
			#Render texture for ping-ponging
			tex2 = viz.addRenderTexture()
			
			"""
			Pass 2 renders the shadow texture onto a quad.
			The quad has a shader attached which blurs the texture horizontally.
			"""
			self.blurPass1 = viz.addRenderNode(scene=scene)
			self.blurPass1.setHUD(0,200,0,200,renderQuad=True)
			self.blurPass1.setSize(size,size)
			self.blurPass1.setBuffer(viz.RENDER_FBO)
			self.blurPass1.setOrder(viz.PRE_RENDER,1)
			self.blurPass1.attachTexture(tex2)
			self.blurPass1.texture(self.shadowTex)
			self.blurPass1.apply(horzBlurShader)
			self.blurPass1.apply(srcImageUniform)
			self.passes.append(self.blurPass1)
			
			"""
			Pass 3 renders the texture from pass 2 onto a quad.
			The quad has a shader attached which blurs the texture vertically.
			"""
			self.blurPass2 = viz.addRenderNode(scene=scene)
			self.blurPass2.setHUD(0,200,0,200,renderQuad=True)
			self.blurPass2.setSize(size,size)
			self.blurPass2.setBuffer(viz.RENDER_FBO)
			self.blurPass2.setOrder(viz.PRE_RENDER,2)
			self.blurPass2.attachTexture(self.shadowTex)
			self.blurPass2.texture(tex2)
			self.blurPass2.apply(vertBlurShader)
			self.blurPass2.apply(srcImageUniform)
			self.passes.append(self.blurPass2)
			
			#Remove texture/shader/uniforms (already applied)
			horzBlurShader.remove()
			vertBlurShader.remove()
			srcImageUniform.remove()
			tex2.remove()

		#Initialize shadow area/pos/euler
		self.setArea(area)
		self.setPosition(pos)
		self.setEuler(euler)
		
	def addCaster(self,node):
		"""Add a shadow caster node"""
		node.duplicate(viz.MainScene,self.shadowPass)
		
	def addReceiver(self,node,unit=1):
		"""Add a shadow receiver node"""
		self.texProj.affect(node,unit)
		
	def setPosition(self,pos):
		"""Set position of shadow projector"""
		self.shadowPass.setPosition(pos)
		self.texProj.setPosition(pos)
		
	def setEuler(self,euler):
		"""Set euler of shadow projector"""
		self.shadowPass.setEuler(euler)
		self.texProj.setEuler(euler)

	def setArea(self,area):
		"""Set [width,height] area of orthographic projection of shadow"""
		proj = viz.Matrix.ortho(-area[0]/2.0,area[0]/2.0,-area[1]/2.0,area[1]/2.0,0.1,1000)
		self.shadowPass.setProjectionMatrix(proj)
		self.texProj.ortho(area[0],area[1])
		
	def visible(self,mode):
		"""Enable shadow projector"""
		for p in self.passes:
			p.visible(mode)
		self.texProj.visible(mode)
	
	def remove(self):
		"""Permanently remove all resources"""
		for p in self.passes:
			p.remove(False)
		self.shadowTex.remove()
		self.texProj.remove()
thanks in advance
Reply With Quote
Reply

Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Realistic Light and Shadows Using Vizard and 3DS Max jde Vizard 4 07-13-2012 10:58 AM
Problem using mirror dan12345 Vizard 3 07-28-2008 04:48 AM
Eyes that keep looking at the mirror Frank Verberne Vizard 3 05-13-2008 05:39 AM
Mirror issues Frank Verberne Vizard 2 04-08-2008 10:37 AM
Getting a mirror to work in any environment Frank Verberne Vizard 5 03-27-2008 08:21 AM


All times are GMT -7. The time now is 07:45 AM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Copyright 2002-2018 WorldViz LLC