def update(cls, task): # Reflection plane if settings.camera_at_origin: camera_offset = -cls.observer._local_position[2] + cls.z else: camera_offset = cls.z waterPlane = Plane(Vec3(0, 0, camera_offset + 1), Point3(0, 0, camera_offset)) # update matrix of the reflection camera if not settings.debug_lod_freeze and cls.watercamNP is not None: mc = base.camera.getMat() mf = waterPlane.getReflectionMat() cls.watercamNP.setMat(mc * mf) return task.cont
class WaterManager: def __init__(self): self.enabled = True sMgr = CIGlobals.getSettingsMgr() reso = sMgr.ReflectionQuality[sMgr.getSetting("refl").getValue()] if reso == 0: self.enabled = False return self.waterPlaneNP = None self.waterNodes = [] # Buffer and reflection camera buffer = base.win.makeTextureBuffer('waterBuffer', reso, reso) buffer.setClearColor(Vec4(0, 0, 0, 1)) cfa = CullFaceAttrib.makeReverse() rs = RenderState.make(cfa) self.watercamNP = base.makeCamera(buffer) self.watercamNP.reparentTo(render) self.makePlane(0.0) cam = self.watercamNP.node() cam.getLens().setFov(base.camLens.getFov()) cam.getLens().setNear(1) cam.getLens().setFar(5000) cam.setInitialState(rs) cam.setTagStateKey('Clipped') self.ts0 = TextureStage("tex_0") self.tex0 = buffer.getTexture() self.tex0.setWrapU(Texture.WMClamp) self.tex0.setWrapV(Texture.WMClamp) self.ts1 = TextureStage("tex_1") self.waterTex = loader.loadTexture('phase_3/maps/water_distort.png') self.waterQuad = None self.waterStage = TextureStage("waterStage") image0 = OnscreenImage(image=self.tex0, scale=0.3, pos=(-0.5, 0, 0.7)) image1 = OnscreenImage(image=waterTex, scale=0.3, pos=(0.5, 0, 0.7)) taskMgr.add(self.update, "waterTask") def makePlane(self, height): if not self.enabled: return self.clearPlane() # Reflection plane self.waterPlane = Plane(Vec3(0, 0, height), Point3(0, 0, height)) planeNode = PlaneNode('waterPlane') planeNode.setPlane(self.waterPlane) self.waterPlaneNP = render.attachNewNode(planeNode) def clearPlane(self): if not self.enabled: return if self.waterPlaneNP: self.waterPlaneNP.removeNode() self.waterPlaneNP = None def addWaterNode(self, node, height): if not self.enabled: return self.waterNodes.append(node) node.setTransparency(TransparencyAttrib.MAlpha) node.setTexture(ts0, self.tex0) node.setTexture(ts1, self.waterTex) node.setShaderInput('wateranim', Vec4(0.03, -0.015, 64.0, 0)) # vx, vy, scale, skip # offset, strength, refraction factor (0=perfect mirror, 1=total refraction), refractivity node.setShaderInput('waterdistort', Vec4(0.4, 4.0, 0.25, 0.45)) node.setShaderInput('time', 0) node.setShader(loader.loadShader("phase_3/models/shaders/water.sha")) node.projectTexture(self.waterStage, self.tex0, self.watercamNP) self.makePlane(height) def clearWaterNodes(self): if not self.enabled: return for node in self.waterNodes: if not node.isEmpty(): node.setShaderOff(1) node.setTextureOff(1) self.waterNodes = [] self.clearPlane() def update(self, task): if not self.enabled: return # update matrix of the reflection camera mc = base.camera.getMat() mf = self.waterPlane.getReflectionMat() self.watercamNP.setMat(mc * mf) for node in self.waterNodes: if not node.isEmpty(): node.setShaderInput("time", task.time) return task.cont
class WaterNode(): watercamNP = None buffer = None def __init__(self, x1, y1, x2, y2, z, scale, parent): # Water surface maker = CardMaker('water') maker.setFrame(x1, x2, y1, y2) self.waterNP = parent.instance.attachNewNode(maker.generate()) self.waterNP.setHpr(0, -90, 0) self.waterNP.setPos(0, 0, z) self.waterNP.setTransparency(TransparencyAttrib.MAlpha) self.waterNP.setShader( Shader.load( Shader.SL_GLSL, vertex=defaultDirContext.find_shader('water-vertex.glsl'), fragment=defaultDirContext.find_shader('water-fragment.glsl'))) self.waterNP.setShaderInput('wateranim', Vec4(0.03, -0.015, scale, 0)) # vx, vy, scale, skip # offset, strength, refraction factor (0=perfect mirror, 1=total refraction), refractivity self.waterNP.setShaderInput('waterdistort', Vec4(0.4, 4.0, 0.25, 0.45)) self.waterNP.setShaderInput('time', 0) # Reflection plane self.waterPlane = Plane(Vec3(0, 0, z + 1), Point3(0, 0, z)) planeNode = PlaneNode('waterPlane') planeNode.setPlane(self.waterPlane) if self.watercamNP is None: # Buffer and reflection camera WaterNode.buffer = base.win.makeTextureBuffer( 'waterBuffer', 512, 512) self.buffer.setClearColor(Vec4(0, 0, 0, 1)) cfa = CullFaceAttrib.makeReverse() rs = RenderState.make(cfa) WaterNode.watercamNP = base.makeCamera(self.buffer) self.watercamNP.reparentTo(render) #sa = ShaderAttrib.make() #sa = sa.setShader(loader.loadShader('shaders/splut3Clipped.sha') ) cam = self.watercamNP.node() cam.getLens().setFov(base.camLens.getFov()) cam.getLens().setNear(1) cam.getLens().setFar(5000) cam.setInitialState(rs) cam.setTagStateKey('Clipped') #cam.setTagState('True', RenderState.make(sa)) # ---- water textures --------------------------------------------- # reflection texture, created in realtime by the 'water camera' tex0 = self.buffer.getTexture() tex0.setWrapU(Texture.WMClamp) tex0.setWrapV(Texture.WMClamp) ts0 = TextureStage('reflection') self.waterNP.setTexture(ts0, tex0) # distortion texture tex1 = loader.loadTexture('textures/water.png') ts1 = TextureStage('distortion') self.waterNP.setTexture(ts1, tex1) self.task = taskMgr.add(self.update, "waterTask") def update(self, task): # update matrix of the reflection camera mc = base.camera.getMat() mf = self.waterPlane.getReflectionMat() self.watercamNP.setMat(mc * mf) self.waterNP.setShaderInput('time', task.time) #self.waterNP.setX(base.cam.getX()) #self.waterNP.setY(base.cam.getY()) return task.cont def remove_instance(self): if self.waterNP: self.waterNP.removeNode() self.waterNP = None # if self.watercamNP: # self.watercamNP.removeNode() # self.watercamNP = None # if self.buffer: # self.buffer.set_active(False) # base.graphicsEngine.removeWindow(self.buffer) # self.buffer = None if self.task: taskMgr.remove(self.task) self.task = None
class Water: """Represents a water surface""" def __init__(self,manager,xml): self.surface = getWaterSurface(manager) self.surface.reparentTo(render) self.surface.hide(BitMask32.bit(1)) # Invisible to reflection camera (speedup) self.surface.hide(BitMask32.bit(2)) # Invisible to volumetric lighting camera (speedup) self.surface.hide(BitMask32.bit(3)) # Invisible to shadow cameras (speedup) self.surface.setShader(loader.loadShader(manager.get('paths').getConfig().find('shaders').get('path')+'/water.cg')) self.surface.setShaderInput('time', 0.0, 0.0, 0.0, 0.0) ntex = loader.loadTexture(manager.get('paths').getConfig().find('textures').get('path')+'/water-normal.png') ntex.setMinfilter(Texture.FTLinearMipmapLinear) self.surface.setShaderInput('normal', ntex) self.surface.setShaderInput('camera', base.cam) self.surface.setTransparency(TransparencyAttrib.MDual, 10) self.surface.setTwoSided(True) self.surface.setShaderInput('waveInfo', Vec4(0.4, 0.4, 0.4, 0)) self.surface.setShaderInput('param2', Vec4(-0.015,0.005, 0.05, 0.05)) self.surface.setShaderInput('param3', Vec4(0.7, 0.3, 0, 0)) self.surface.setShaderInput('param4', Vec4(2.0, 0.5, 0.5, 0.0)) #self.surface.setShaderInput('speed', Vec4(-.8, -.4, -.9, .3)) self.surface.setShaderInput('speed', Vec4(0.2, -1.2, -0.2, -0.7)) self.surface.setShaderInput('deepcolor', Vec4(0.0,0.3,0.5,1.0)) self.surface.setShaderInput('shallowcolor', Vec4(0.0,1.0,1.0,1.0)) self.surface.setShaderInput('reflectioncolor', Vec4(0.95,1.0,1.0,1.0)) self.surface.hide() self.wbuffer = base.win.makeTextureBuffer('water', 512, 512) self.wbuffer.setClearColorActive(True) self.wbuffer.setClearColor(base.win.getClearColor()) self.wcamera = base.makeCamera(self.wbuffer) if manager.get('sky') != None and manager.get('sky').model != None: self.sky = manager.get('sky').model.copyTo(self.wcamera) self.sky.setTwoSided(True) self.sky.setSz(self.sky, -1) self.sky.setClipPlaneOff(1) self.sky.show() self.sky.hide(BitMask32.bit(0)) # Hide for normal camera self.sky.hide(BitMask32.bit(2)) # Hide for volumetric lighting camera self.sky.hide(BitMask32.bit(3)) # Hide for shadow camera(s), if any else: self.sky = None self.wcamera.reparentTo(render) self.wcamera.node().setLens(base.camLens) self.wcamera.node().setCameraMask(BitMask32.bit(1)) self.surface.hide(BitMask32.bit(1)) wtexture = self.wbuffer.getTexture() wtexture.setWrapU(Texture.WMClamp) wtexture.setWrapV(Texture.WMClamp) wtexture.setMinfilter(Texture.FTLinearMipmapLinear) self.surface.setShaderInput('reflection', wtexture) self.wplane = Plane(Vec3(0, 0, 1), Point3(0, 0, 0)) self.wplanenp = render.attachNewNode(PlaneNode('water', self.wplane)) tmpnp = NodePath('StateInitializer') tmpnp.setClipPlane(self.wplanenp) tmpnp.setAttrib(CullFaceAttrib.makeReverse()) self.wcamera.node().setInitialState(tmpnp.getState()) #self.fog = Fog('UnderwaterFog') #self.fog.setColor(0.0,0.3,0.5) self.fogEnabled = False def start(self): self.updateTask = taskMgr.add(self.update, 'water-update') self.surface.show() def stop(self): self.surface.hide() taskMgr.remove(self.updateTask) def update(self, task): if base.cam.getX(render) < 0.0 and not self.fogEnabled: self.fogEnabled = True elif base.cam.getX(render) > 0.0 and self.fogEnabled: self.fogEnabled = False self.surface.setX(render, base.cam.getX(render)) self.surface.setY(render, base.cam.getY(render)) self.wcamera.setMat(base.cam.getMat(render) * self.wplane.getReflectionMat()) self.surface.setShaderInput('time', task.time, 0.0, 0, 0) return task.cont