def __init__(self): ShowBase.__init__(self) cm = CardMaker("cm") cm.setFrame(Point3(-1, -1, -1), Point3(1, -1, -1), Point3(1, 1, -1), Point3(-1, 1, -1)) model = self.hidden.attachNewNode(cm.generate()) model.setScale(0.1) #self.disableMouse() base.setFrameRateMeter(True) self.n = 100 self.data = gen(self.n) self.zvezde = self.render.attachNewNode("zvezde") model.reparentTo(self.zvezde) model.setTexture(self.loader.loadTexture("explosion1.png")) self.zvezde.setPosHpr(0, 70, 0, 0, 90, 0) self.zvezde.setInstanceCount(self.n) myShader = Shader.load(Shader.SLGLSL, "vertex.glsl", "fragment.glsl") self.zvezde.setShader(myShader) #Shader.load('instance.cg')) self.render.setShaderAuto() self.offsets = PTA_LVecBase4f.emptyArray(self.n) self.accept("r", self.reset) self.zvezde.setShaderInput('shader_data', self.offsets) self.zvezde.setShaderInput('shader_data[0]', self.offsets) #self.taskMgr.setupTaskChain('threaded chain', numThreads = 0, frameBudget = -1,frameSync = 1) self.taskMgr.add(self.update, "update") #,taskChain = 'threaded chain')
def setupGlowFilter(self): #create the shader that will determime what parts of the scene will glow glowShader=Shader.load(self.pandapath + "/data/glowShader.sha") # create the glow buffer. This buffer renders like a normal scene, # except that only the glowing materials should show up nonblack. glowBuffer=base.win.makeTextureBuffer("Glow scene", 512, 512) glowBuffer.setSort(-3) glowBuffer.setClearColor(Vec4(0,0,0,1)) # We have to attach a camera to the glow buffer. The glow camera # must have the same frustum as the main camera. As long as the aspect # ratios match, the rest will take care of itself. self.glowCamera=base.makeCamera(glowBuffer, lens=base.cam.node().getLens()) # Tell the glow camera to use the glow shader tempnode = NodePath(PandaNode("temp node")) tempnode.setShader(glowShader) self.glowCamera.node().setInitialState(tempnode.getState()) # set up the pipeline: from glow scene to blur x to blur y to main window. blurXBuffer=self.makeFilterBuffer(glowBuffer, "Blur X", -2, self.pandapath+"/data/XBlurShader.sha") blurYBuffer=self.makeFilterBuffer(blurXBuffer, "Blur Y", -1, self.pandapath+"/data/YBlurShader.sha") self.finalcard = blurYBuffer.getTextureCard() self.finalcard.reparentTo(render2d) self.finalcard.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd)) render.setShaderInput('glow', Vec4(0,0,0,0),0) render.analyze()
def __init__(self, parent, star, **kwargs): super(StarView, self).__init__(parent, star, **kwargs) if not StarView.ready: StarView.setup(self.base.loader) self.seed = random.random() self.node = NodePath('star') plight = PointLight("starlight") self.light = self.node.attachNewNode(plight) self.light.setColor(self.obj.color) self.model = self.light.attachNewNode(SphereNode(subdivides=4)) self.model.setShader(Shader.load("shader/star.cg")) self.cloudtime = 0.0 #self.seed = hash("fish") self.param_set = ParamSet(self.seed) min_scale = Vec4(0.5, 0.5, 0.5, 0.5) max_scale = Vec4(1, 1, 1, 1) max_radius = StellarClass.highest_radius min_radius = StellarClass.lowest_radius radius_factor = log(self.obj.radius*(1/min_radius), 100) / log(max_radius*(1/min_radius), 100) self.param_set.vectors['scale'] = min_scale + (max_scale-min_scale)*radius_factor self.compute_seed_param() for stage, tex in StarView.texture_set: self.model.setTexture(stage, tex) self.speed = 0.00000001 self.setup_shader_inputs() self.node.setScale(1/self.node.getBounds().getRadius()) self.node.reparentTo(self.parent.node)
def make_filter_buffer (srcbuffer, name, sort, prog): blur_buffer = base.win.makeTextureBuffer (name, 512, 512) blur_buffer.setSort (sort) blur_buffer.setClearColor (Vec4 (1, 0, 0, 1)) blur_camera = base.makeCamera2d (blur_buffer) blur_scene = NodePath ("filter_scene") blur_camera.node ().setScene (blur_scene) shader = Shader.load (prog) card = srcbuffer.getTextureCard () card.reparentTo (blur_scene) card.setShader (shader) return blur_buffer
def render(self): LOG.debug("[SkyBox] Rendering") # If we are an orphan use render if self.parent is None: self.parent = render #LOG.debug("[SkyBox] model=%s"%self.modelFile) self.node = loader.loadModel(self.modelFile) #print("tf1 = %s, tf2 = %s"%(self.texture1File,self.texture2File)) if self.texture1File != '' and self.texture2File == '': #LOG.debug("[SkyBox] single texture = %s"%self.texture1File) t = loader.loadTexture(self.texture1File) self.node.setTexture(t) elif self.texture1File != '' and self.texture2File != '': #LOG.debug("[SkyBox] texture staging 1 = %s, 2 = %s"%(self.texture1File,self.texture2File)) t1 = loader.loadTexture(self.texture1File) t1.setWrapU(Texture.WMClamp) t1.setWrapV(Texture.WMClamp) ts1 = TextureStage('Space') ts1.setSort(self.texture1Sort) t2 = loader.loadTexture(self.texture2File) t2.setWrapU(Texture.WMClamp) t2.setWrapV(Texture.WMClamp) ts2 = TextureStage('SpaceClouds') ts2.setSort(self.texture2Sort) self.node.setTexture(ts1, t1) self.node.setTexture(ts2, t2) if self.shaderFile: LOG.debug("[SkyBox] shader = %s"%self.shaderFile) #skyShader = Shader.load("./data/shaders/%s"%self.shaderFile) skyShader = Shader.load("%s"%self.shaderFile) self.node.setShader(skyShader) # Should this be scaled here or done to the model? # It doesn't look like scaling the objects looks any different. self.node.setScale(280) # make sure it's drawn first (this can be done with shaders?) self.node.setBin('background', 0) # dont set depth attribute when rendering the sky (this can be done with shaders?) self.node.setAttrib(DepthWriteAttrib.make(DepthWriteAttrib.MOff)) # We don't want shadows on the skybox self.node.setLightOff() # Render self.node.reparentTo(self.parent) taskMgr.add(self.moveSkyTask, "Move the sky box with the cam")
def render(self): LOG.debug("[SkyBox] Rendering") # If we are an orphan use render if self.parent is None: self.parent = render #LOG.debug("[SkyBox] model=%s"%self.modelFile) self.node = loader.loadModel(self.modelFile) #print("tf1 = %s, tf2 = %s"%(self.texture1File,self.texture2File)) if self.texture1File != '' and self.texture2File == '': #LOG.debug("[SkyBox] single texture = %s"%self.texture1File) t = loader.loadTexture(self.texture1File) self.node.setTexture(t) elif self.texture1File != '' and self.texture2File != '': #LOG.debug("[SkyBox] texture staging 1 = %s, 2 = %s"%(self.texture1File,self.texture2File)) t1 = loader.loadTexture(self.texture1File) t1.setWrapU(Texture.WMClamp) t1.setWrapV(Texture.WMClamp) ts1 = TextureStage('Space') ts1.setSort(self.texture1Sort) t2 = loader.loadTexture(self.texture2File) t2.setWrapU(Texture.WMClamp) t2.setWrapV(Texture.WMClamp) ts2 = TextureStage('SpaceClouds') ts2.setSort(self.texture2Sort) self.node.setTexture(ts1, t1) self.node.setTexture(ts2, t2) if self.shaderFile: LOG.debug("[SkyBox] shader = %s" % self.shaderFile) #skyShader = Shader.load("./data/shaders/%s"%self.shaderFile) skyShader = Shader.load("%s" % self.shaderFile) self.node.setShader(skyShader) # Should this be scaled here or done to the model? # It doesn't look like scaling the objects looks any different. self.node.setScale(280) # make sure it's drawn first (this can be done with shaders?) self.node.setBin('background', 0) # dont set depth attribute when rendering the sky (this can be done with shaders?) self.node.setAttrib(DepthWriteAttrib.make(DepthWriteAttrib.MOff)) # We don't want shadows on the skybox self.node.setLightOff() # Render self.node.reparentTo(self.parent) taskMgr.add(self.moveSkyTask, "Move the sky box with the cam")
def makeFilterBuffer(self, srcbuffer, name, sort, prog): blurBuffer=base.win.makeTextureBuffer(name, 512, 512) blurBuffer.setSort(sort) blurBuffer.setClearColor(Vec4(1,0,0,1)) blurCamera=base.makeCamera2d(blurBuffer) blurScene=NodePath("new Scene") blurCamera.node().setScene(blurScene) shader = Shader.load(prog) card = srcbuffer.getTextureCard() card.reparentTo(blurScene) card.setShader(shader) return blurBuffer
def __init__(self, parent, planet, **kwargs): super(PlanetView, self).__init__(parent, planet, **kwargs) if not PlanetView.ready: PlanetView.setup(self.base.loader) self.node = NodePath(SphereNode(subdivides=4)) self.node.setShader(Shader.load("shader/planet.cg")) self.cloudtime = 0.0 self.seed = hash("fish") self.param_set = ParamSet(self.seed) self.compute_seed_param() for stage, tex in PlanetView.texture_sets['terrestrial_big']: self.node.setTexture(stage, tex) self.setup_shader_inputs() self.node.setScale(1/self.node.getBounds().getRadius()) self.node.reparentTo(self.parent.node)
def __init__(self, parent, planet, **kwargs): super(PlanetView, self).__init__(parent, planet, **kwargs) if not PlanetView.ready: PlanetView.setup(self.base.loader) self.node = NodePath(SphereNode(subdivides=4)) self.node.setShader(Shader.load("shader/planet.cg")) self.cloudtime = 0.0 self.seed = hash("fish") self.param_set = ParamSet(self.seed) self.compute_seed_param() for stage, tex in PlanetView.texture_sets['terrestrial_big']: self.node.setTexture(stage, tex) self.setup_shader_inputs() self.node.setScale(1 / self.node.getBounds().getRadius()) self.node.reparentTo(self.parent.node)
def make_shadow_shader (showas=False): shdkey = () ret = _shadow_shader_cache.get(shdkey) if ret is not None: shader = ret return shader vshstr = GLSL_PROLOGUE vshstr += """ uniform mat4 p3d_ModelViewProjectionMatrix; in vec4 p3d_Vertex; out vec4 m_vertpos; void main () { gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex; m_vertpos = gl_Position; } """ fshstr = GLSL_PROLOGUE ret = make_frag_outputs(wcolor=True) odeclstr, ocolorn = ret fshstr += """ in vec4 m_vertpos; """ fshstr += odeclstr fshstr += """ void main () { float d = (m_vertpos.z / m_vertpos.w) * 0.5 + 0.5; %(ocolorn)s = vec4(d, d, d, 1.0); } """ % locals() if showas: printsh((vshstr, fshstr), showas) shader = Shader.make(Shader.SLGLSL, vshstr, fshstr) _shadow_shader_cache[shdkey] = shader return shader
def make_glow(self, data_dir='./src/core/sha'): """ TODO: data_dir = current module directory? """ glow_shader = Shader.load(data_dir + "/glow_shader.sha") # create the glow buffer. This buffer renders like a normal # scene, except that only the glowing materials should show up # nonblack. glow_buffer = base.win.makeTextureBuffer("glow_scene", 512, 512) glow_buffer.setSort(-3) glow_buffer.setClearColor(Vec4(0, 0, 0, 1)) # We have to attach a camera to the glow buffer. The glow # camera must have the same frustum as the main camera. As # long as the aspect ratios match, the rest will take care of # itself. glow_camera = base.makeCamera(glow_buffer, lens=base.cam.node().getLens()) # Tell the glow camera to use the glow shader temp_node = NodePath(PandaNode("temp_node")) temp_node.setShader(glow_shader) glow_camera.node().setInitialState(temp_node.getState()) # set up the pipeline: from glow scene to blur x to blur y to # main window. blur_xbuffer = make_filter_buffer(glow_buffer, "blur_x", -2, data_dir + "/x_blur_shader.sha") blur_ybuffer = make_filter_buffer(blur_xbuffer, "blur_y", -1, data_dir + "/y_blur_shader.sha") final_card = blur_ybuffer.getTextureCard() final_card.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd)) self.glow_camera = glow_camera self.glow_buffer = glow_buffer self.blur_xbuffer = blur_xbuffer self.blur_ybuffer = blur_ybuffer self.final_card = final_card
def make_glow (self, data_dir = './src/core/sha'): """ TODO: data_dir = current module directory? """ glow_shader = Shader.load (data_dir + "/glow_shader.sha") # create the glow buffer. This buffer renders like a normal # scene, except that only the glowing materials should show up # nonblack. glow_buffer = base.win.makeTextureBuffer ("glow_scene", 512, 512) glow_buffer.setSort (-3) glow_buffer.setClearColor (Vec4 (0, 0, 0, 1)) # We have to attach a camera to the glow buffer. The glow # camera must have the same frustum as the main camera. As # long as the aspect ratios match, the rest will take care of # itself. glow_camera = base.makeCamera (glow_buffer, lens = base.cam.node ().getLens ()) # Tell the glow camera to use the glow shader temp_node = NodePath (PandaNode("temp_node")) temp_node.setShader (glow_shader) glow_camera.node ().setInitialState (temp_node.getState ()) # set up the pipeline: from glow scene to blur x to blur y to # main window. blur_xbuffer = make_filter_buffer (glow_buffer, "blur_x", -2, data_dir + "/x_blur_shader.sha") blur_ybuffer = make_filter_buffer (blur_xbuffer, "blur_y", -1, data_dir + "/y_blur_shader.sha") final_card = blur_ybuffer.getTextureCard () final_card.setAttrib (ColorBlendAttrib.make (ColorBlendAttrib.MAdd)) self.glow_camera = glow_camera self.glow_buffer = glow_buffer self.blur_xbuffer = blur_xbuffer self.blur_ybuffer = blur_ybuffer self.final_card = final_card
def __init__(self, parent, star, **kwargs): super(StarView, self).__init__(parent, star, **kwargs) if not StarView.ready: StarView.setup(self.base.loader) self.seed = random.random() self.node = NodePath('star') plight = PointLight("starlight") self.light = self.node.attachNewNode(plight) self.light.setColor(self.obj.color) self.model = self.light.attachNewNode(SphereNode(subdivides=4)) self.model.setShader(Shader.load("shader/star.cg")) self.cloudtime = 0.0 #self.seed = hash("fish") self.param_set = ParamSet(self.seed) min_scale = Vec4(0.5, 0.5, 0.5, 0.5) max_scale = Vec4(1, 1, 1, 1) max_radius = StellarClass.highest_radius min_radius = StellarClass.lowest_radius radius_factor = log(self.obj.radius * (1 / min_radius), 100) / log( max_radius * (1 / min_radius), 100) self.param_set.vectors['scale'] = min_scale + ( max_scale - min_scale) * radius_factor self.compute_seed_param() for stage, tex in StarView.texture_set: self.model.setTexture(stage, tex) self.speed = 0.00000001 self.setup_shader_inputs() self.node.setScale(1 / self.node.getBounds().getRadius()) self.node.reparentTo(self.parent.node)
def reconfigure(self, fullrebuild, changed): """ Reconfigure is called whenever any configuration change is made. """ configuration = self.configuration if (fullrebuild): self.cleanup() if (len(configuration) == 0): return auxbits = 0 needtex = {} needtex["color"] = True if (configuration.has_key("CartoonInk")): needtex["aux"] = True auxbits |= AuxBitplaneAttrib.ABOAuxNormal if (configuration.has_key("AmbientOcclusion")): needtex["depth"] = True needtex["ssao0"] = True needtex["ssao1"] = True needtex["ssao2"] = True needtex["aux"] = True auxbits |= AuxBitplaneAttrib.ABOAuxNormal if (configuration.has_key("BlurSharpen")): needtex["blur0"] = True needtex["blur1"] = True if (configuration.has_key("Bloom")): needtex["bloom0"] = True needtex["bloom1"] = True needtex["bloom2"] = True needtex["bloom3"] = True auxbits |= AuxBitplaneAttrib.ABOGlow if (configuration.has_key("ViewGlow")): auxbits |= AuxBitplaneAttrib.ABOGlow for tex in needtex: self.textures[tex] = Texture("scene-" + tex) self.textures[tex].setWrapU(Texture.WMClamp) self.textures[tex].setWrapV(Texture.WMClamp) needtexpix = True self.finalQuad = self.manager.renderSceneInto( textures=self.textures, auxbits=auxbits) if (self.finalQuad == None): self.cleanup() return False if (configuration.has_key("BlurSharpen")): blur0 = self.textures["blur0"] blur1 = self.textures["blur1"] self.blur.append( self.manager.renderQuadInto(colortex=blur0, div=2)) self.blur.append(self.manager.renderQuadInto(colortex=blur1)) self.blur[0].setShaderInput("src", self.textures["color"]) self.blur[0].setShader(self.loadShader("filter-blurx.sha")) self.blur[1].setShaderInput("src", blur0) self.blur[1].setShader(self.loadShader("filter-blury.sha")) if (configuration.has_key("AmbientOcclusion")): ssao0 = self.textures["ssao0"] ssao1 = self.textures["ssao1"] ssao2 = self.textures["ssao2"] self.ssao.append(self.manager.renderQuadInto(colortex=ssao0)) self.ssao.append( self.manager.renderQuadInto(colortex=ssao1, div=2)) self.ssao.append(self.manager.renderQuadInto(colortex=ssao2)) self.ssao[0].setShaderInput("depth", self.textures["depth"]) self.ssao[0].setShaderInput("normal", self.textures["aux"]) self.ssao[0].setShaderInput( "random", loader.loadTexture("maps/random.rgb")) self.ssao[0].setShader(self.loadShader("filter-ssao.sha")) self.ssao[1].setShaderInput("src", ssao0) self.ssao[1].setShader(self.loadShader("filter-blurx.sha")) self.ssao[2].setShaderInput("src", ssao1) self.ssao[2].setShader(self.loadShader("filter-blury.sha")) if (configuration.has_key("Bloom")): bloomconf = configuration["Bloom"] bloom0 = self.textures["bloom0"] bloom1 = self.textures["bloom1"] bloom2 = self.textures["bloom2"] bloom3 = self.textures["bloom3"] if (bloomconf.size == "large"): scale = 8 downsampler = "filter-down4.sha" elif (bloomconf.size == "medium"): scale = 4 downsampler = "filter-copy.sha" else: scale = 2 downsampler = "filter-copy.sha" self.bloom.append( self.manager.renderQuadInto(colortex=bloom0, div=2, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom1, div=scale, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom2, div=scale, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom3, div=scale, align=scale)) self.bloom[0].setShaderInput("src", self.textures["color"]) self.bloom[0].setShader(self.loadShader("filter-bloomi.sha")) self.bloom[1].setShaderInput("src", bloom0) self.bloom[1].setShader(self.loadShader(downsampler)) self.bloom[2].setShaderInput("src", bloom1) self.bloom[2].setShader(self.loadShader("filter-bloomx.sha")) self.bloom[3].setShaderInput("src", bloom2) self.bloom[3].setShader(self.loadShader("filter-bloomy.sha")) text = "//Cg\n" text += "void vshader(float4 vtx_position : POSITION,\n" text += " out float4 l_position : POSITION,\n" text += " uniform float4 texpad_txcolor,\n" text += " uniform float4 texpix_txcolor,\n" text += " out float4 l_texcoordC : TEXCOORD0,\n" if (configuration.has_key("CartoonInk")): text += " uniform float4 texpad_txaux,\n" text += " uniform float4 texpix_txaux,\n" text += " out float4 l_texcoordN : TEXCOORD1,\n" if (configuration.has_key("Bloom")): text += " uniform float4 texpad_txbloom3,\n" text += " out float4 l_texcoordB : TEXCOORD2,\n" if (configuration.has_key("BlurSharpen")): text += " uniform float4 texpad_txblur1,\n" text += " out float4 l_texcoordBS : TEXCOORD3,\n" if (configuration.has_key("AmbientOcclusion")): text += " uniform float4 texpad_txssao2,\n" text += " out float4 l_texcoordAO : TEXCOORD4,\n" text += " uniform float4x4 mat_modelproj)\n" text += "{\n" text += " l_position=mul(mat_modelproj, vtx_position);\n" text += " l_texcoordC=(vtx_position.xzxz * texpad_txcolor) + texpad_txcolor;\n" if (configuration.has_key("CartoonInk")): text += " l_texcoordN=(vtx_position.xzxz * texpad_txaux) + texpad_txaux;\n" if (configuration.has_key("Bloom")): text += " l_texcoordB=(vtx_position.xzxz * texpad_txbloom3) + texpad_txbloom3;\n" if (configuration.has_key("BlurSharpen")): text += " l_texcoordBS=(vtx_position.xzxz * texpad_txblur1) + texpad_txblur1;\n" if (configuration.has_key("AmbientOcclusion")): text += " l_texcoordAO=(vtx_position.xzxz * texpad_txssao2) + texpad_txssao2;\n" if (configuration.has_key("HalfPixelShift")): text += " l_texcoordC+=texpix_txcolor*0.5;\n" if (configuration.has_key("CartoonInk")): text += " l_texcoordN+=texpix_txaux*0.5;\n" text += "}\n" text += "void fshader(\n" text += "float4 l_texcoordC : TEXCOORD0,\n" text += "uniform float4 texpix_txcolor,\n" if (configuration.has_key("CartoonInk")): text += "float4 l_texcoordN : TEXCOORD1,\n" text += "uniform float4 texpix_txaux,\n" if (configuration.has_key("Bloom")): text += "float4 l_texcoordB : TEXCOORD2,\n" if (configuration.has_key("BlurSharpen")): text += "float4 l_texcoordBS : TEXCOORD3,\n" text += "uniform float4 k_blurval,\n" if (configuration.has_key("AmbientOcclusion")): text += "float4 l_texcoordAO : TEXCOORD4,\n" for key in self.textures: text += "uniform sampler2D k_tx" + key + ",\n" if (configuration.has_key("CartoonInk")): text += "uniform float4 k_cartoonseparation,\n" if (configuration.has_key("VolumetricLighting")): text += "uniform float4 k_casterpos,\n" text += "uniform float4 k_vlparams,\n" text += "out float4 o_color : COLOR)\n" text += "{\n" text += " o_color = tex2D(k_txcolor, l_texcoordC.xy);\n" if (configuration.has_key("CartoonInk")): text += CARTOON_BODY if (configuration.has_key("AmbientOcclusion")): text += "o_color *= tex2D(k_txssao2, l_texcoordAO.xy).r;\n" if (configuration.has_key("BlurSharpen")): text += " o_color = lerp(tex2D(k_txblur1, l_texcoordBS.xy), o_color, k_blurval.x);\n" if (configuration.has_key("Bloom")): text += "o_color = saturate(o_color);\n" text += "float4 bloom = 0.5*tex2D(k_txbloom3, l_texcoordB.xy);\n" text += "o_color = 1-((1-bloom)*(1-o_color));\n" if (configuration.has_key("ViewGlow")): text += "o_color.r = o_color.a;\n" if (configuration.has_key("VolumetricLighting")): text += "float decay = 1.0f;\n" text += "float2 curcoord = l_texcoordC.xy;\n" text += "float2 lightdir = curcoord - k_casterpos.xy;\n" text += "lightdir *= k_vlparams.x;\n" text += "half4 sample = tex2D(k_txcolor, curcoord);\n" text += "float3 vlcolor = sample.rgb * sample.a;\n" text += "for (int i = 0; i < %s; i++) {\n" % int( configuration["VolumetricLighting"].numsamples) text += " curcoord -= lightdir;\n" text += " sample = tex2D(k_txcolor, curcoord);\n" text += " sample *= sample.a * decay;//*weight\n" text += " vlcolor += sample.rgb;\n" text += " decay *= k_vlparams.y;\n" text += "}\n" text += "o_color += float4(vlcolor * k_vlparams.z, 1);\n" if (configuration.has_key("Inverted")): text += "o_color = float4(1, 1, 1, 1) - o_color;\n" text += "}\n" self.finalQuad.setShader(Shader.make(text)) for tex in self.textures: self.finalQuad.setShaderInput("tx" + tex, self.textures[tex]) self.task = taskMgr.add(self.update, "common-filters-update") if (changed == "CartoonInk") or fullrebuild: if (configuration.has_key("CartoonInk")): separation = configuration["CartoonInk"] self.finalQuad.setShaderInput( "cartoonseparation", Vec4(separation, 0, separation, 0)) if (changed == "BlurSharpen") or fullrebuild: if (configuration.has_key("BlurSharpen")): blurval = configuration["BlurSharpen"] self.finalQuad.setShaderInput( "blurval", Vec4(blurval, blurval, blurval, blurval)) if (changed == "Bloom") or fullrebuild: if (configuration.has_key("Bloom")): bloomconf = configuration["Bloom"] intensity = bloomconf.intensity * 3.0 self.bloom[0].setShaderInput("blend", bloomconf.blendx, bloomconf.blendy, bloomconf.blendz, bloomconf.blendw * 2.0) self.bloom[0].setShaderInput( "trigger", bloomconf.mintrigger, 1.0 / (bloomconf.maxtrigger - bloomconf.mintrigger), 0.0, 0.0) self.bloom[0].setShaderInput("desat", bloomconf.desat) self.bloom[3].setShaderInput("intensity", intensity, intensity, intensity, intensity) if (changed == "VolumetricLighting") or fullrebuild: if (configuration.has_key("VolumetricLighting")): config = configuration["VolumetricLighting"] tcparam = config.density / float(config.numsamples) self.finalQuad.setShaderInput("vlparams", tcparam, config.decay, config.exposure, 0.0) if (changed == "AmbientOcclusion") or fullrebuild: if (configuration.has_key("AmbientOcclusion")): config = configuration["AmbientOcclusion"] self.ssao[0].setShaderInput( "params1", config.numsamples, -float(config.amount) / config.numsamples, config.radius, 0) self.ssao[0].setShaderInput("params2", config.strength, config.falloff, 0, 0) self.update() return True
def __init__(self, manager, xml): self.updateTask = None self.sun = base.cam.attachNewNode('sun') loader.loadModel( manager.get('paths').getConfig().find('misc').get('path') + '/sphere').reparentTo(self.sun) self.sun.setScale(0.1) self.sun.setTwoSided(True) self.sun.setColorScale(10.0, 10.0, 10.0, 1.0, 10001) self.sun.setLightOff(1) self.sun.setShaderOff(1) self.sun.setFogOff(1) self.sun.setCompass() self.sun.setBin('background', 10) self.sun.setDepthWrite(False) self.sun.setDepthTest(False) # Workaround an annoyance in Panda. No idea why it's needed. self.sun.node().setBounds(OmniBoundingVolume()) isa = xml.find('isa') inst = xml.find('instance') if isa != None or inst != None: if inst != None: orig = Vec3(float(inst.get('x', '0')), float(inst.get('y', '0')), float(inst.get('z', '0'))) else: level = manager.get(isa.get('source')) orig = Vec3(level.getByIsA(isa.get('name'))[0].getPos(render)) orig.normalize() self.sun.setPos(orig) godrays = xml.find('godrays') if godrays != None: self.vlbuffer = base.win.makeTextureBuffer('volumetric-lighting', base.win.getXSize() / 2, base.win.getYSize() / 2) self.vlbuffer.setClearColor(Vec4(0, 0, 0, 1)) cam = base.makeCamera(self.vlbuffer) cam.node().setLens(base.camLens) cam.reparentTo(base.cam) initstatenode = NodePath('InitialState') initstatenode.setColorScale(0, 0, 0, 1, 10000) initstatenode.setShaderOff(10000) initstatenode.setLightOff(10000) initstatenode.setMaterialOff(10000) initstatenode.setTransparency(TransparencyAttrib.MBinary, 10000) cam.node().setCameraMask(BitMask32.bit(2)) cam.node().setInitialState(initstatenode.getState()) self.vltexture = self.vlbuffer.getTexture() self.vltexture.setWrapU(Texture.WMClamp) self.vltexture.setWrapV(Texture.WMClamp) card = CardMaker('VolumetricLightingCard') card.setFrameFullscreenQuad() self.finalQuad = render2d.attachNewNode(card.generate()) self.finalQuad.setAttrib( ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OIncomingColor, ColorBlendAttrib.OFbufferColor)) self.finalQuad.setShader( Shader.load( posixpath.join( manager.get('paths').getConfig().find('shaders').get( 'path'), 'filter-vlight.cg'))) self.finalQuad.setShaderInput('src', self.vltexture) self.finalQuad.setShaderInput( 'vlparams', 32, 0.9 / 32.0, 0.97, 0.5 ) # Note - first 32 is now hardcoded into shader for cards that don't support variable sized loops. self.finalQuad.setShaderInput('casterpos', 0.5, 0.5, 0, 0) # Last parameter to vlcolor is the exposure vlcolor = Vec4(float(godrays.get('r', '1')), float(godrays.get('g', '1')), float(godrays.get('b', '1')), 0.04) self.finalQuad.setShaderInput('vlcolor', vlcolor) else: self.finalQuad = None
def make_blur_shader (dir, size, numsamples, randrot=False, hfac=1.0, desat=0.0, showas=False): shdkey = (dir, size, numsamples, hfac, desat) ret = _blur_shader_cache.get(shdkey) if ret is not None: shader = ret return shader vshstr = GLSL_PROLOGUE vshstr += """ uniform mat4 p3d_ModelViewProjectionMatrix; in vec4 p3d_Vertex; in vec2 p3d_MultiTexCoord0; out vec2 l_texcoord0; void main () { gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex; l_texcoord0 = p3d_MultiTexCoord0; } """ fshstr = GLSL_PROLOGUE ret = make_frag_outputs(wcolor=True) odeclstr, ocolorn = ret if desat: dfr, dfg, dfb = 0.30, 0.59, 0.11 fshstr += """ const vec3 desatfac = vec3(%(dfr)f, %(dfg)f, %(dfb)f); """ % locals() fshstr += """ const float pi2 = 6.2832; """ tind = 0 tind_col = tind fshstr += """ uniform sampler2D p3d_Texture%(tind_col)d; """ % locals() tind += 1 if randrot: tind_rrt = tind fshstr += """ uniform sampler2D p3d_Texture%(tind_rrt)d; """ % locals() tind += 1 fshstr += """ in vec2 l_texcoord0; """ fshstr += odeclstr fshstr += """ void main () { vec4 col = vec4(0.0, 0.0, 0.0, 0.0); vec4 col_1; float xc, yc, x, y; xc = l_texcoord0.x; yc = l_texcoord0.y; """ if randrot: fshstr += """ float ra; ra = texture(p3d_Texture%(tind_rrt)d, vec2(xc, yc)).x * pi2; float sra = sin(ra); float cra = cos(ra); """ % locals() eff_hfac = hfac if dir == "u" else 1.0 #eff_hfac = 1.0 sampling = _blur_sampling(size, numsamples, eff_hfac) for o, c in sampling: if dir == "u": if randrot: fshstr += """ x = xc + %(o)s * cra; y = yc + %(o)s * sra; """ % locals() else: fshstr += """ x = xc + %(o)s; y = yc; """ % locals() elif dir == "v": if randrot: fshstr += """ x = xc - %(o)s * sra; y = yc + %(o)s * cra; """ % locals() else: fshstr += """ x = xc; y = yc + %(o)s; """ % locals() elif dir == "uv": raise StandardError("Blur direction '%s' not implemented yet." % dir) else: raise StandardError("Unknown blur direction '%s'." % dir) fshstr += """ col_1 = texture(p3d_Texture%(tind_col)d, vec2(x, y)); """ % locals() fshstr += """ col += col_1 * %(c)s; """ % locals() if desat: fshstr += """ float g = dot(col.rgb, desatfac); col = mix(col, vec4(g, g, g, col.a), %(desat)f); """ % locals() fshstr += """ %(ocolorn)s = col; """ % locals() fshstr += """ } """ if showas: printsh((vshstr, fshstr), showas) shader = Shader.make(Shader.SLGLSL, vshstr, fshstr) _blur_shader_cache[shdkey] = shader return shader
def make_text_shader (shadow=False, glow=False, showas=None): if isinstance(glow, Vec4): glow = tuple(glow) elif not glow: pass shdkey = (shadow, glow) shader = _text_shader_cache.get(shdkey) if shader is not None: return shader vshstr = GLSL_PROLOGUE vshstr += """ uniform mat4 p3d_ModelViewProjectionMatrix; in vec2 p3d_MultiTexCoord0; out vec2 l_texcoord0; """ if shadow: vshstr += """ in vec4 p3d_Color; out vec4 l_color; """ vshstr += """ in vec4 p3d_Vertex; void main () { gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex; l_texcoord0 = p3d_MultiTexCoord0; """ if shadow: vshstr += """ l_color = p3d_Color; """ vshstr += """ } """ fshstr = GLSL_PROLOGUE ret = make_frag_outputs(wcolor=True, wsunvis=True, wbloom=base.with_bloom) odeclstr, ocolorn, osunvisn = ret[:3] if base.with_bloom: obloomn = ret[3] fshstr += """ in vec2 l_texcoord0; """ if shadow: fshstr += """ in vec4 l_color; """ else: fshstr += """ uniform vec4 p3d_Color; """ tind = 0 tind_col = tind fshstr += """ uniform sampler2D p3d_Texture%(tind_col)d; """ % locals() tind += 1 if glow and not isinstance(glow, tuple): tind_glw = tind fshstr += """ uniform sampler2D p3d_Texture%(tind_glw)d; """ % locals() tind += 1 fshstr += """ uniform vec4 p3d_ColorScale; """ fshstr += odeclstr fshstr += """ void main () { vec4 color; vec4 t_color = texture(p3d_Texture%(tind_col)d, l_texcoord0); """ % locals() if shadow: fshstr += """ color = l_color * t_color.a; """ else: fshstr += """ color = p3d_Color * t_color.a; """ fshstr += """ color *= p3d_ColorScale; """ if isinstance(glow, tuple): gwr, gwg, gwb, gwa = glow fshstr += """ vec4 glwm = vec4(%(gwr)f, %(gwg)f, %(gwb)f, %(gwa)f); """ % locals() elif glow: fshstr += """ vec4 glwm = texture(p3d_Texture%(tind_glw)d, l_texcoord0); """ % locals() if glow: fshstr += """ //color.rgb *= clamp(glwm.rgb, 0.0, 1.0); color.rgb *= glwm.rgb; // no cutoff """ if glow: fshstr += """ vec4 bloom; bloom.a = glwm.a * color.a; bloom.rgb = color.rgb * bloom.a; """ else: fshstr += """ vec4 bloom = vec4(0.0, 0.0, 0.0, color.a); """ if base.with_glow_add and not base.with_bloom: fshstr += """ color.rgb += bloom.rgb; """ fshstr += """ %(ocolorn)s = color; %(osunvisn)s = vec4(0.0, 0.0, 0.0, 0.0); """ % locals() if base.with_bloom: fshstr += """ %(obloomn)s = bloom; """ % locals() fshstr += """ } """ if showas: printsh((vshstr, fshstr), showas) shader = Shader.make(Shader.SLGLSL, vshstr, fshstr) _text_shader_cache[shdkey] = shader return shader
def make_shader (ambln=None, dirlns=[], pntlns=[], fogn=None, fogsbl=(), camn=None, uvscrn=None, uvoffscn=None, pntobrn=None, obrthr=0.0, color=True, normal=False, glow=False, gloss=False, modcol=False, selfalpha=False, glowfacn=None, glowaddn=None, glowzerodist=None, sunposn=None, sunbcoln=None, sunstr=0.0, sunopq=1.0, shadowrefn=False, shadowdirlin=None, shadowblendn=None, shadowpush=0.0, shadowblur=None, showas=None, getargs=False): if not dirlns and not pntlns: normal = False gloss = False if not fogn: fogsbl = () glow_orig = glow if isinstance(glow, Vec4): glow = tuple(glow) elif not glow: glowfacn = None glowaddn = None glowzerodist = None gloss_orig = gloss if isinstance(gloss, Vec4): gloss = tuple(gloss) if not dirlns or not shadowrefn: shadowrefn = None shadowdirlin = None shadowblendn = None shadowpush = 0.0 shadowblur = None shdkey = (ambln, tuple(sorted(dirlns)), tuple(sorted(pntlns)), fogn, tuple(fogsbl), camn, uvscrn, uvoffscn, pntobrn, obrthr, color, normal, glow, gloss, modcol, selfalpha, glowfacn, glowaddn, sunposn, sunbcoln, sunstr, sunopq, shadowrefn, shadowdirlin, shadowblendn, shadowpush, shadowblur) ret = _shader_cache.get(shdkey) if ret is not None: shader, kwargs = ret if getargs: return shader, kwargs else: return shader if not camn and (fogn or gloss or glowzerodist): raise StandardError( "Shader input for camera must be present if " "fog or gloss is activated.") if not (sunposn and sunbcoln) and fogsbl: raise StandardError( "Shader input for sun position and sun color must be present if " "fog-sun blending is activated.") vshstr = GLSL_PROLOGUE need_texcoord = (color or normal or (glow and not isinstance(glow, tuple)) or (gloss and not isinstance(gloss, tuple))) if ambln: vshstr += make_shdfunc_amblit() if dirlns and not (gloss or normal or shadowrefn): vshstr += make_shdfunc_dirlit(gloss=gloss) if fogn: if fogsbl: vshstr += make_shdfunc_sunbln(sunblend=fogsbl) vshstr += make_shdfunc_fogbln(sunblend=fogsbl) if shadowrefn: vshstr += make_shdfunc_shdcrd(push=shadowpush) if ambln: vshstr += """ uniform AmbLight %(ambln)s; """ % locals() if not (gloss or normal or shadowrefn): for dirln in dirlns: vshstr += """ uniform DirLight %(dirln)s; """ % locals() if ambln or dirlns or pntlns or glow: vshstr += """ out vec4 l_lit; """ if pntlns or pntobrn or gloss: vshstr += """ out vec4 l_vertpos; """ if dirlns or pntlns: vshstr += """ in vec3 p3d_Normal; """ if normal: vshstr += """ in vec3 p3d_Tangent; """ if pntlns or gloss or normal or shadowrefn: vshstr += """ out vec3 l_vertnrm; """ if normal: vshstr += """ out vec3 l_verttng; """ if modcol: vshstr += """ in vec4 p3d_Color; out vec4 l_color; """ if fogn: vshstr += """ uniform mat4 p3d_ModelMatrix; uniform vec4 wspos_%(camn)s; uniform FogSpec %(fogn)s; """ % locals() if fogsbl: vshstr += """ uniform vec4 wspos_%(sunposn)s; uniform SunBlendSpec %(sunbcoln)s; """ % locals() vshstr += """ out vec4 l_fog; """ % locals() # FIXME: Passing glowfac through vertex shader to fragment shader # because, if sent directly to fragment shader, Cg won't compile it. # FIXME: Check again with GLSL. if glowfacn: vshstr += """ uniform float %(glowfacn)s; out float l_%(glowfacn)s; """ % locals() if glowaddn: vshstr += """ uniform float %(glowaddn)s; out float l_%(glowaddn)s; """ % locals() if glowzerodist: vshstr += """ uniform vec4 vspos_%(camn)s; out float l_glwfac; """ % locals() if shadowrefn: vshstr += """ uniform mat4 trans_model_to_clip_of_%(shadowrefn)s; uniform int %(shadowdirlin)s; uniform float %(shadowblendn)s; out vec4 l_shdcoord; flat out int l_shddirli; """ % locals() vshstr += """ uniform mat4 p3d_ModelViewProjectionMatrix; """ if pntlns or pntobrn or gloss or glowzerodist: vshstr += """ uniform mat4 p3d_ModelViewMatrix; """ if dirlns or pntlns or gloss or normal or shadowrefn: vshstr += """ uniform mat3 p3d_NormalMatrix; """ if need_texcoord: vshstr += """ in vec2 p3d_MultiTexCoord0; out vec2 l_texcoord0; """ vshstr += """ in vec4 p3d_Vertex; void main () { """ if ambln or dirlns or pntlns or glow: vshstr += """ l_lit = vec4(0.0, 0.0, 0.0, 0.0); """ if dirlns or pntlns: vshstr += """ vec3 normal = normalize(p3d_NormalMatrix * p3d_Normal); """ if normal: vshstr += """ vec3 tangent = normalize(p3d_NormalMatrix * p3d_Tangent); """ if ambln: vshstr += """ amblit(%(ambln)s, 1.0, l_lit); """ % locals() if not (gloss or normal or shadowrefn): for dirln in dirlns: vshstr += """ dirlit(%(dirln)s, normal, 1.0, l_lit); """ % locals() if pntlns or pntobrn or gloss: vshstr += """ l_vertpos = p3d_ModelViewMatrix * p3d_Vertex; """ if pntlns or gloss or normal or shadowrefn: vshstr += """ l_vertnrm = normal; """ if normal: vshstr += """ l_verttng = tangent; """ if fogn: vshstr += """ vec4 pw = p3d_ModelMatrix * p3d_Vertex; l_fog = vec4(0.0, 0.0, 0.0, 0.0); """ if fogsbl: vshstr += """ fogbln(%(fogn)s, wspos_%(camn)s, pw, wspos_%(sunposn)s, %(sunbcoln)s.ambient, l_fog); """ % locals() else: vshstr += """ fogbln(%(fogn)s, wspos_%(camn)s, pw, l_fog); """ % locals() vshstr += """ gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex; """ if need_texcoord: vshstr += """ l_texcoord0 = p3d_MultiTexCoord0; """ if modcol: vshstr += """ l_color = p3d_Color; """ % locals() if glowfacn: vshstr += """ l_%(glowfacn)s = %(glowfacn)s; """ % locals() if glowaddn: vshstr += """ l_%(glowaddn)s = %(glowaddn)s; """ % locals() if glowzerodist: vshstr += """ float4 vertpos = p3d_ModelViewMatrix * p3d_Vertex; float cdist = length(vspos_%(camn)s.xyz - vertpos.xyz); l_glwfac = 1.0 - clamp(cdist / %(glowzerodist)f, 0.0, 1.0); """ % locals() if shadowrefn: vshstr += """ l_shdcoord = shdcrd(trans_model_to_clip_of_%(shadowrefn)s, p3d_Vertex, %(shadowblendn)s); l_shddirli = %(shadowdirlin)s; """ % locals() vshstr += """ } """ fshstr = GLSL_PROLOGUE ret = make_frag_outputs(wcolor=True, wsunvis=True, wbloom=base.with_bloom) odeclstr, ocolorn, osunvisn = ret[:3] if base.with_bloom: obloomn = ret[3] if dirlns and (gloss or normal or shadowrefn): fshstr += make_shdfunc_dirlit(gloss=gloss) if pntlns: fshstr += make_shdfunc_pntlit(gloss=gloss) if fogn: fshstr += make_shdfunc_fogapl() if pntobrn: fshstr += make_shdfunc_pntobr() if shadowrefn: fshstr += make_shdfunc_shdfac(blur=shadowblur) if ambln or dirlns or pntlns or glow: fshstr += """ in vec4 l_lit; """ % locals() if pntlns or pntobrn or gloss: fshstr += """ in vec4 l_vertpos; """ if pntlns or gloss or normal or shadowrefn: fshstr += """ in vec3 l_vertnrm; """ if normal: fshstr += """ in vec3 l_verttng; """ if modcol: fshstr += """ in vec4 l_color; """ % locals() if gloss or normal or shadowrefn: for dirln in dirlns: fshstr += """ uniform DirLight %(dirln)s; """ % locals() for pntln in pntlns: fshstr += """ uniform PntLight %(pntln)s; """ % locals() if gloss: fshstr += """ uniform vec4 vspos_%(camn)s; """ % locals() if fogn: fshstr += """ in vec4 l_fog; """ % locals() if pntobrn: fshstr += """ uniform PntLight %(pntobrn)s; """ % locals() if glowfacn: fshstr += """ in float l_%(glowfacn)s; """ % locals() if glowaddn: fshstr += """ in float l_%(glowaddn)s; """ % locals() if glowzerodist: fshstr += """ in float l_glwfac; """ % locals() if uvscrn: fshstr += """ struct UvScrollSpec { vec4 ambient; }; uniform UvScrollSpec %(uvscrn)s; """ % locals() if uvoffscn: fshstr += """ uniform vec4 %(uvoffscn)s; """ % locals() if shadowrefn: fshstr += """ in vec4 l_shdcoord; flat in int l_shddirli; """ % locals() if need_texcoord: fshstr += """ in vec2 l_texcoord0; """ tind = 0 if color: tind_col = tind fshstr += """ uniform sampler2D p3d_Texture%(tind_col)d; """ % locals() tind += 1 if normal: tind_nrm = tind fshstr += """ uniform sampler2D p3d_Texture%(tind_nrm)d; """ % locals() tind += 1 if glow and not isinstance(glow, tuple): tind_glw = tind fshstr += """ uniform sampler2D p3d_Texture%(tind_glw)d; """ % locals() tind += 1 if gloss and not isinstance(gloss, tuple): tind_gls = tind fshstr += """ uniform sampler2D p3d_Texture%(tind_gls)d; """ % locals() tind += 1 if shadowrefn: tind_shd = tind fshstr += """ uniform sampler2D p3d_Texture%(tind_shd)d; """ % locals() tind += 1 fshstr += """ uniform vec4 p3d_Color; uniform vec4 p3d_ColorScale; """ fshstr += odeclstr fshstr += """ void main () { """ if need_texcoord: fshstr += """ vec2 texcoord0 = l_texcoord0; vec2 texcoord0b = l_texcoord0; """ if uvscrn and need_texcoord: fshstr += """ texcoord0 += %(uvscrn)s.ambient.xy; vec2 uvmax = %(uvscrn)s.ambient.zw; if (uvmax.x > 0.0 || uvmax.y > 0.0) { // uv-range [0, uvmax] texcoord0 = mod(texcoord0, uvmax); } else { // uv-range [0, 1] texcoord0 = mod(texcoord0, 1.0); } texcoord0b = texcoord0; """ % locals() if uvoffscn and need_texcoord: fshstr += """ float uoff = %(uvoffscn)s.x; float voff = %(uvoffscn)s.y; float usc = %(uvoffscn)s.z; float vsc = %(uvoffscn)s.w; texcoord0.x = texcoord0.x * usc + uoff; texcoord0.y = texcoord0.y * vsc + voff; """ % locals() fshstr += """ vec4 color; """ if color: fshstr += """ color = texture(p3d_Texture%(tind_col)d, texcoord0); """ % locals() else: fshstr += """ color = vec4(1.0, 1.0, 1.0, 1.0); """ if modcol: fshstr += """ color *= l_color; """ fshstr += """ color *= p3d_Color * p3d_ColorScale; """ if pntlns or gloss or shadowrefn: fshstr += """ vec3 vertnrm = l_vertnrm; vertnrm = normalize(vertnrm); // due to interpolation """ if normal: fshstr += """ vec3 verttng = l_verttng; verttng = normalize(verttng); // also vec3 vertbnr = cross(verttng, vertnrm); vec3 dn = texture(p3d_Texture%(tind_nrm)d, texcoord0b).xyz * 2.0 - 1.0; vertnrm = normalize(vertnrm * dn.z + verttng * dn.x + vertbnr * dn.y); """ % locals() if ambln or dirlns or pntlns or glow: fshstr += """ vec4 lit = l_lit; """ if isinstance(glow, tuple): gwr, gwg, gwb, gwa = glow fshstr += """ vec4 glwm = vec4(%(gwr)f, %(gwg)f, %(gwb)f, %(gwa)f); """ % locals() elif glow: fshstr += """ vec4 glwm = texture(p3d_Texture%(tind_glw)d, texcoord0b); """ % locals() if glow: if glowfacn: fshstr += """ glwm.rgb *= l_%(glowfacn)s; glwm.a = max(glwm.a * l_%(glowfacn)s, min(glwm.a, 0.1)); """ % locals() if glowaddn: fshstr += """ color.rgb += glwm.rgb * (glwm.a * l_%(glowaddn)s); """ % locals() fshstr += """ lit.rgb += glwm.rgb; """ if gloss: fshstr += """ vec4 gls = vec4(0.0, 0.0, 0.0, 0.0); vec3 cdir = normalize(vspos_%(camn)s.xyz - l_vertpos.xyz); """ % locals() if isinstance(gloss, tuple): gsr, gsg, gsb, gsa = gloss fshstr += """ vec4 glsm = vec4(%(gsr)f, %(gsg)f, %(gsb)f, %(gsa)f); """ % locals() elif gloss: fshstr += """ vec4 glsm = texture(p3d_Texture%(tind_gls)d, texcoord0b); """ % locals() fshstr += """ float kshd = 1.0; """ if shadowrefn: fshstr += """ float kshdb = shdfac(p3d_Texture%(tind_shd)d, l_shdcoord); """ % locals() for li, dirln in enumerate(dirlns): if shadowrefn: fshstr += """ kshd = l_shddirli == %(li)s ? kshdb : 1.0; """ % locals() if gloss: fshstr += """ dirlit(%(dirln)s, vertnrm, kshd, cdir, glsm, gls, lit); """ % locals() elif normal or shadowrefn: fshstr += """ dirlit(%(dirln)s, vertnrm, kshd, lit); """ % locals() for pntln in pntlns: if gloss: fshstr += """ pntlit(%(pntln)s, l_vertpos, vertnrm, cdir, glsm, gls, lit); """ % locals() else: fshstr += """ pntlit(%(pntln)s, l_vertpos, vertnrm, lit); """ % locals() if ambln or dirlns or pntlns or glow: fshstr += """ //color.rgb *= clamp(lit.rgb, 0.0, 1.0); color.rgb *= lit.rgb; // no cutoff """ if gloss: fshstr += """ color.rgb = clamp(color.rgb + gls.rgb, 0.0, 1.0); //color = clamp(color + gls, 0.0, 1.0); // opaque reflection """ if pntobrn: fshstr += """ float br = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; if (br > %(obrthr)s) { vec4 obr = vec4(1.0, 1.0, 1.0, 0.0); pntobr(%(pntobrn)s, l_vertpos, obr); color.rgb *= obr.rgb; // no cutoff } """ % locals() if fogn: fshstr += """ fogapl(color, l_fog, color); """ % locals() if selfalpha: fshstr += """ color.rgb *= color.a; """ if glow: fshstr += """ vec4 bloom; bloom.a = glwm.a * color.a; bloom.rgb = color.rgb * bloom.a; """ if glowzerodist: fshstr += """ bloom *= l_glwfac; """ % locals() else: fshstr += """ vec4 bloom = vec4(0.0, 0.0, 0.0, color.a); """ if base.with_glow_add and not base.with_bloom: fshstr += """ color.rgb += bloom.rgb; """ fshstr += """ %(ocolorn)s = color; %(osunvisn)s = vec4(%(sunstr)f, %(sunstr)f, %(sunstr)f, color.a * %(sunopq)f); """ % locals() if base.with_bloom: fshstr += """ %(obloomn)s = bloom; """ % locals() fshstr += """ } """ if showas: printsh((vshstr, fshstr), showas) shader = Shader.make(Shader.SLGLSL, vshstr, fshstr) kwargs = dict( # only the arguments influencing creation ambln=ambln, dirlns=dirlns, pntlns=pntlns, fogn=fogn, camn=camn, uvscrn=uvscrn, uvoffscn=uvoffscn, pntobrn=pntobrn, obrthr=obrthr, normal=normal, gloss=gloss_orig, glow=glow_orig, modcol=modcol, selfalpha=selfalpha) _shader_cache[shdkey] = (shader, kwargs) if getargs: return shader, kwargs else: return shader
def make_bloom_shader (limbrthr=1.0, limbrfac=1.0, visiblen=None, showas=False): shdkey = (limbrthr, limbrfac, visiblen) ret = _bloom_shader_cache.get(shdkey) if ret is not None: shader = ret return shader vshstr = GLSL_PROLOGUE vshstr += """ uniform mat4 p3d_ModelViewProjectionMatrix; in vec4 p3d_Vertex; in vec2 p3d_MultiTexCoord0; out vec2 l_texcoord0; void main () { gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex; l_texcoord0 = p3d_MultiTexCoord0; } """ fshstr = GLSL_PROLOGUE ret = make_frag_outputs(wcolor=True) odeclstr, ocolorn = ret fshstr += """ uniform sampler2D p3d_Texture0; uniform sampler2D p3d_Texture1; in vec2 l_texcoord0; """ if visiblen: fshstr += """ uniform bool %(visiblen)s; """ % locals() fshstr += odeclstr fshstr += """ void main () { vec4 color_0 = texture(p3d_Texture0, l_texcoord0); vec4 color = color_0; """ if visiblen: fshstr += """ if (%(visiblen)s) { """ % locals() fshstr += """ vec4 color_1 = texture(p3d_Texture1, l_texcoord0); float bfac; float br = 0.2126 * color_0.r + 0.7152 * color_0.g + 0.0722 * color_0.b; br = clamp(br, 0.0, 1.0); if (br > %(limbrthr)s) { bfac = mix(1.0, %(limbrfac)s, (br - %(limbrthr)s) / (1.0 - %(limbrthr)s)); } else { bfac = 1.0; } color += color_1 * bfac; """ % locals() if visiblen: fshstr += """ } """ fshstr += """ %(ocolorn)s = color; """ % locals() fshstr += """ } """ if showas: printsh((vshstr, fshstr), showas) shader = Shader.make(Shader.SLGLSL, vshstr, fshstr) _bloom_shader_cache[shdkey] = shader return shader
def __init__(self, manager, xml): self.updateTask = None self.sun = base.cam.attachNewNode("sun") loader.loadModel(manager.get("paths").getConfig().find("misc").get("path") + "/sphere").reparentTo(self.sun) self.sun.setScale(0.1) self.sun.setTwoSided(True) self.sun.setColorScale(10.0, 10.0, 10.0, 1.0, 10001) self.sun.setLightOff(1) self.sun.setShaderOff(1) self.sun.setFogOff(1) self.sun.setCompass() self.sun.setBin("background", 10) self.sun.setDepthWrite(False) self.sun.setDepthTest(False) # Workaround an annoyance in Panda. No idea why it's needed. self.sun.node().setBounds(OmniBoundingVolume()) isa = xml.find("isa") inst = xml.find("instance") if isa != None or inst != None: if inst != None: orig = Vec3(float(inst.get("x", "0")), float(inst.get("y", "0")), float(inst.get("z", "0"))) else: level = manager.get(isa.get("source")) orig = Vec3(level.getByIsA(isa.get("name"))[0].getPos(render)) orig.normalize() self.sun.setPos(orig) godrays = xml.find("godrays") if godrays != None: self.vlbuffer = base.win.makeTextureBuffer( "volumetric-lighting", base.win.getXSize() / 2, base.win.getYSize() / 2 ) self.vlbuffer.setClearColor(Vec4(0, 0, 0, 1)) cam = base.makeCamera(self.vlbuffer) cam.node().setLens(base.camLens) cam.reparentTo(base.cam) initstatenode = NodePath("InitialState") initstatenode.setColorScale(0, 0, 0, 1, 10000) initstatenode.setShaderOff(10000) initstatenode.setLightOff(10000) initstatenode.setMaterialOff(10000) initstatenode.setTransparency(TransparencyAttrib.MBinary, 10000) cam.node().setCameraMask(BitMask32.bit(2)) cam.node().setInitialState(initstatenode.getState()) self.vltexture = self.vlbuffer.getTexture() self.vltexture.setWrapU(Texture.WMClamp) self.vltexture.setWrapV(Texture.WMClamp) card = CardMaker("VolumetricLightingCard") card.setFrameFullscreenQuad() self.finalQuad = render2d.attachNewNode(card.generate()) self.finalQuad.setAttrib( ColorBlendAttrib.make( ColorBlendAttrib.MAdd, ColorBlendAttrib.OIncomingColor, ColorBlendAttrib.OFbufferColor ) ) self.finalQuad.setShader( Shader.load( posixpath.join(manager.get("paths").getConfig().find("shaders").get("path"), "filter-vlight.cg") ) ) self.finalQuad.setShaderInput("src", self.vltexture) self.finalQuad.setShaderInput( "vlparams", 32, 0.9 / 32.0, 0.97, 0.5 ) # Note - first 32 is now hardcoded into shader for cards that don't support variable sized loops. self.finalQuad.setShaderInput("casterpos", 0.5, 0.5, 0, 0) # Last parameter to vlcolor is the exposure vlcolor = Vec4( float(godrays.get("r", "1")), float(godrays.get("g", "1")), float(godrays.get("b", "1")), 0.04 ) self.finalQuad.setShaderInput("vlcolor", vlcolor) else: self.finalQuad = None
def make_desat_shader (avgfac=Vec3(0.30, 0.59, 0.11), desfacn=None, raddesn=None, raddarkn=None, sunblindn=None, sunbrpnum=0, sunberad=0.9, sunbmaxout=5.0, sunboexp=1.0, sunbdexp=2.0, hfac=1.0, showas=False): shdkey = (tuple(avgfac), desfacn, raddesn, raddarkn, sunblindn, sunbrpnum, sunberad, sunbmaxout, sunboexp, sunbdexp, hfac) ret = _desat_shader_cache.get(shdkey) if ret is not None: shader = ret return shader ihfac = 1.0 / hfac vshstr = GLSL_PROLOGUE vshstr += """ uniform mat4 p3d_ModelViewProjectionMatrix; in vec4 p3d_Vertex; in vec2 p3d_MultiTexCoord0; out vec2 l_texcoord0; void main () { gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex; l_texcoord0 = p3d_MultiTexCoord0; } """ fshstr = GLSL_PROLOGUE ret = make_frag_outputs(wcolor=True) odeclstr, ocolorn = ret dfr, dfg, dfb = avgfac fshstr += """ vec3 desatfac = vec3(%(dfr)f, %(dfg)f, %(dfb)f); """ % locals() fshstr += """ void desat (inout vec4 color, float desfac) { float g = dot(color.rgb, desatfac); vec4 color_fd = vec4(g, g, g, color.a); color = mix(color, color_fd, desfac); } """ if raddesn: fshstr += """ struct RadDesSpec { vec4 ambient; }; void rdesat (inout vec4 color, RadDesSpec rdesspc, float rad, float ang) { float outrad = rdesspc.ambient.x; float ifac0 = rdesspc.ambient.y; float ifac1 = rdesspc.ambient.z; float ifac = mix(ifac0, ifac1, clamp(rad / outrad, 0.0, 1.0)); desat(color, ifac); } """ if raddarkn: fshstr += """ struct RadDarkSpec { vec4 diffuse; vec4 specular; }; void rdarken (inout vec4 color, RadDarkSpec rdarkspc, float rad, float ang) { vec4 radspc = rdarkspc.diffuse; vec4 angspc = rdarkspc.specular; float outrad0 = radspc.x; float ifac0 = radspc.y; float ifac1 = radspc.z; float colr = radspc.w; float drampl = angspc.x; float drfreq = angspc.y; float drphase = angspc.z; float outrad = outrad0 * (1.0 + drampl * sin(drfreq * ang + drphase)); float ifac = mix(ifac0, ifac1, clamp(rad / outrad, 0.0, 1.0)); color.rgb = mix(color.rgb, vec3(colr, 0.0, 0.0), ifac); } """ if sunblindn: fshstr += """ void sunblind (inout vec4 color, vec4 spblspc0, vec4 spblspc1, sampler2D vtex, vec2 tc) { vec2 sctc = spblspc0.xy; float svrad = spblspc0.z; float sstr = spblspc0.w; vec3 scol = spblspc1.xyz; float outdist = spblspc1.w; """ fshstr += """ float vstr = texture(vtex, sctc).r; vec2 stc; //float mintd = length(tc - sctc); float td = 0.0; """ pi2 = pi * 0.5 pi4 = pi * 0.25 if isinstance(sunbrpnum, int): rptotnum = sunbrpnum rpcircnum = 1 else: rptotnum, rpcircnum = sunbrpnum # FIXME: Replace this with Poisson disk distribution. # rpcircnum will then not be needed anymore. if rptotnum > 0: off_uv = [] drad = sunberad / rpcircnum totperim = 0.0 for i in range(rpcircnum): rad = drad * (i + 1) perim = 2 * rad * pi totperim += perim rpnums = [] for i in range(rpcircnum): rad = drad * (i + 1) perim = 2 * rad * pi rpnum = int(rptotnum * (perim / totperim) + 0.5) rpnums.append(rpnum) while sum(rpnums) > rptotnum: for j in reversed(range(rpcircnum)): if rpnums[j] > 0: rpnums[j] -= 1 if sum(rpnums) == rptotnum: break for i in range(rpcircnum): rpnum = rpnums[i] if rpnum == 0: continue rad = drad * (i + 1) dang = 2 * pi / rpnum dang0 = (i + 0.5) * dang for j in range(rpnum): ang = dang * j + dang0 du = cos(ang) * rad * ihfac dv = sin(ang) * rad off_uv.append((du, dv)) for du, dv in off_uv: fshstr += """ stc = sctc + vec2(%(du)f, %(dv)f) * svrad; vstr += texture(vtex, stc).r; //td = length(tc - stc); if (mintd > td) { mintd = td; } """ % locals() sumfac = 1.0 / (rptotnum + 1) fshstr += """ vstr *= %(sumfac)f; """ % locals() epsdiv = 1.0 / sunbmaxout fshstr += """ //color.rgb = mix(color.rgb, vec3(1.0, 0.0, 0.0), pow(clamp(1.0 - mintd, 0.0, 1.0), 600)); vec2 spos = vec2((sctc.x - 0.5) * %(hfac)f, sctc.y - 0.5) * 2; float srad = svrad * 2; vec2 pos = vec2((tc.x - 0.5) * %(hfac)f, tc.y - 0.5) * 2; float cstr = clamp(1.0 - clamp(length(spos) / outdist, 0.0, 1.0), 0.0, 1.0); float estr = pow(cstr, 2.0) * pow(sstr, 0.5) * pow(vstr, 0.5); vec2 dpos = pos - spos; float dist = length(dpos); vec3 tcol = color.rgb; float ofac = sin(pow(clamp((dist - srad) / (outdist - srad), 0.0, 1.0), 0.75) * %(pi2)f); float cfac = tan((estr + 1.0) * %(pi4)f); tcol = clamp((tcol - 0.5) * mix(1.0, cfac, ofac) + 0.5, 0.0, 1.0); tcol = tcol * (1.0 + mix(0.0, -estr, ofac)); //color.rgb = tcol; float scrdist = 1.0 / (pow(clamp(1.0 - estr, 0.0, 1.0), %(sunboexp)f) + %(epsdiv)f); vec3 ecol = mix(scol, vec3(1.0, 1.0, 1.0), estr); float dfac = clamp((1.0 - clamp(dist / scrdist, 0.0, 1.0)) * estr, 0.0, 1.0); color.rgb = mix(tcol, ecol, pow(dfac, %(sunbdexp)f)); } """ % locals() fshstr += """ uniform sampler2D p3d_Texture0; in vec2 l_texcoord0; """ if desfacn: fshstr += """ uniform float %(desfacn)s; """ % locals() if raddesn: fshstr += """ uniform RadDesSpec %(raddesn)s; """ % locals() if raddarkn: fshstr += """ uniform RadDarkSpec %(raddarkn)s; """ % locals() if sunblindn: sunblind1n, sunblind2n = sunblindn fshstr += """ uniform sampler2D p3d_Texture1; struct SunBlindSpec { vec4 ambient; }; uniform SunBlindSpec %(sunblind1n)s; uniform SunBlindSpec %(sunblind2n)s; """ % locals() fshstr += odeclstr fshstr += """ void main () { vec4 color; color = texture(p3d_Texture0, l_texcoord0); //color = textureLod(p3d_Texture0, vec2(l_texcoord0.x, l_texcoord0.y), 3); """ if sunblindn: fshstr += """ // Sun blind. sunblind(color, %(sunblind1n)s.ambient, %(sunblind2n)s.ambient, p3d_Texture1, l_texcoord0); """ % locals() if raddesn or raddarkn: fshstr += """ vec2 uvcen = l_texcoord0 - 0.5; float uvrad = length(uvcen); float uvang = atan(uvcen.y, uvcen.x); """ % locals() if raddesn: fshstr += """ // Radially desaturate. rdesat(color, %(raddesn)s, uvrad, uvang); """ % locals() if raddarkn: fshstr += """ // Radially darken. rdarken(color, %(raddarkn)s, uvrad, uvang); """ % locals() dfovr = ("%(desfacn)s" % locals()) if desfacn else "1.0" fshstr += """ // Overally desaturate. desat(color, %(dfovr)s); """ % locals() fshstr += """ %(ocolorn)s = color; """ % locals() fshstr += """ } """ if showas: printsh((vshstr, fshstr), showas) shader = Shader.make(Shader.SLGLSL, vshstr, fshstr) _desat_shader_cache[shdkey] = shader return shader
def loadShader(self, name): fn = os.path.join(os.path.abspath(os.path.dirname(__file__)), name) fn = Filename.fromOsSpecific(fn) fn.makeTrueCase() return Shader.load(fn)
def _loadInternal(self, resType, filename, locationName=None, preloading=False): ''' Manages the actual loading of a resource given the resource filename and the resource location that contains it. @param resType: A constant that identifies the type of the resource. @param filename: The filename of the resource. @param locationName: The name of the resource location containing the resource. This is optional. @return: A pano.resources.Resource instance if preloading is True, or the actual resource instance if preloading is False or finally None if the resource couldn't be found. ''' self.requests += 1 if locationName is not None: location = self.locationsByName.get(locationName) else: location = self.locateResource(resType, filename) if location is None: self.log.error('Failed to locate resource %s' % filename) return None # get the full path to query the cache, sticky and preload stores fullPath = location.getResourceFullPath(filename) if fullPath is None: self.log.error('Failed to get full path to resource %s' % filename) return None # resource locations can be sticky if location.sticky: resource = self._getStickyResource(fullPath, resType) if resource is not None: if self.log.isEnabledFor(logging.DEBUG): self.log.debug('Returning sticky resource %s' % fullPath) self.stickyLoads += 1 if not preloading: resource.requested = True return resource.data if not preloading else resource # if the location has a preload flag, then search first in the preload store if location.preload: resource = self._fetchPreloaded(fullPath, location.name) if resource is not None: self.preloadHits += 1 if not preloading: resource.requested = True return resource.data if not preloading else resource else: self.preloadMisses += 1 # then search in our cache # resource = self._cacheLookup(fullPath, location.name) # if resource is not None: # if self.log.isEnabledFor(logging.DEBUG): # self.log.debug('Returning cached instance of resource %s' % fullPath) # if not preloading: # resource.requested = True # return resource.data if not preloading else resource # finally load it from the resource location if ResourcesTypes.isParsedResource(resType): # Convention: construct resource name from the basename of the filename and by dropping the extension. resName = os.path.basename(filename) extIndex = resName.rfind('.') if extIndex >= 0: resName = resName[:extIndex] resData = self._loadParsedResource(resType, resName, fullPath, location) else: if ResourcesTypes.isPandaResource(resType): # for Panda resources we use the BaseLoader resName = filename try: if resType == PanoConstants.RES_TYPE_MODELS: resData = loader.loadModel(fullPath) elif resType == PanoConstants.RES_TYPE_TEXTURES or resType == PanoConstants.RES_TYPE_VIDEOS: resData = loader.loadTexture(fullPath) elif resType == PanoConstants.RES_TYPE_IMAGES: img = PNMImage() img.read(fullPath) resData = img elif resType == PanoConstants.RES_TYPE_MUSIC: resData = loader.loadMusic(fullPath) elif resType == PanoConstants.RES_TYPE_SFX: resData = loader.loadSfx(fullPath) elif resType == PanoConstants.RES_TYPE_SHADERS: resData = Shader.load(fullPath) except Exception: self.log.exception( 'Panda loader failed to load resource %s' % fullPath) return None elif ResourcesTypes.isStreamResource(resType): # we consider character based and binary based streams # by handling stream resources in a special way we can perhaps provide more efficient # handling of streams, i.e. memory mapped files, compressed streams, decryption, etc. resName = filename if resType == PanoConstants.RES_TYPE_SCRIPTS or resType == PanoConstants.RES_TYPE_TEXTS: resData = self._loadCharacterStream(fullPath, location) else: resData = self._loadBinaryStream(fullPath, location) elif ResourcesTypes.isOpaqueResource(resType): # opaque resources perform their own loading, we only load the file's contents without caring # about how it looks and pass it to the read() method. resName = os.path.basename(filename) resData = ResourcesTypes.constructOpaqueResource( resType, resName, filename) opaque = self._loadBinaryStream(fullPath, location) fp = StringIO.StringIO(opaque) resData.read(fp) if resData is None: self.log.error('Failed to load resource %s' % fullPath) return None resource = Resource(resName, resData, resType, fullPath, location.name) resource.sticky = location.sticky resource.preload = location.preload if not preloading: resource.requested = True # consider caching the resource if not resource.sticky and not resource.preload: self._cacheResource(fullPath, resource, location.name) elif resource.sticky: self._addStickyResource(fullPath, resource, location.name) # when we are preloading, return the Resource instance instead return resource.data if not preloading else resource
def __init__(self, _base): self._base = _base self._base.cam.node().setActive(0) # window properties self.winprops = WindowProperties.size(base.win.getXSize(),base.win.getYSize()) self.props = FrameBufferProperties() self.props.setDepthBits(1) self.props.setColorBits(1) self.props.setAlphaBits(1) # buffers creation self.geom_buffer = self.make_FBO("geom buffer",3) self.light_buffer = self.make_FBO("light buffer",0) self.transparency_buffer = self.make_FBO("transparency buffer",0) # cameras creation self.geom_cam = self._base.makeCamera(self.geom_buffer) self.light_cam = self._base.makeCamera(self.light_buffer) self.transparency_cam = self._base.makeCamera(self.transparency_buffer) # cameras setup self.geom_cam.node().getDisplayRegion(0).setClearColorActive(1) self.geom_cam.node().getDisplayRegion(0).setClearColor(Vec4(1,0,0,1)) self.geom_cam.node().getDisplayRegion(0).setClearDepthActive(1) self.light_cam.node().getDisplayRegion(0).setClearColorActive(1) self.geom_cam.node().getDisplayRegion(0).setClearColor(Vec4(0,1,0,1)) self.light_cam.node().getDisplayRegion(0).setClearDepthActive(1) self.transparency_cam.node().getDisplayRegion(0).setClearColorActive(1) self.transparency_cam.node().getDisplayRegion(0).setClearDepthActive(1) self.geom_cam.node().getLens().setNear(0.1) self.light_cam.node().getLens().setNear(0.1) self.transparency_cam.node().getLens().setNear(0.1) self.geom_cam.node().getLens().setFov(90) self.light_cam.node().getLens().setFov(90) self._base.cam.node().getLens().setFov(90) self.transparency_cam.node().getLens().setFov(90) # cameras masks self.geom_mask = BitMask32(1) self.light_mask = BitMask32(2) self.transparency_mask = BitMask32(4) self.light_cam.node().setCameraMask(self.light_mask) self.geom_cam.node().setCameraMask(self.geom_mask) self.transparency_cam.node().setCameraMask(self.transparency_mask) RENDER_NODES['LIGHTS'].hide(self.geom_mask) RENDER_NODES['GEOMS'].hide(self.light_mask) RENDER_NODES['TRANSPS'].hide(self.geom_mask) # link cameras self.geom_cam.node().setScene(RENDER_NODES['GEOMS']) self.light_cam.node().setScene(RENDER_NODES['LIGHTS']) self.transparency_cam.node().setScene(RENDER_NODES['TRANSPS']) # buffers rendering order self.light_buffer.setSort(0) self.geom_buffer.setSort(-50) self.transparency_buffer.setSort(50) self._base.win.setSort(-100) # shadows cube creation self.shadow_cube = RENDER_NODES['GEOMS'].attachNewNode("cubemap") self.shadow_cube.setPos(0, 0, 0) buffer_cube_shadow = self._base.win.makeCubeMap("cube 1", 512, self.shadow_cube, camera_mask = self.geom_mask, to_ram = False, fbp = self.props) self.shadow_cube_texture = buffer_cube_shadow.getTexture() cameras = [] for camera in self.shadow_cube.getChildren(): cameras.append(camera) camera.node().getLens().setFov(90) camera.node().getLens().setNearFar(0.1 ,10.0) camera.node().setCameraMask(self.geom_mask) cameraInit = NodePath(PandaNode("cube camera initiator")) cameraInit.setShader(Shader.load('shaders/point_lights_cube.sha')) cameraInit.setShaderInput("light2", self.shadow_cube) cameraInit.setShaderInput("lightCamera", camera) cameraInit.setShaderInput("lensFar", Vec4(camera.node().getLens().getFar())) cameraInit.setShaderInput("transparency", Vec4(1)) camera.node().setInitialState(cameraInit.getState()) # reflections cube creation self.reflection_cube = RENDER_NODES['GEOMS'].attachNewNode("cubemap pivot") self.buffer_reflection_cube = self._base.win.makeCubeMap("cube 2", 512, self.reflection_cube, camera_mask = self.geom_mask, to_ram = False, fbp = self.props) self.reflection_cube_texture = self.buffer_reflection_cube.getTexture() for camera in self.reflection_cube.getChildren(): camera.node().getLens().setNearFar(0.1 ,500.0) # shader rendering normal maps normal_shader = ShaderAttrib.make() normal_shader = normal_shader.setShader(Shader.load(CG_NORMALMAP)) # shader rendering light light_shader = ShaderAttrib.make() light_shader = light_shader.setShader(Shader.load(CG_LIGHT)) # link states with cameras self.geom_cam.node().setTagStateKey(SHADER_TAGS['g-buffer']) self.geom_cam.node().setTagState("True", RenderState.make(normal_shader)) self.light_cam.node().setTagStateKey(SHADER_TAGS['compute light']) self.light_cam.node().setTagState("True", RenderState.make(light_shader)) # render textures creation self.albedo_map = Texture() self.normal_map = Texture() self.depth_map = Texture() self.specular_map = Texture() self.misc_map = Texture() self.light_map = Texture() self.transparency_map = Texture() self.transparency_depth_map = Texture() # render textures self.transparency_buffer.addRenderTexture(self.transparency_map, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPColor) self.transparency_buffer.addRenderTexture(self.transparency_depth_map, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPDepth) self.geom_buffer.addRenderTexture(self.normal_map, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPColor) self.geom_buffer.addRenderTexture(self.depth_map, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPDepth) self.geom_buffer.addRenderTexture(self.albedo_map, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPAuxRgba0) self.geom_buffer.addRenderTexture(self.specular_map, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPAuxRgba1) self.geom_buffer.addRenderTexture(self.misc_map, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPAuxRgba2) self.light_buffer.addRenderTexture(self.light_map, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPColor) taskMgr.add(self.update,'update reflections cubemap')
def reconfigure(self, fullrebuild, changed): """ Reconfigure is called whenever any configuration change is made. """ configuration = self.configuration if (fullrebuild): self.cleanup() if (len(configuration) == 0): return auxbits = 0 needtex = set(["color"]) needtexcoord = set(["color"]) if ("CartoonInk" in configuration): needtex.add("aux") auxbits |= AuxBitplaneAttrib.ABOAuxNormal needtexcoord.add("aux") if ("AmbientOcclusion" in configuration): needtex.add("depth") needtex.add("ssao0") needtex.add("ssao1") needtex.add("ssao2") needtex.add("aux") auxbits |= AuxBitplaneAttrib.ABOAuxNormal needtexcoord.add("ssao2") if ("BlurSharpen" in configuration): needtex.add("blur0") needtex.add("blur1") needtexcoord.add("blur1") if ("Bloom" in configuration): needtex.add("bloom0") needtex.add("bloom1") needtex.add("bloom2") needtex.add("bloom3") auxbits |= AuxBitplaneAttrib.ABOGlow needtexcoord.add("bloom3") if ("ViewGlow" in configuration): auxbits |= AuxBitplaneAttrib.ABOGlow if ("VolumetricLighting" in configuration): needtex[configuration["VolumetricLighting"].source] = True for tex in needtex: self.textures[tex] = Texture("scene-" + tex) self.textures[tex].setWrapU(Texture.WMClamp) self.textures[tex].setWrapV(Texture.WMClamp) self.finalQuad = self.manager.renderSceneInto( textures=self.textures, auxbits=auxbits) if (self.finalQuad == None): self.cleanup() return False if ("BlurSharpen" in configuration): blur0 = self.textures["blur0"] blur1 = self.textures["blur1"] self.blur.append( self.manager.renderQuadInto(colortex=blur0, div=2)) self.blur.append(self.manager.renderQuadInto(colortex=blur1)) self.blur[0].setShaderInput("src", self.textures["color"]) self.blur[0].setShader(self.loadShader("filter-blurx.sha")) self.blur[1].setShaderInput("src", blur0) self.blur[1].setShader(self.loadShader("filter-blury.sha")) if ("AmbientOcclusion" in configuration): ssao0 = self.textures["ssao0"] ssao1 = self.textures["ssao1"] ssao2 = self.textures["ssao2"] self.ssao.append(self.manager.renderQuadInto(colortex=ssao0)) self.ssao.append( self.manager.renderQuadInto(colortex=ssao1, div=2)) self.ssao.append(self.manager.renderQuadInto(colortex=ssao2)) self.ssao[0].setShaderInput("depth", self.textures["depth"]) self.ssao[0].setShaderInput("normal", self.textures["aux"]) self.ssao[0].setShaderInput( "random", loader.loadTexture("maps/random.rgb")) self.ssao[0].setShader( Shader.make(SSAO_BODY % configuration["AmbientOcclusion"].numsamples)) self.ssao[1].setShaderInput("src", ssao0) self.ssao[1].setShader(self.loadShader("filter-blurx.sha")) self.ssao[2].setShaderInput("src", ssao1) self.ssao[2].setShader(self.loadShader("filter-blury.sha")) if ("Bloom" in configuration): bloomconf = configuration["Bloom"] bloom0 = self.textures["bloom0"] bloom1 = self.textures["bloom1"] bloom2 = self.textures["bloom2"] bloom3 = self.textures["bloom3"] if (bloomconf.size == "large"): scale = 8 downsampler = "filter-down4.sha" elif (bloomconf.size == "medium"): scale = 4 downsampler = "filter-copy.sha" else: scale = 2 downsampler = "filter-copy.sha" self.bloom.append( self.manager.renderQuadInto(colortex=bloom0, div=2, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom1, div=scale, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom2, div=scale, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom3, div=scale, align=scale)) self.bloom[0].setShaderInput("src", self.textures["color"]) self.bloom[0].setShader(self.loadShader("filter-bloomi.sha")) self.bloom[1].setShaderInput("src", bloom0) self.bloom[1].setShader(self.loadShader(downsampler)) self.bloom[2].setShaderInput("src", bloom1) self.bloom[2].setShader(self.loadShader("filter-bloomx.sha")) self.bloom[3].setShaderInput("src", bloom2) self.bloom[3].setShader(self.loadShader("filter-bloomy.sha")) texcoords = {} texcoordPadding = {} for tex in needtexcoord: if self.textures[tex].getAutoTextureScale() != ATSNone or \ "HalfPixelShift" in configuration: texcoords[tex] = "l_texcoord_" + tex texcoordPadding["l_texcoord_" + tex] = tex else: # Share unpadded texture coordinates. texcoords[tex] = "l_texcoord" texcoordPadding["l_texcoord"] = None texcoordSets = list(enumerate(texcoordPadding.keys())) text = "//Cg\n" text += "void vshader(float4 vtx_position : POSITION,\n" text += " out float4 l_position : POSITION,\n" for texcoord, padTex in texcoordPadding.items(): if padTex is not None: text += " uniform float4 texpad_tx%s,\n" % (padTex) if ("HalfPixelShift" in configuration): text += " uniform float4 texpix_tx%s,\n" % (padTex) for i, name in texcoordSets: text += " out float2 %s : TEXCOORD%d,\n" % (name, i) text += " uniform float4x4 mat_modelproj)\n" text += "{\n" text += " l_position = mul(mat_modelproj, vtx_position);\n" for texcoord, padTex in texcoordPadding.items(): if padTex is None: text += " %s = vtx_position.xz * float2(0.5, 0.5) + float2(0.5, 0.5);\n" % ( texcoord) else: text += " %s = (vtx_position.xz * texpad_tx%s.xy) + texpad_tx%s.xy;\n" % ( texcoord, padTex, padTex) if ("HalfPixelShift" in configuration): text += " %s += texpix_tx%s.xy * 0.5;\n" % (texcoord, padTex) text += "}\n" text += "void fshader(\n" for i, name in texcoordSets: text += " float2 %s : TEXCOORD%d,\n" % (name, i) for key in self.textures: text += " uniform sampler2D k_tx" + key + ",\n" if ("CartoonInk" in configuration): text += " uniform float4 k_cartoonseparation,\n" text += " uniform float4 k_cartooncolor,\n" text += " uniform float4 texpix_txaux,\n" if ("BlurSharpen" in configuration): text += " uniform float4 k_blurval,\n" if ("VolumetricLighting" in configuration): text += " uniform float4 k_casterpos,\n" text += " uniform float4 k_vlparams,\n" text += " out float4 o_color : COLOR)\n" text += "{\n" text += " o_color = tex2D(k_txcolor, %s);\n" % ( texcoords["color"]) if ("CartoonInk" in configuration): text += CARTOON_BODY % {"texcoord": texcoords["aux"]} if ("AmbientOcclusion" in configuration): text += " o_color *= tex2D(k_txssao2, %s).r;\n" % ( texcoords["ssao2"]) if ("BlurSharpen" in configuration): text += " o_color = lerp(tex2D(k_txblur1, %s), o_color, k_blurval.x);\n" % ( texcoords["blur1"]) if ("Bloom" in configuration): text += " o_color = saturate(o_color);\n" text += " float4 bloom = 0.5 * tex2D(k_txbloom3, %s);\n" % ( texcoords["bloom3"]) text += " o_color = 1-((1-bloom)*(1-o_color));\n" if ("ViewGlow" in configuration): text += " o_color.r = o_color.a;\n" if ("VolumetricLighting" in configuration): text += " float decay = 1.0f;\n" text += " float2 curcoord = %s;\n" % (texcoords["color"]) text += " float2 lightdir = curcoord - k_casterpos.xy;\n" text += " lightdir *= k_vlparams.x;\n" text += " half4 sample = tex2D(k_txcolor, curcoord);\n" text += " float3 vlcolor = sample.rgb * sample.a;\n" text += " for (int i = 0; i < %s; i++) {\n" % (int( configuration["VolumetricLighting"].numsamples)) text += " curcoord -= lightdir;\n" text += " sample = tex2D(k_tx%s, curcoord);\n" % ( configuration["VolumetricLighting"].source) text += " sample *= sample.a * decay;//*weight\n" text += " vlcolor += sample.rgb;\n" text += " decay *= k_vlparams.y;\n" text += " }\n" text += " o_color += float4(vlcolor * k_vlparams.z, 1);\n" if ("GammaAdjust" in configuration): gamma = configuration["GammaAdjust"] if gamma == 0.5: text += " o_color.rgb = sqrt(o_color.rgb);\n" elif gamma == 2.0: text += " o_color.rgb *= o_color.rgb;\n" elif gamma != 1.0: text += " o_color.rgb = pow(o_color.rgb, %ff);\n" % ( gamma) if ("Inverted" in configuration): text += " o_color = float4(1, 1, 1, 1) - o_color;\n" text += "}\n" self.finalQuad.setShader(Shader.make(text)) for tex in self.textures: self.finalQuad.setShaderInput("tx" + tex, self.textures[tex]) self.task = taskMgr.add(self.update, "common-filters-update") if (changed == "CartoonInk") or fullrebuild: if ("CartoonInk" in configuration): c = configuration["CartoonInk"] self.finalQuad.setShaderInput( "cartoonseparation", Vec4(c.separation, 0, c.separation, 0)) self.finalQuad.setShaderInput("cartooncolor", c.color) if (changed == "BlurSharpen") or fullrebuild: if ("BlurSharpen" in configuration): blurval = configuration["BlurSharpen"] self.finalQuad.setShaderInput( "blurval", Vec4(blurval, blurval, blurval, blurval)) if (changed == "Bloom") or fullrebuild: if ("Bloom" in configuration): bloomconf = configuration["Bloom"] intensity = bloomconf.intensity * 3.0 self.bloom[0].setShaderInput("blend", bloomconf.blendx, bloomconf.blendy, bloomconf.blendz, bloomconf.blendw * 2.0) self.bloom[0].setShaderInput( "trigger", bloomconf.mintrigger, 1.0 / (bloomconf.maxtrigger - bloomconf.mintrigger), 0.0, 0.0) self.bloom[0].setShaderInput("desat", bloomconf.desat) self.bloom[3].setShaderInput("intensity", intensity, intensity, intensity, intensity) if (changed == "VolumetricLighting") or fullrebuild: if ("VolumetricLighting" in configuration): config = configuration["VolumetricLighting"] tcparam = config.density / float(config.numsamples) self.finalQuad.setShaderInput("vlparams", tcparam, config.decay, config.exposure, 0.0) if (changed == "AmbientOcclusion") or fullrebuild: if ("AmbientOcclusion" in configuration): config = configuration["AmbientOcclusion"] self.ssao[0].setShaderInput( "params1", config.numsamples, -float(config.amount) / config.numsamples, config.radius, 0) self.ssao[0].setShaderInput("params2", config.strength, config.falloff, 0, 0) self.update() return True
def reconfigure(self, fullrebuild, changed): """ Reconfigure is called whenever any configuration change is made. """ configuration = self.configuration if fullrebuild: self.cleanup() if len(configuration) == 0: return auxbits = 0 needtex = {} needtex["color"] = True if configuration.has_key("CartoonInk"): needtex["aux"] = True auxbits |= AuxBitplaneAttrib.ABOAuxNormal if configuration.has_key("AmbientOcclusion"): needtex["depth"] = True needtex["ssao0"] = True needtex["ssao1"] = True needtex["ssao2"] = True needtex["aux"] = True auxbits |= AuxBitplaneAttrib.ABOAuxNormal if configuration.has_key("BlurSharpen"): needtex["blur0"] = True needtex["blur1"] = True if configuration.has_key("Bloom"): needtex["bloom0"] = True needtex["bloom1"] = True needtex["bloom2"] = True needtex["bloom3"] = True auxbits |= AuxBitplaneAttrib.ABOGlow if configuration.has_key("ViewGlow"): auxbits |= AuxBitplaneAttrib.ABOGlow for tex in needtex: self.textures[tex] = Texture("scene-" + tex) self.textures[tex].setWrapU(Texture.WMClamp) self.textures[tex].setWrapV(Texture.WMClamp) needtexpix = True self.finalQuad = self.manager.renderSceneInto(textures=self.textures, auxbits=auxbits) if self.finalQuad == None: self.cleanup() return False if configuration.has_key("BlurSharpen"): blur0 = self.textures["blur0"] blur1 = self.textures["blur1"] self.blur.append(self.manager.renderQuadInto(colortex=blur0, div=2)) self.blur.append(self.manager.renderQuadInto(colortex=blur1)) self.blur[0].setShaderInput("src", self.textures["color"]) self.blur[0].setShader(self.loadShader("filter-blurx.sha")) self.blur[1].setShaderInput("src", blur0) self.blur[1].setShader(self.loadShader("filter-blury.sha")) if configuration.has_key("AmbientOcclusion"): ssao0 = self.textures["ssao0"] ssao1 = self.textures["ssao1"] ssao2 = self.textures["ssao2"] self.ssao.append(self.manager.renderQuadInto(colortex=ssao0)) self.ssao.append(self.manager.renderQuadInto(colortex=ssao1, div=2)) self.ssao.append(self.manager.renderQuadInto(colortex=ssao2)) self.ssao[0].setShaderInput("depth", self.textures["depth"]) self.ssao[0].setShaderInput("normal", self.textures["aux"]) self.ssao[0].setShaderInput("random", loader.loadTexture("maps/random.rgb")) self.ssao[0].setShader(self.loadShader("filter-ssao.sha")) self.ssao[1].setShaderInput("src", ssao0) self.ssao[1].setShader(self.loadShader("filter-blurx.sha")) self.ssao[2].setShaderInput("src", ssao1) self.ssao[2].setShader(self.loadShader("filter-blury.sha")) if configuration.has_key("Bloom"): bloomconf = configuration["Bloom"] bloom0 = self.textures["bloom0"] bloom1 = self.textures["bloom1"] bloom2 = self.textures["bloom2"] bloom3 = self.textures["bloom3"] if bloomconf.size == "large": scale = 8 downsampler = "filter-down4.sha" elif bloomconf.size == "medium": scale = 4 downsampler = "filter-copy.sha" else: scale = 2 downsampler = "filter-copy.sha" self.bloom.append(self.manager.renderQuadInto(colortex=bloom0, div=2, align=scale)) self.bloom.append(self.manager.renderQuadInto(colortex=bloom1, div=scale, align=scale)) self.bloom.append(self.manager.renderQuadInto(colortex=bloom2, div=scale, align=scale)) self.bloom.append(self.manager.renderQuadInto(colortex=bloom3, div=scale, align=scale)) self.bloom[0].setShaderInput("src", self.textures["color"]) self.bloom[0].setShader(self.loadShader("filter-bloomi.sha")) self.bloom[1].setShaderInput("src", bloom0) self.bloom[1].setShader(self.loadShader(downsampler)) self.bloom[2].setShaderInput("src", bloom1) self.bloom[2].setShader(self.loadShader("filter-bloomx.sha")) self.bloom[3].setShaderInput("src", bloom2) self.bloom[3].setShader(self.loadShader("filter-bloomy.sha")) text = "//Cg\n" text += "void vshader(float4 vtx_position : POSITION,\n" text += " out float4 l_position : POSITION,\n" text += " uniform float4 texpad_txcolor,\n" text += " uniform float4 texpix_txcolor,\n" text += " out float4 l_texcoordC : TEXCOORD0,\n" if configuration.has_key("CartoonInk"): text += " uniform float4 texpad_txaux,\n" text += " uniform float4 texpix_txaux,\n" text += " out float4 l_texcoordN : TEXCOORD1,\n" if configuration.has_key("Bloom"): text += " uniform float4 texpad_txbloom3,\n" text += " out float4 l_texcoordB : TEXCOORD2,\n" if configuration.has_key("BlurSharpen"): text += " uniform float4 texpad_txblur1,\n" text += " out float4 l_texcoordBS : TEXCOORD3,\n" if configuration.has_key("AmbientOcclusion"): text += " uniform float4 texpad_txssao2,\n" text += " out float4 l_texcoordAO : TEXCOORD4,\n" text += " uniform float4x4 mat_modelproj)\n" text += "{\n" text += " l_position=mul(mat_modelproj, vtx_position);\n" text += " l_texcoordC=(vtx_position.xzxz * texpad_txcolor) + texpad_txcolor;\n" if configuration.has_key("CartoonInk"): text += " l_texcoordN=(vtx_position.xzxz * texpad_txaux) + texpad_txaux;\n" if configuration.has_key("Bloom"): text += " l_texcoordB=(vtx_position.xzxz * texpad_txbloom3) + texpad_txbloom3;\n" if configuration.has_key("BlurSharpen"): text += " l_texcoordBS=(vtx_position.xzxz * texpad_txblur1) + texpad_txblur1;\n" if configuration.has_key("AmbientOcclusion"): text += " l_texcoordAO=(vtx_position.xzxz * texpad_txssao2) + texpad_txssao2;\n" if configuration.has_key("HalfPixelShift"): text += " l_texcoordC+=texpix_txcolor*0.5;\n" if configuration.has_key("CartoonInk"): text += " l_texcoordN+=texpix_txaux*0.5;\n" text += "}\n" text += "void fshader(\n" text += "float4 l_texcoordC : TEXCOORD0,\n" text += "uniform float4 texpix_txcolor,\n" if configuration.has_key("CartoonInk"): text += "float4 l_texcoordN : TEXCOORD1,\n" text += "uniform float4 texpix_txaux,\n" if configuration.has_key("Bloom"): text += "float4 l_texcoordB : TEXCOORD2,\n" if configuration.has_key("BlurSharpen"): text += "float4 l_texcoordBS : TEXCOORD3,\n" text += "uniform float4 k_blurval,\n" if configuration.has_key("AmbientOcclusion"): text += "float4 l_texcoordAO : TEXCOORD4,\n" for key in self.textures: text += "uniform sampler2D k_tx" + key + ",\n" if configuration.has_key("CartoonInk"): text += "uniform float4 k_cartoonseparation,\n" if configuration.has_key("VolumetricLighting"): text += "uniform float4 k_casterpos,\n" text += "uniform float4 k_vlparams,\n" text += "out float4 o_color : COLOR)\n" text += "{\n" text += " o_color = tex2D(k_txcolor, l_texcoordC.xy);\n" if configuration.has_key("CartoonInk"): text += CARTOON_BODY if configuration.has_key("AmbientOcclusion"): text += "o_color *= tex2D(k_txssao2, l_texcoordAO.xy).r;\n" if configuration.has_key("BlurSharpen"): text += " o_color = lerp(tex2D(k_txblur1, l_texcoordBS.xy), o_color, k_blurval.x);\n" if configuration.has_key("Bloom"): text += "o_color = saturate(o_color);\n" text += "float4 bloom = 0.5*tex2D(k_txbloom3, l_texcoordB.xy);\n" text += "o_color = 1-((1-bloom)*(1-o_color));\n" if configuration.has_key("ViewGlow"): text += "o_color.r = o_color.a;\n" if configuration.has_key("VolumetricLighting"): text += "float decay = 1.0f;\n" text += "float2 curcoord = l_texcoordC.xy;\n" text += "float2 lightdir = curcoord - k_casterpos.xy;\n" text += "lightdir *= k_vlparams.x;\n" text += "half4 sample = tex2D(k_txcolor, curcoord);\n" text += "float3 vlcolor = sample.rgb * sample.a;\n" text += "for (int i = 0; i < %s; i++) {\n" % int(configuration["VolumetricLighting"].numsamples) text += " curcoord -= lightdir;\n" text += " sample = tex2D(k_txcolor, curcoord);\n" text += " sample *= sample.a * decay;//*weight\n" text += " vlcolor += sample.rgb;\n" text += " decay *= k_vlparams.y;\n" text += "}\n" text += "o_color += float4(vlcolor * k_vlparams.z, 1);\n" if configuration.has_key("Inverted"): text += "o_color = float4(1, 1, 1, 1) - o_color;\n" text += "}\n" self.finalQuad.setShader(Shader.make(text)) for tex in self.textures: self.finalQuad.setShaderInput("tx" + tex, self.textures[tex]) self.task = taskMgr.add(self.update, "common-filters-update") if (changed == "CartoonInk") or fullrebuild: if configuration.has_key("CartoonInk"): separation = configuration["CartoonInk"] self.finalQuad.setShaderInput("cartoonseparation", Vec4(separation, 0, separation, 0)) if (changed == "BlurSharpen") or fullrebuild: if configuration.has_key("BlurSharpen"): blurval = configuration["BlurSharpen"] self.finalQuad.setShaderInput("blurval", Vec4(blurval, blurval, blurval, blurval)) if (changed == "Bloom") or fullrebuild: if configuration.has_key("Bloom"): bloomconf = configuration["Bloom"] intensity = bloomconf.intensity * 3.0 self.bloom[0].setShaderInput( "blend", bloomconf.blendx, bloomconf.blendy, bloomconf.blendz, bloomconf.blendw * 2.0 ) self.bloom[0].setShaderInput( "trigger", bloomconf.mintrigger, 1.0 / (bloomconf.maxtrigger - bloomconf.mintrigger), 0.0, 0.0 ) self.bloom[0].setShaderInput("desat", bloomconf.desat) self.bloom[3].setShaderInput("intensity", intensity, intensity, intensity, intensity) if (changed == "VolumetricLighting") or fullrebuild: if configuration.has_key("VolumetricLighting"): config = configuration["VolumetricLighting"] tcparam = config.density / float(config.numsamples) self.finalQuad.setShaderInput("vlparams", tcparam, config.decay, config.exposure, 0.0) if (changed == "AmbientOcclusion") or fullrebuild: if configuration.has_key("AmbientOcclusion"): config = configuration["AmbientOcclusion"] self.ssao[0].setShaderInput( "params1", config.numsamples, -float(config.amount) / config.numsamples, config.radius, 0 ) self.ssao[0].setShaderInput("params2", config.strength, config.falloff, 0, 0) self.update() return True
def __init__(self, filters): self.filters = filters self.updateTask = None self.finalQuad = None self.sun = base.cam.attachNewNode('sun') loader.loadModel("models/sphere").reparentTo(self.sun) self.sun.setScale(0.08) self.sun.setTwoSided(True) self.sun.setColorScale(1.0, 1.0, 1.0, 1.0, 10001) self.sun.setLightOff(1) self.sun.setShaderOff(1) self.sun.setFogOff(1) self.sun.setCompass() self.sun.setBin('background', 2) self.sun.setDepthWrite(False) self.sun.setDepthTest(False) # Workaround an annoyance in Panda. No idea why it's needed. self.sun.node().setBounds(OmniBoundingVolume()) direct = Vec4(2.0, 1.9, 1.8, 1) #bright for hdr #direct = Vec4(0.7, 0.65, 0.6, 1) self.dlight = DirectionalLight('dlight') self.dlight.setColor(direct) dlnp = self.sun.attachNewNode(self.dlight) render.setLight(dlnp) render.setShaderInput('dlight0', dlnp) self.setTime(700.0) pandaVolumetricLighting = False if pandaVolumetricLighting: self.filters.setVolumetricLighting( dlnp ) else: self.vlbuffer = base.win.makeTextureBuffer('volumetric-lighting', base.win.getXSize() / 2, base.win.getYSize() / 2) self.vlbuffer.setClearColor(Vec4(0, 0, 0, 1)) cam = base.makeCamera(self.vlbuffer) cam.node().setLens(base.camLens) cam.reparentTo(base.cam) initstatenode = NodePath('InitialState') initstatenode.setColorScale(0, 0, 0, 1, 10000) initstatenode.setShaderOff(10000) initstatenode.setFogOff(1) initstatenode.setLightOff(10000) initstatenode.setMaterialOff(10000) initstatenode.setTransparency(TransparencyAttrib.MBinary, 10000) cam.node().setCameraMask(BitMask32.bit(2)) cam.node().setInitialState(initstatenode.getState()) self.vltexture = self.vlbuffer.getTexture() self.vltexture.setWrapU(Texture.WMClamp) self.vltexture.setWrapV(Texture.WMClamp) card = CardMaker('VolumetricLightingCard') card.setFrameFullscreenQuad() self.finalQuad = render2d.attachNewNode(card.generate()) self.finalQuad.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OIncomingColor, ColorBlendAttrib.OFbufferColor)) self.finalQuad.setShader(Shader.load("shaders/filter-vlight.cg")) self.finalQuad.setShaderInput('src', self.vltexture) self.finalQuad.setShaderInput('vlparams', 32, 0.95 / 32.0, 0.985, 0.5) # Note - first 32 is now hardcoded into shader for cards that don't support variable sized loops. self.finalQuad.setShaderInput('casterpos', 0.5, 0.5, 0, 0) # Last parameter to vlcolor is the exposure vlcolor = Vec4(1, 0.99, 0.80, 0.03) self.finalQuad.setShaderInput('vlcolor', vlcolor) self.start()
def reconfigure(self, fullrebuild, changed): configuration = self.configuration if fullrebuild: self.cleanup() if len(configuration) == 0: return None auxbits = 0 needtex = {} needtex['color'] = True if configuration.has_key('CartoonInk'): needtex['aux'] = True auxbits |= AuxBitplaneAttrib.ABOAuxNormal if configuration.has_key('AmbientOcclusion'): needtex['depth'] = True needtex['ssao0'] = True needtex['ssao1'] = True needtex['ssao2'] = True needtex['aux'] = True auxbits |= AuxBitplaneAttrib.ABOAuxNormal if configuration.has_key('BlurSharpen'): needtex['blur0'] = True needtex['blur1'] = True if configuration.has_key('Bloom'): needtex['bloom0'] = True needtex['bloom1'] = True needtex['bloom2'] = True needtex['bloom3'] = True auxbits |= AuxBitplaneAttrib.ABOGlow if configuration.has_key('ViewGlow'): auxbits |= AuxBitplaneAttrib.ABOGlow for tex in needtex: self.textures[tex] = Texture('scene-' + tex) self.textures[tex].setWrapU(Texture.WMClamp) self.textures[tex].setWrapV(Texture.WMClamp) needtexpix = True self.finalQuad = self.manager.renderSceneInto( textures=self.textures, auxbits=auxbits) if self.finalQuad == None: self.cleanup() return False if configuration.has_key('BlurSharpen'): blur0 = self.textures['blur0'] blur1 = self.textures['blur1'] self.blur.append( self.manager.renderQuadInto(colortex=blur0, div=2)) self.blur.append(self.manager.renderQuadInto(colortex=blur1)) self.blur[0].setShaderInput('src', self.textures['color']) self.blur[0].setShader(self.loadShader('filter-blurx.sha')) self.blur[1].setShaderInput('src', blur0) self.blur[1].setShader(self.loadShader('filter-blury.sha')) if configuration.has_key('AmbientOcclusion'): ssao0 = self.textures['ssao0'] ssao1 = self.textures['ssao1'] ssao2 = self.textures['ssao2'] self.ssao.append(self.manager.renderQuadInto(colortex=ssao0)) self.ssao.append( self.manager.renderQuadInto(colortex=ssao1, div=2)) self.ssao.append(self.manager.renderQuadInto(colortex=ssao2)) self.ssao[0].setShaderInput('depth', self.textures['depth']) self.ssao[0].setShaderInput('normal', self.textures['aux']) self.ssao[0].setShaderInput( 'random', loader.loadTexture('maps/random.rgb')) self.ssao[0].setShader(self.loadShader('filter-ssao.sha')) self.ssao[1].setShaderInput('src', ssao0) self.ssao[1].setShader(self.loadShader('filter-blurx.sha')) self.ssao[2].setShaderInput('src', ssao1) self.ssao[2].setShader(self.loadShader('filter-blury.sha')) if configuration.has_key('Bloom'): bloomconf = configuration['Bloom'] bloom0 = self.textures['bloom0'] bloom1 = self.textures['bloom1'] bloom2 = self.textures['bloom2'] bloom3 = self.textures['bloom3'] if bloomconf.size == 'large': scale = 8 downsampler = 'filter-down4.sha' elif bloomconf.size == 'medium': scale = 4 downsampler = 'filter-copy.sha' else: scale = 2 downsampler = 'filter-copy.sha' self.bloom.append( self.manager.renderQuadInto(colortex=bloom0, div=2, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom1, div=scale, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom2, div=scale, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom3, div=scale, align=scale)) self.bloom[0].setShaderInput('src', self.textures['color']) self.bloom[0].setShader(self.loadShader('filter-bloomi.sha')) self.bloom[1].setShaderInput('src', bloom0) self.bloom[1].setShader(self.loadShader(downsampler)) self.bloom[2].setShaderInput('src', bloom1) self.bloom[2].setShader(self.loadShader('filter-bloomx.sha')) self.bloom[3].setShaderInput('src', bloom2) self.bloom[3].setShader(self.loadShader('filter-bloomy.sha')) text = '//Cg\n' text += 'void vshader(float4 vtx_position : POSITION,\n' text += ' out float4 l_position : POSITION,\n' text += ' uniform float4 texpad_txcolor,\n' text += ' uniform float4 texpix_txcolor,\n' text += ' out float4 l_texcoordC : TEXCOORD0,\n' if configuration.has_key('CartoonInk'): text += ' uniform float4 texpad_txaux,\n' text += ' uniform float4 texpix_txaux,\n' text += ' out float4 l_texcoordN : TEXCOORD1,\n' if configuration.has_key('Bloom'): text += ' uniform float4 texpad_txbloom3,\n' text += ' out float4 l_texcoordB : TEXCOORD2,\n' if configuration.has_key('BlurSharpen'): text += ' uniform float4 texpad_txblur1,\n' text += ' out float4 l_texcoordBS : TEXCOORD3,\n' if configuration.has_key('AmbientOcclusion'): text += ' uniform float4 texpad_txssao2,\n' text += ' out float4 l_texcoordAO : TEXCOORD4,\n' text += ' uniform float4x4 mat_modelproj)\n' text += '{\n' text += ' l_position=mul(mat_modelproj, vtx_position);\n' text += ' l_texcoordC=(vtx_position.xzxz * texpad_txcolor) + texpad_txcolor;\n' if configuration.has_key('CartoonInk'): text += ' l_texcoordN=(vtx_position.xzxz * texpad_txaux) + texpad_txaux;\n' if configuration.has_key('Bloom'): text += ' l_texcoordB=(vtx_position.xzxz * texpad_txbloom3) + texpad_txbloom3;\n' if configuration.has_key('BlurSharpen'): text += ' l_texcoordBS=(vtx_position.xzxz * texpad_txblur1) + texpad_txblur1;\n' if configuration.has_key('AmbientOcclusion'): text += ' l_texcoordAO=(vtx_position.xzxz * texpad_txssao2) + texpad_txssao2;\n' if configuration.has_key('HalfPixelShift'): text += ' l_texcoordC+=texpix_txcolor*0.5;\n' if configuration.has_key('CartoonInk'): text += ' l_texcoordN+=texpix_txaux*0.5;\n' text += '}\n' text += 'void fshader(\n' text += 'float4 l_texcoordC : TEXCOORD0,\n' text += 'uniform float4 texpix_txcolor,\n' if configuration.has_key('CartoonInk'): text += 'float4 l_texcoordN : TEXCOORD1,\n' text += 'uniform float4 texpix_txaux,\n' if configuration.has_key('Bloom'): text += 'float4 l_texcoordB : TEXCOORD2,\n' if configuration.has_key('BlurSharpen'): text += 'float4 l_texcoordBS : TEXCOORD3,\n' text += 'uniform float4 k_blurval,\n' if configuration.has_key('AmbientOcclusion'): text += 'float4 l_texcoordAO : TEXCOORD4,\n' for key in self.textures: text += 'uniform sampler2D k_tx' + key + ',\n' if configuration.has_key('CartoonInk'): text += 'uniform float4 k_cartoonseparation,\n' if configuration.has_key('VolumetricLighting'): text += 'uniform float4 k_casterpos,\n' text += 'uniform float4 k_vlparams,\n' text += 'out float4 o_color : COLOR)\n' text += '{\n' text += ' o_color = tex2D(k_txcolor, l_texcoordC.xy);\n' if configuration.has_key('CartoonInk'): text += CARTOON_BODY if configuration.has_key('AmbientOcclusion'): text += 'o_color *= tex2D(k_txssao2, l_texcoordAO.xy).r;\n' if configuration.has_key('BlurSharpen'): text += ' o_color = lerp(tex2D(k_txblur1, l_texcoordBS.xy), o_color, k_blurval.x);\n' if configuration.has_key('Bloom'): text += 'o_color = saturate(o_color);\n' text += 'float4 bloom = 0.5*tex2D(k_txbloom3, l_texcoordB.xy);\n' text += 'o_color = 1-((1-bloom)*(1-o_color));\n' if configuration.has_key('ViewGlow'): text += 'o_color.r = o_color.a;\n' if configuration.has_key('VolumetricLighting'): text += 'float decay = 1.0f;\n' text += 'float2 curcoord = l_texcoordC.xy;\n' text += 'float2 lightdir = curcoord - k_casterpos.xy;\n' text += 'lightdir *= k_vlparams.y;\n' text += 'half4 sample = tex2D(k_txcolor, curcoord);\n' text += 'float3 vlcolor = sample.rgb * sample.a;\n' text += 'for (int i = 0; i < k_vlparams.x; i++) {\n' text += ' curcoord -= lightdir;\n' text += ' sample = tex2D(k_txcolor, curcoord);\n' text += ' sample *= sample.a * decay;//*weight\n' text += ' vlcolor += sample.rgb;\n' text += ' decay *= k_vlparams.z;\n' text += '}\n' text += 'o_color += float4(vlcolor * k_vlparams.w, 1);\n' if configuration.has_key('Inverted'): text += 'o_color = float4(1, 1, 1, 1) - o_color;\n' text += '}\n' self.finalQuad.setShader(Shader.make(text)) for tex in self.textures: self.finalQuad.setShaderInput('tx' + tex, self.textures[tex]) self.task = taskMgr.add(self.update, 'common-filters-update') if changed == 'CartoonInk' or fullrebuild: if configuration.has_key('CartoonInk'): separation = configuration['CartoonInk'] self.finalQuad.setShaderInput( 'cartoonseparation', Vec4(separation, 0, separation, 0)) if changed == 'BlurSharpen' or fullrebuild: if configuration.has_key('BlurSharpen'): blurval = configuration['BlurSharpen'] self.finalQuad.setShaderInput( 'blurval', Vec4(blurval, blurval, blurval, blurval)) if changed == 'Bloom' or fullrebuild: if configuration.has_key('Bloom'): bloomconf = configuration['Bloom'] intensity = bloomconf.intensity * 3.0 self.bloom[0].setShaderInput('blend', bloomconf.blendx, bloomconf.blendy, bloomconf.blendz, bloomconf.blendw * 2.0) self.bloom[0].setShaderInput( 'trigger', bloomconf.mintrigger, 1.0 / (bloomconf.maxtrigger - bloomconf.mintrigger), 0.0, 0.0) self.bloom[0].setShaderInput('desat', bloomconf.desat) self.bloom[3].setShaderInput('intensity', intensity, intensity, intensity, intensity) if changed == 'VolumetricLighting' or fullrebuild: if configuration.has_key('VolumetricLighting'): config = configuration['VolumetricLighting'] tcparam = config.density / float(config.numsamples) self.finalQuad.setShaderInput('vlparams', config.numsamples, tcparam, config.decay, config.exposure) if changed == 'AmbientOcclusion' or fullrebuild: if configuration.has_key('AmbientOcclusion'): config = configuration['AmbientOcclusion'] self.ssao[0].setShaderInput( 'params1', config.numsamples, -float(config.amount) / config.numsamples, config.radius, 0) self.ssao[0].setShaderInput('params2', config.strength, config.falloff, 0, 0) self.update() return True
def Make(self): """Makes a new shader object.""" return Shader.make(self.Write())