From dc940ebffb4c9d32f4006499e23b0aff259739ef Mon Sep 17 00:00:00 2001 From: tobspr Date: Thu, 13 Aug 2015 09:45:38 +0200 Subject: [PATCH] =?UTF-8?q?Support=20for=20multi-bounce=20GI,=20add=20"Wri?= =?UTF-8?q?te=20to=20Disk"=20button,=20fix=20bug=20when=20using=20a=20128?= =?UTF-8?q?=C2=B3=20voxel=20grid,=20Add=20example=20instancing=20effect?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Code/GUI/BufferViewerGUI.py | 8 ++ Code/GUI/FastText.py | 7 +- Code/GlobalIllumination.py | 48 ++++++------ Code/LightManager.py | 16 ++-- Code/MemoryMonitor.py | 17 ++++- Code/RenderPasses/AmbientOcclusionPass.py | 3 - Code/RenderPasses/ViewSpacePass.py | 3 +- Code/RenderingPipeline.py | 5 +- Config/configuration.prc | 6 +- Config/pipeline.ini | 9 ++- Data/Textures/font.png | Bin 3919 -> 7846 bytes Effects/DisplayVoxels.effect | 67 +++++++++++------ Effects/Examples/ExampleTreeInstanced.effect | 32 ++++++++ Effects/Skybox/Skybox.effect | 2 +- Samples/02-Roaming-Ralph/Tut-Roaming-Ralph.py | 4 +- Shader/BloomExtract.fragment | 4 +- Shader/BloomMerge.fragment | 2 +- Shader/DefaultShaders/Default/fragment.glsl | 7 +- Shader/DefaultShaders/Default/vertex.glsl | 1 + Shader/DefaultShaders/Shadows/fragment.glsl | 5 +- Shader/DefaultShaders/Voxelize/fragment.glsl | 8 +- Shader/DefaultShaders/Voxelize/vertex.glsl | 1 + Shader/ExposurePass.fragment | 15 ++-- Shader/FinalPostprocessPass.fragment | 9 ++- Shader/GI/ClearGrid.fragment | 8 ++ Shader/GI/ConvertGrid.fragment | 9 ++- Shader/GI/Distribute.fragment | 44 ++++++----- Shader/Includes/Ambient.include | 16 ++-- Shader/Includes/CommonFunctions.include | 14 ++++ Shader/Includes/Configuration.include | 1 + Shader/Includes/GlobalIllumination.include | 32 +++++--- Shader/Includes/Material.include | 2 +- .../Includes/PositionReconstruction.include | 8 ++ Shader/Includes/VoxelGeneration.include | 17 ++--- Shader/LightingPass.fragment | 2 +- Shader/Occlusion/HBAO.include | 70 +++++++++--------- Shader/Occlusion/SAO.include | 24 ++++-- Shader/ScatteringCubemapPass.fragment | 13 +--- Shader/ScatteringPass.fragment | 4 +- Shader/ViewSpacePass.fragment | 35 ++++----- main.py | 30 ++++---- 41 files changed, 360 insertions(+), 248 deletions(-) create mode 100644 Effects/Examples/ExampleTreeInstanced.effect diff --git a/Code/GUI/BufferViewerGUI.py b/Code/GUI/BufferViewerGUI.py index 01a02c8de..32ab9ede6 100644 --- a/Code/GUI/BufferViewerGUI.py +++ b/Code/GUI/BufferViewerGUI.py @@ -193,6 +193,14 @@ def showDetail(self, tex, coord): backBtn = BetterButton( self.buffersParent, 230, 2, "Back", callback=self.renderBuffers) + writeBtn = BetterButton( + self.buffersParent, 350, 2, "Write to Disk", callback=partial(self.writeTexToDisk, tex)) + + def writeTexToDisk(self, tex): + print "Writing",tex,"to disk .." + Globals.base.graphicsEngine.extractTextureData(tex, Globals.base.win.getGsg()) + tex.write(tex.getName() + ".png") + print "Done!" def onMouseOver(self, node, a): node['frameColor'] = (1, 1, 1, 0.4) diff --git a/Code/GUI/FastText.py b/Code/GUI/FastText.py index f7b4d9726..2ed19f739 100644 --- a/Code/GUI/FastText.py +++ b/Code/GUI/FastText.py @@ -79,6 +79,7 @@ def _prepareFontTextures(self): self.fontTex.setMinfilter(Texture.FTLinear) self.fontTex.setMagfilter(Texture.FTLinear) self.fontTex.setAnisotropicDegree(16) + self.fontTex.setFormat(Texture.FRgba) def _loadCharset(self): self.charset = """ !"#$%&'()*+,-./""" @@ -109,13 +110,11 @@ def _makeFontShader(self): texcoord = clamp(p3d_MultiTexCoord0, halfOffset, 1.0 - halfOffset) / vec2(16,6) + offsetCoordReal; vec4 offset = vec4(gl_InstanceID*size.x*0.56 , 0, 0, 0) + vec4(pos.x, 0, pos.y, 0); - vec4 finalPos = p3d_Vertex * vec4(size.xxx, 1.0) + offset; gl_Position = p3d_ModelViewProjectionMatrix * finalPos; } """, """ #version 150 - #pragma file FastText.fragment in vec2 texcoord; uniform sampler2D font; uniform vec3 color; @@ -149,9 +148,9 @@ def _makeSquare(self): c.setFrame(-0.5, 0.5, -0.5, 0.5) self.square = NodePath(c.generate()) self.square.setShaderInput("font", self.fontTex) - self.square.setShader(self.fontShader, 100) + self.square.setShader(self.fontShader, 1000) self.square.setAttrib( - TransparencyAttrib.make(TransparencyAttrib.MAlpha), 100) + TransparencyAttrib.make(TransparencyAttrib.MAlpha), 1000) self.square.reparentTo(Globals.base.aspect2d) return self.square diff --git a/Code/GlobalIllumination.py b/Code/GlobalIllumination.py index 5418f7548..7dd5f7ef5 100644 --- a/Code/GlobalIllumination.py +++ b/Code/GlobalIllumination.py @@ -16,6 +16,7 @@ from SettingsManager import SettingsManager from MemoryMonitor import MemoryMonitor from DistributedTaskManager import DistributedTaskManager +from GUI.FastText import FastText from RenderPasses.GlobalIlluminationPass import GlobalIlluminationPass from RenderPasses.VoxelizePass import VoxelizePass @@ -62,12 +63,12 @@ def __init__(self, pipeline): self.voxelGridSize = self.pipeline.settings.giVoxelGridSize # Grid resolution in pixels - self.voxelGridResolution = 64 + self.voxelGridResolution = 128 # Has to be a multiple of 2 - self.distributionSteps = 30 - - self.slideCount = int(math.sqrt(self.voxelGridResolution)) + self.distributionSteps = 40 + self.slideCount = int(self.voxelGridResolution / 8) + self.slideVertCount = self.voxelGridResolution / self.slideCount self.bounds = BoundingBox() self.renderCount = 0 @@ -85,24 +86,16 @@ def __init__(self, pipeline): self.frameIndex = 0 self.steps = [] - - def _createDebugTexts(self): """ Creates a debug overlay to show GI status """ self.debugText = None self.buildingText = None if self.pipeline.settings.displayDebugStats: - try: - from .GUI.FastText import FastText - self.debugText = FastText(pos=Vec2( - Globals.base.getAspectRatio() - 0.1, 0.88), rightAligned=True, color=Vec3(1, 1, 0), size=0.03) - self.buildingText = FastText(pos=Vec2(-0.3, 0), rightAligned=False, color=Vec3(1, 1, 0), size=0.03) - self.buildingText.setText("PREPARING GI, PLEASE BE PATIENT ....") - - except Exception, msg: - self.debug( - "GI-Debug text is disabled because FastText wasn't loaded") + self.debugText = FastText(pos=Vec2( + Globals.base.getAspectRatio() - 0.1, 0.88), rightAligned=True, color=Vec3(1, 1, 0), size=0.03) + self.buildingText = FastText(pos=Vec2(-0.3, 0), rightAligned=False, color=Vec3(1, 1, 0), size=0.03) + self.buildingText.setText("PREPARING GI, PLEASE BE PATIENT ....") def stepVoxelize(self, idx): @@ -126,14 +119,13 @@ def stepVoxelize(self, idx): self.buildingText.remove() self.buildingText = None - self.voxelizePass.voxelizeSceneFromDirection(self.gridPosTemp[0], "yxz"[idx]) + self.voxelizePass.voxelizeSceneFromDirection(self.gridPosTemp[0], "xyz"[idx]) def stepDistribute(self, idx): if idx == 0: - self.convertGridTarget.setActive(True) - + self.convertGridTarget.setActive(True) self.distributeTarget.setActive(True) @@ -143,14 +135,14 @@ def stepDistribute(self, idx): if idx == self.distributionSteps - 1: self.publishGrid() - - dests = self.dataTextures for i in xrange(5): self.distributeTarget.setShaderInput("src" + str(i), sources[i]) self.distributeTarget.setShaderInput("dst" + str(i), dests[i]) + self.distributeTarget.setShaderInput("isLastStep", idx >= self.distributionSteps-4) + def publishGrid(self): """ This function gets called when the grid is ready to be used, and updates the live grid data """ @@ -219,7 +211,7 @@ def setup(self): self.bindTo(Globals.render, "giData") self.convertGridTarget = RenderTarget("ConvertGIGrid") - self.convertGridTarget.setSize(self.voxelGridResolution * self.slideCount, self.voxelGridResolution * self.slideCount) + self.convertGridTarget.setSize(self.voxelGridResolution * self.slideCount, self.voxelGridResolution * self.slideVertCount) if self.pipeline.settings.useDebugAttachments: self.convertGridTarget.addColorTexture() @@ -231,7 +223,7 @@ def setup(self): self.convertGridTarget.getColorTexture().setMagfilter(Texture.FTNearest) self.clearGridTarget = RenderTarget("ClearGIGrid") - self.clearGridTarget.setSize(self.voxelGridResolution * self.slideCount, self.voxelGridResolution * self.slideCount) + self.clearGridTarget.setSize(self.voxelGridResolution * self.slideCount, self.voxelGridResolution * self.slideVertCount) if self.pipeline.settings.useDebugAttachments: self.clearGridTarget.addColorTexture() self.clearGridTarget.prepareOffscreenBuffer() @@ -240,6 +232,7 @@ def setup(self): self.convertGridTarget.setShaderInput("voxelGenSrc" + color.upper(), self.generationTextures[idx]) self.clearGridTarget.setShaderInput("voxelGenTex" + color.upper(), self.generationTextures[idx]) + # Create the data textures self.dataTextures = [] @@ -267,10 +260,10 @@ def setup(self): self.pongDataTextures.append(texPong) self.convertGridTarget.setShaderInput("voxelDataDest"+str(i), self.pingDataTextures[i]) - + # self.clearGridTarget.setShaderInput("voxelDataDest" + str(i), self.pongDataTextures[i]) # Set texture wrap modes - for tex in self.pingDataTextures + self.pongDataTextures + self.dataTextures: + for tex in self.pingDataTextures + self.pongDataTextures + self.dataTextures + self.generationTextures: tex.setMinfilter(Texture.FTNearest) tex.setMagfilter(Texture.FTNearest) tex.setWrapU(Texture.WMBorderColor) @@ -283,7 +276,7 @@ def setup(self): tex.setMagfilter(Texture.FTLinear) self.distributeTarget = RenderTarget("DistributeVoxels") - self.distributeTarget.setSize(self.voxelGridResolution * self.slideCount, self.voxelGridResolution * self.slideCount) + self.distributeTarget.setSize(self.voxelGridResolution * self.slideCount, self.voxelGridResolution * self.slideVertCount) if self.pipeline.settings.useDebugAttachments: self.distributeTarget.addColorTexture() @@ -294,6 +287,7 @@ def setup(self): self.distributeTarget.getColorTexture().setMinfilter(Texture.FTNearest) self.distributeTarget.getColorTexture().setMagfilter(Texture.FTNearest) + # Create the various render targets to generate the mipmaps of the stable voxel grid # self.mipmapTargets = [] # computeSize = self.voxelGridResolution @@ -326,7 +320,7 @@ def setup(self): if False: self.voxelCube = loader.loadModel("Box") self.voxelCube.reparentTo(render) - self.voxelCube.setTwoSided(True) + # self.voxelCube.setTwoSided(True) self.voxelCube.node().setFinal(True) self.voxelCube.node().setBounds(OmniBoundingVolume()) self.voxelCube.setInstanceCount(self.voxelGridResolution**3) diff --git a/Code/LightManager.py b/Code/LightManager.py index 1b25ecf8e..de2b3c7d5 100644 --- a/Code/LightManager.py +++ b/Code/LightManager.py @@ -31,6 +31,8 @@ from RenderPasses.ShadowedLightsPass import ShadowedLightsPass from RenderPasses.ExposurePass import ExposurePass +from GUI.FastText import FastText + pstats_ProcessLights = PStatCollector("App:LightManager:ProcessLights") pstats_CullLights = PStatCollector("App:LightManager:CullLights") pstats_PerLightUpdates = PStatCollector("App:LightManager:PerLightUpdates") @@ -298,16 +300,10 @@ def _createDebugTexts(self): self.lightsUpdatedDebugText = None if self.pipeline.settings.displayDebugStats: - try: - from .GUI.FastText import FastText - self.lightsVisibleDebugText = FastText(pos=Vec2( - Globals.base.getAspectRatio() - 0.1, 0.84), rightAligned=True, color=Vec3(1, 1, 0), size=0.03) - self.lightsUpdatedDebugText = FastText(pos=Vec2( - Globals.base.getAspectRatio() - 0.1, 0.8), rightAligned=True, color=Vec3(1, 1, 0), size=0.03) - - except Exception, msg: - self.debug( - "Overlay is disabled because FastText wasn't loaded") + self.lightsVisibleDebugText = FastText(pos=Vec2( + Globals.base.getAspectRatio() - 0.1, 0.84), rightAligned=True, color=Vec3(1, 1, 0), size=0.03) + self.lightsUpdatedDebugText = FastText(pos=Vec2( + Globals.base.getAspectRatio() - 0.1, 0.8), rightAligned=True, color=Vec3(1, 1, 0), size=0.03) def _queueShadowUpdate(self, sourceIndex): """ Internal method to add a shadowSource to the list of queued updates. Returns diff --git a/Code/MemoryMonitor.py b/Code/MemoryMonitor.py index 2c5a96c96..39d7b345d 100644 --- a/Code/MemoryMonitor.py +++ b/Code/MemoryMonitor.py @@ -21,12 +21,13 @@ def _calculateTexSize(self, tex): # Assign the texture format a size textureTypes = { - 6: 1, # ALPHA + 3: 1, # FRED + 6: 1, # ALPHA 7: 3 * 1, # RGB (Unkown type, we will just assume 8 bit) 9: 3 * 1, # FRGBA8 - 12: 4 * 1, # RGBA (Unkown type, we will just assume 8 bit) - 18: 1, # LUMINANCE - 19: 2, # LUMINANCE_ALPHA + 12: 4 * 1,# RGBA (Unkown type, we will just assume 8 bit) + 18: 1, # LUMINANCE + 19: 2, # LUMINANCE_ALPHA 16: 4 * 1, # RGBA8 21: 4 * 2, # RGBA16 22: 4 * 4, # RGBA32 @@ -40,6 +41,7 @@ def _calculateTexSize(self, tex): 35: 4, # FR32 } + # Get format and compute size per component form = tex.getFormat() componentSize = 0 @@ -52,6 +54,13 @@ def _calculateTexSize(self, tex): # Fetch the amount of pixels pixelCount = tex.getXSize() * tex.getYSize() * tex.getZSize() + # Check for deprecated formats + deprecated = [18, 19, 6] + + if form in deprecated: + # print "DEPRECATED FORMAT:", form, "USED BY",tex.getName() + pass + # Mipmaps take approx 33% of the texture size, so just multiply the pixel # count by that amount if tex.usesMipmaps(): diff --git a/Code/RenderPasses/AmbientOcclusionPass.py b/Code/RenderPasses/AmbientOcclusionPass.py index bf9cb2717..1a61ecca7 100644 --- a/Code/RenderPasses/AmbientOcclusionPass.py +++ b/Code/RenderPasses/AmbientOcclusionPass.py @@ -23,9 +23,6 @@ def getRequiredInputs(self): "frameIndex": "Variables.frameIndex", "mainRender": "Variables.mainRender", "mainCam": "Variables.mainCam", - "noiseTexture": "Variables.noise4x4", - "viewSpaceNormals": "ViewSpacePass.normals", - "viewSpacePosition": "ViewSpacePass.position", "depthTex": "DeferredScenePass.depth", "cameraPosition": "Variables.cameraPosition", "currentViewMat": "Variables.currentViewMat", diff --git a/Code/RenderPasses/ViewSpacePass.py b/Code/RenderPasses/ViewSpacePass.py index 7bbc26fb8..b2d1e1300 100644 --- a/Code/RenderPasses/ViewSpacePass.py +++ b/Code/RenderPasses/ViewSpacePass.py @@ -22,7 +22,8 @@ def getRequiredInputs(self): "depthTex": "DeferredScenePass.depth", "mainRender": "Variables.mainRender", "mainCam": "Variables.mainCam", - "currentViewMat": "Variables.currentViewMat" + "currentViewMat": "Variables.currentViewMat", + "currentProjMatInv": "Variables.currentProjMatInv", } def create(self): diff --git a/Code/RenderingPipeline.py b/Code/RenderingPipeline.py index 00bed138a..27cdc8513 100644 --- a/Code/RenderingPipeline.py +++ b/Code/RenderingPipeline.py @@ -225,6 +225,7 @@ def getDefaultSkybox(self, scale=60000): skytex.setWrapV(SamplerState.WMRepeat) skytex.setMinfilter(SamplerState.FTLinear) skytex.setMagfilter(SamplerState.FTLinear) + skytex.setFormat(Texture.FRed) skybox.setShaderInput("skytex", skytex) self.setEffect(skybox, "Effects/Skybox/Skybox.effect", { "castShadows": False, @@ -554,8 +555,8 @@ def _setGuiShaders(self): shader = Shader.load(Shader.SLGLSL, "Shader/GUI/vertex.glsl", "Shader/GUI/fragment.glsl") for target in [self.showbase.aspect2d, self.showbase.render2d, self.showbase.pixel2d, self.showbase.aspect2dp, self.showbase.render2dp, self.showbase.pixel2dp]: - target.setShader(shader, 50) - + # target.setShader(shader, 50) + pass def create(self): """ Creates the pipeline """ diff --git a/Config/configuration.prc b/Config/configuration.prc index f2e2da34a..f8bec72ff 100644 --- a/Config/configuration.prc +++ b/Config/configuration.prc @@ -120,7 +120,7 @@ gl-force-fbo-color false # Set the minimum openGL version -gl-version 3 2 +#gl-version 3 2 # Animations on the gpu. This is WIP, the default shader has to get adjusted first! # hardware-animated-vertices #t @@ -172,6 +172,8 @@ gl-debug-object-labels #f + # Default window settings depth-bits 0 -color-bits 0 \ No newline at end of file +color-bits 0 + diff --git a/Config/pipeline.ini b/Config/pipeline.ini index 11577c45f..46326a5ce 100644 --- a/Config/pipeline.ini +++ b/Config/pipeline.ini @@ -86,7 +86,7 @@ # Size of the generated cubemap for the scattering, used for the ambient term # and reflections - scatteringCubemapSize = 256 + scatteringCubemapSize = 128 [SSLR] @@ -111,8 +111,9 @@ # Todo: Write explanation of all techniques occlusionTechnique = "HBAO" - # Radius of the occlusion - occlusionRadius = 1.0 + # Radius of the occlusion in pixels, higher pixels mean better results but also + # worse performance. + occlusionRadius = 10.0 # Strength of the occlusion. 1.0 is default occlusionStrength = 1.0 @@ -266,4 +267,4 @@ # Wheter to a attach a color texture to buffers which don't really produce # a useful color texture. This is mainly helpful for debugging - useDebugAttachments = True + useDebugAttachments = False diff --git a/Data/Textures/font.png b/Data/Textures/font.png index 8fb5774e5c6fffd1e064a4355cdf0e3490f41bf7..3f69a9593298d2508f7503c3f240b96947a3c433 100644 GIT binary patch delta 7803 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 Dp#jNa delta 3845 zcmV+g5Bl(?J`E?NZZxqyOe zwdLdwi(nCAifpP(W(N&ncZb=ZfA$6*!Q*&?6oMB~Qd_75OTka|c+Ge&qYqs}pu zmBegf@>xFDhZ_#q0|4uqV8-JsfU2%MzbV+hp#WY_&9Fb>Z}we?0=xi8;Ts2h0ILTH z0%`$Y^p@)&pakfxr;`DwC!j0-Q2+*YXyfYUR`hwArrH$s((CKC5nnd?vT}6{b+qCO z;Cln$D2uk$nJr7Jle2_>H_PYxE4@!qfI8Xix*c~H?|=U6T)-zw8#pk|P0^B*kqRz< z4c19SK~#9!>|H&Yq&O0Nwcj3qJ_3CM%3GKA#-zPnlkvvP_10y*cE_X5U5_!xquuqW z8_-8k-QcZ(Ac0gw@RL+kcMN)(%=<;F=`M*jd)Z4J4(?irLA!99|ywG>{14@sj; zyCPvde9nJzUg;7jcZ}!=g00YcOEP9midX2p>su+6(o$&~tXZ*T!D`3-kN(M7O#Z&( z7VwPc;Zs^&{~JE%^aa2pfKLE^3nKR!5r7=O3$1?u5DmX+eUvFdj6ap~KM^B;5lcTI zLX5xR^Bd*>e@C^41GLHts96u668d`zuir#jA3XPxJCmvEUR?9JogBu|;S?c=VcE zz_JH;-TTL?2-8E<$69A_*@T3!e04JRQ05Y^7+R15pPL;A_q-a4nltTH%DDP~3PQ1h9?4tMs z6lQG-0+=)U??5!BN5EU96b%@7g3$@Lr$jiS)XF(C9n~*`r}Qh;sxgM*30zYp$KDh~ z;iOKZf2C1gnB#M#zHW(?CNa!FW6Eyz0F{66k`yd%RHg^4y(33|DqK^OOoxe-R6(s+ znhTC1;|VN%`?ac&cA^R;QTj)(0Z7F0S)$0X%H>67nUbg~(K=g6J}f173jjAXD{0be z^#STp{npT>Rbq(@kCJ3d(kZrtB^F64^?Lxc20+{)0Ej#nDuZj;0zfj1og%(rV|1;Y#^ayT(SWGrHN2| z54Y|xK1QZS`-QT~v7rC@G0-Wp_TE##amPTD1Av(q(Xves;7k^t`u6jUL)7^Tw881` z+HaIof<63y7k|nqRESinIrts`IM&=gzyE0rdQpl|E4Ied7Vy(k`R0N~P7ZJygHAdD zaMB5YlioQ1BIMqlPBbWdoNdUe?o4}oC5k|@MSWa5-el3Y$~%7q?f#+P<*Tsjn(Kcf zIJm$wTDccEcxq&UXB?M@Tax@81|2{#s1jlpL481fswiTnRExHLsf97QphjznK~yep zCZ(x*LY7bKOV06f@A{sERY{f&=BlBs0?){ihSYlgX08az*f3(m$}568mw{WONJ)mw z3A3Aqm9ZC+4I|(ER;(W_xWoF%DF-7@#74dU(Ew;fO`-*WvBA9#0-)Ei-nMiZY=AMF zsV)|OjQomghV|Dqklok>9LY%0dKT_;{TLI9H6x`PRj|4y?@XsXx z$h@s3^S_5UKsS@OEsdW)nfn8jK4`OJ4atawGib;Sn^dM7K(uT6w)@0LrOSdoZF}TC z05qbdVQKoEe*6&xKtDsbElvM3`3v3w;<`eAujUlqm_vF57RCS;Zx#UB6-NWWdAE~j zBLFJTfhz$3z0GnZ066()GB^#!vs@VMXn0y<3n0TOoL+MaNKF9j*#azw8jhAvxe)-F z-~BTY0FmIi*^aiJbiM^}Vh?Wy_s4p&Tg9^#60Zb6u}}z7F%X8sdEb71 zcL0=zKf<+UDjbuw=j;Dd4TnJq02qY$#mB(Rcc&&N`=wOo-9JjGV4RV9`#-a4m`l~ctm1g!F^r+B2ryp2&TeXTsG z$+)(eFX(^CEva6M1u+wvCL){1{;!D)np*=TRpO03d7(c5CPVLb=-R_qjV%asgUiKF zS^rXs+)wD`MpxP8A$CIOi<^9Z%i-_M#=wvzF+sY;qhYf)a&Z{|=Jw>qFb1`1ih?bV zXKU)3QFLE(Gby#_1Q);ZL)y48K*H;*G{WCIcx(?Hb2|W#kj$AY9tR5mAh9sToET(* z7j+9L4go+m3UAGVwVk)5I~7EY8vU&2AE^v@*x~irW&qSABSuCK7XhGuG;XT{K#ndf z29t7e008=_b%H4*^Fz~k*NJ8|0OFt>bjm@>U9o|g8F_s7=)!d_Rh4HlPUu*ds;N-3 z;N&~)?ebM!2zp2a?Gwxte)kXi9qLs?L7bxnF(s{3xG|=pwm-eD-nBB;_q*N;j{+6G61l73is6x z(_ha?d0)`O3`8dfIIV#vod7uL1VCr6=f?N#NmlxoZYlE_2#&g|b&VC{|8irv@f1)Z z#-~?5plokxPap1mz}nLO(S0ztfM1pA@88JL2pK&373jn_e|GCreq%@u2dBKTq<^PL zs!F=@D$3!|B37<{h|z+m#V6du0eWhJ`9W;XaPhq_K(s=Jk?yT6(hQ}+@ms7jYLw8> zxh^at#QY*ss@TlXq}j=AtxToU{0HIqUHzRVd*TzX83NX);vIWqY2mq=&sG{%rLR>T z#%d>v!EhuwY{Vjfno)hr;iK9x0e$iN@d4>l=74xWs+)x?YhroB} z`J`6D&$r?jn4tj-8^H5Ukz{H8=m$M?eFyO6!1kY4kKGCYdfRr8JcmQ1A*pR-@_XQBZM|?+ridqyR_mL!Cp0k014`! zdJY zG2A47^Trtcje%j^o`3y+=!$fdnWO?IHt*JF^vFS6aGM>Z>m5D!sRQ{xu31Jxb+5g$ zGI%5aK5T~g13vgR?z`w#t8y)?b)~A3L_y3X&-^CAi&A z_H4cS+SVj)%@1&)qhraK5Q58u@w>H$mx?`qzf|n?*B0b-=+TbgNeckQD7LS-@nNVv zM4Sgg9E4EIR)A+V%GNJi^iv~1{5Sw`(eg9_5cy;)R3aGO9c zTAyjZ_TQ~yj!J}>JvsZpI0CUT(#KRg0U*5r{X#JEd>}s#05Acdr)#dgLFotpz~|C` z5AmTt-%9r07U9L(3kNJ1pt-d(p9p5XVvz|)n$_$ zE=v`cE-gPm>J8bwB$A5xedO!_#VE;yWNy|Iyd22^?gRi$2+UUOGP+Y~ZDb*+%#8nB znI8Z{$a*DS(TRDv>93G(5@C;)0qz8UfK0XLUwr8{07Ra5)C!wS{o4w{{s_(JwRUUs z15{qR&jo;8^8+-7*D-!z0NnO*qzGEBg!$RkHJTddk6re@tK;StMbHr*2d6P;CH-et z?I(2UYPZ720e4R0e*$2|@W=S-eG0bH=biPjlLOt-{|5kCr&>|pelq_600008NkvXX Hu0mjfKGs{I diff --git a/Effects/DisplayVoxels.effect b/Effects/DisplayVoxels.effect index a6e6f29e9..8946bf737 100644 --- a/Effects/DisplayVoxels.effect +++ b/Effects/DisplayVoxels.effect @@ -18,7 +18,7 @@ pass Default: float z = (cubeID / GI_GRID_RESOLUTION) % GI_GRID_RESOLUTION; float voxelSize = (2.0 * giData.size) / giData.resolution; - vOutput.positionWorld *= voxelSize * 0.98; + vOutput.positionWorld *= voxelSize * 0.3; vOutput.positionWorld += (giData.position) - giData.size; vOutput.positionWorld += voxelSize * vec3(x, y, z); vOutput.positionWorld += 0.01; @@ -40,47 +40,66 @@ pass Default: uniform sampler3D giDataTex3; uniform sampler3D giDataTex4; + insert @FUNCTIONS: + + struct Voxel { + vec3 posX; + vec3 negX; + vec3 posY; + vec3 negY; + vec3 posZ; + vec3 negZ; + bool solid; + }; + + Voxel fetchVoxel(vec3 coord) { + + // textureLod() seems to be the fastest, even faster than texelFetch() and texture() + vec4 sample0 = textureLod(giDataTex0, coord, 0); + vec4 sample1 = textureLod(giDataTex1, coord, 0); + vec4 sample2 = textureLod(giDataTex2, coord, 0); + vec4 sample3 = textureLod(giDataTex3, coord, 0); + vec4 sample4 = textureLod(giDataTex4, coord, 0); + + Voxel v; + + v.posX = vec3(sample0.x, sample0.y, sample0.z); + v.negX = vec3(sample1.x, sample1.y, sample1.z); + v.posY = vec3(sample2.x, sample2.y, sample2.z); + v.negY = vec3(sample3.x, sample3.y, sample3.z); + v.posZ = vec3(sample4.x, sample4.y, sample4.z); + + v.negZ = vec3(sample0.w, sample1.w, sample2.w); + + v.solid = sample4.w > 0.1; + return v; + } + insert @MATERIAL: vec3 vsCoord = (vOutput.positionWorld - giData.positionGeneration + giData.size) / (2.0 * giData.size); ivec3 vsiCoord = ivec3(vsCoord * giData.resolution); - vec4 data0 = texelFetch(giDataTex0, vsiCoord, 0); - vec4 data1 = texelFetch(giDataTex1, vsiCoord, 0); - vec4 data2 = texelFetch(giDataTex2, vsiCoord, 0); - vec4 data3 = texelFetch(giDataTex3, vsiCoord, 0); - vec4 data4 = texelFetch(giDataTex4, vsiCoord, 0); - - float csum = dot(data0, vec4(1)) - + dot(data1, vec4(1)) - + dot(data2, vec4(1)) - + dot(data3, vec4(1)) - + dot(data4, vec4(1)); + Voxel v = fetchVoxel(vsCoord); - // if (csum < 0.01) discard; vec3 combinedColor = vec3(0); if (abs(m.normal.x) > 0.5) { - combinedColor.x = mix(data0.x, data0.y, m.normal.x < 0.0 ? 1 : 0); - combinedColor.y = mix(data1.z, data1.w, m.normal.x < 0.0 ? 1 : 0); - combinedColor.z = mix(data3.x, data3.y, m.normal.x < 0.0 ? 1 : 0); + combinedColor = mix(v.posX, v.negX, m.normal.x < 0.0 ? 1 : 0); } if (abs(m.normal.y) > 0.5) { - combinedColor.x = mix(data0.z, data0.w, m.normal.y < 0.0 ? 1 : 0); - combinedColor.y = mix(data2.x, data2.y, m.normal.y < 0.0 ? 1 : 0); - combinedColor.z = mix(data3.z, data3.w, m.normal.y < 0.0 ? 1 : 0); + combinedColor = mix(v.posY, v.negY, m.normal.y < 0.0 ? 1 : 0); } if (abs(m.normal.z) > 0.5) { - combinedColor.x = mix(data1.x, data1.y, m.normal.z < 0.0 ? 1 : 0); - combinedColor.y = mix(data2.z, data2.w, m.normal.z < 0.0 ? 1 : 0); - combinedColor.z = mix(data4.x, data4.y, m.normal.z < 0.0 ? 1 : 0); + combinedColor = mix(v.posZ, v.negZ, m.normal.z < 0.0 ? 1 : 0); } - if (length(combinedColor) < 0.5) discard; - combinedColor *= 0.1; + // if (!v.solid) discard; + if (length(combinedColor) < 0.05) discard; + m.normal = vOutput.normalWorld; m.specular = 0; diff --git a/Effects/Examples/ExampleTreeInstanced.effect b/Effects/Examples/ExampleTreeInstanced.effect new file mode 100644 index 000000000..3a9de8211 --- /dev/null +++ b/Effects/Examples/ExampleTreeInstanced.effect @@ -0,0 +1,32 @@ + +# This effect displaces a tree on the z-plane. + +pass Default: + + vertex: + template default + uniform int numInstanceRows; + + insert @WS_POSITION: + int treeID = gl_InstanceID; + float x = treeID % numInstanceRows; + float y = treeID / numInstanceRows; + vOutput.positionWorld.xy += vec2(x, y) * 3.0; + + fragment: + template default + + +pass Shadows: + + vertex: + template default + uniform int numInstanceRows; + insert @WS_POSITION: + int treeID = gl_InstanceID; + float x = treeID % numInstanceRows; + float y = treeID / numInstanceRows; + worldPos.xy += vec2(x, y) * 3.0; + + fragment: + template default \ No newline at end of file diff --git a/Effects/Skybox/Skybox.effect b/Effects/Skybox/Skybox.effect index e93e4530c..697db25ae 100644 --- a/Effects/Skybox/Skybox.effect +++ b/Effects/Skybox/Skybox.effect @@ -11,7 +11,7 @@ pass Default: insert @MATERIAL: vec2 skycoord = clamp(vOutput.texcoord * vec2(1,2) + vec2(0, 0.04), vec2(0, 0.99), vec2(1, 1.9)); float borderFactor = saturate( pow((skycoord.y-1.0) * 10.0, 5.0)); - m.baseColor = texture(skytex, skycoord).xyz * borderFactor; + m.baseColor = texture(skytex, skycoord).xxx * borderFactor; // m.baseColor = vec3(borderFactor); m.specular = 0.0; m.roughness = 0.0; diff --git a/Samples/02-Roaming-Ralph/Tut-Roaming-Ralph.py b/Samples/02-Roaming-Ralph/Tut-Roaming-Ralph.py index d0bd74244..18ff7ab4b 100644 --- a/Samples/02-Roaming-Ralph/Tut-Roaming-Ralph.py +++ b/Samples/02-Roaming-Ralph/Tut-Roaming-Ralph.py @@ -210,8 +210,8 @@ def __init__(self): # self.cTrav.showCollisions(render) # Create some ocean - # self.water = ProjectedWaterGrid(self.renderPipeline) - # self.water.setWaterLevel(-3.0) + self.water = ProjectedWaterGrid(self.renderPipeline) + self.water.setWaterLevel(-3.0) # Create the skybox self.skybox = self.renderPipeline.getDefaultSkybox() diff --git a/Shader/BloomExtract.fragment b/Shader/BloomExtract.fragment index 5be4d1f1f..8905d10af 100644 --- a/Shader/BloomExtract.fragment +++ b/Shader/BloomExtract.fragment @@ -34,8 +34,8 @@ void main() { vec4 bloom = vec4(0); - if (luminance > 0.5) { - bloom = maxCol * 0.2; + if (luminance > 0.7) { + bloom = maxCol * 0.5; } result = vec4(bloom.xyz,1.0); diff --git a/Shader/BloomMerge.fragment b/Shader/BloomMerge.fragment index fda5cf660..ad0a97a26 100644 --- a/Shader/BloomMerge.fragment +++ b/Shader/BloomMerge.fragment @@ -23,7 +23,7 @@ void main() { // result = colorResult + mix(vec4(0),bloomResult, saturate(1.0 - luminance*1.0) ); // result = colorResult + mix(vec4(0),bloomResult, saturate(1.0 - luminance*1.0) ); - result = colorResult + bloomResult * saturate(1.1 - skybox) * saturate(1.0 - luminance*0.6); + result = colorResult + bloomResult * saturate(1.1 - skybox) * saturate(1.0 - luminance*1.3); #if defined(DEBUG_DISABLE_BLOOM) || defined(DEBUG_VISUALIZATION_ACTIVE) result = colorResult; diff --git a/Shader/DefaultShaders/Default/fragment.glsl b/Shader/DefaultShaders/Default/fragment.glsl index eca89af62..f957cf1a8 100644 --- a/Shader/DefaultShaders/Default/fragment.glsl +++ b/Shader/DefaultShaders/Default/fragment.glsl @@ -28,6 +28,7 @@ uniform int frameIndex; #endif #pragma ENTRY_POINT SHADER_IN_OUT +#pragma ENTRY_POINT FUNCTIONS void main() { @@ -74,7 +75,7 @@ void main() { #endif // Most textures are not in sRGB, account for that - sampledDiffuse.xyz = pow(sampledDiffuse.xyz, vec3(1.7)); + sampledDiffuse.xyz = pow(sampledDiffuse.xyz, vec3(1.5)); // Extract material properties float specularFactor = vOutput.materialSpecular.x; @@ -104,6 +105,10 @@ void main() { m.metallic = metallic; m.normal = mixedNormal; + // m.metallic = 0; + // m.specular = 0.04; + // m.roughness = 0.4; + // Entry point for the user to modify the material #pragma ENTRY_POINT MATERIAL diff --git a/Shader/DefaultShaders/Default/vertex.glsl b/Shader/DefaultShaders/Default/vertex.glsl index 601b9a8e3..1dcf5bed3 100644 --- a/Shader/DefaultShaders/Default/vertex.glsl +++ b/Shader/DefaultShaders/Default/vertex.glsl @@ -40,6 +40,7 @@ uniform mat4 currentMVP; #endif #pragma ENTRY_POINT SHADER_IN_OUT +#pragma ENTRY_POINT FUNCTIONS uniform int frameIndex; diff --git a/Shader/DefaultShaders/Shadows/fragment.glsl b/Shader/DefaultShaders/Shadows/fragment.glsl index db03f6bbc..b1699708b 100644 --- a/Shader/DefaultShaders/Shadows/fragment.glsl +++ b/Shader/DefaultShaders/Shadows/fragment.glsl @@ -3,7 +3,6 @@ #pragma include "Includes/Configuration.include" #pragma include "Includes/Structures/VertexOutput.struct" -#pragma ENTRY_POINT SHADER_IN_OUT #if defined(USE_ALPHA_TEST) && defined(USE_ALPHA_TESTED_SHADOWS) @@ -13,6 +12,10 @@ uniform sampler2D p3d_Texture0; #endif +#pragma ENTRY_POINT SHADER_IN_OUT +#pragma ENTRY_POINT FUNCTIONS + + void main() { #if defined(USE_ALPHA_TEST) && defined(USE_ALPHA_TESTED_SHADOWS) diff --git a/Shader/DefaultShaders/Voxelize/fragment.glsl b/Shader/DefaultShaders/Voxelize/fragment.glsl index bed227a0e..ebfbd5286 100644 --- a/Shader/DefaultShaders/Voxelize/fragment.glsl +++ b/Shader/DefaultShaders/Voxelize/fragment.glsl @@ -18,9 +18,8 @@ uniform sampler2D p3d_Texture3; #pragma include "Includes/UBOs/Lights.ubo" #pragma include "Includes/UBOs/Shadows.ubo" - #pragma ENTRY_POINT SHADER_IN_OUT - +#pragma ENTRY_POINT FUNCTIONS // Modify the lighting settings to get the lowest possible quality for voxelization @@ -60,7 +59,6 @@ uniform vec3 cameraPosition; #pragma include "Includes/LightingPipeline.include" - out vec4 result; void main() { @@ -94,6 +92,7 @@ void main() { m.metallic = metallic; m.normal = vOutput.normalWorld.xyz; + // Make everything diffuse m.specular = 0.0; m.metallic = 0.0; m.roughness = 1.0; @@ -102,8 +101,9 @@ void main() { #pragma ENTRY_POINT MATERIAL - vec3 lightingResult = computeLighting(renderedLightsBuffer, m) * 2.0; + vec3 lightingResult = computeLighting(renderedLightsBuffer, m) * 0.1; result = vec4(lightingResult, 1); + // lightingResult += vec3(1,1,1) * 0.2 * m.baseColor * GLOBAL_AMBIENT_FACTOR; // SRGB Correction diff --git a/Shader/DefaultShaders/Voxelize/vertex.glsl b/Shader/DefaultShaders/Voxelize/vertex.glsl index e613d5ed9..0a653ea5e 100644 --- a/Shader/DefaultShaders/Voxelize/vertex.glsl +++ b/Shader/DefaultShaders/Voxelize/vertex.glsl @@ -25,6 +25,7 @@ uniform vec4 p3d_ColorScale; uniform mat4 trans_mainRender_to_clip_of_voxelizeCam; #pragma ENTRY_POINT SHADER_IN_OUT +#pragma ENTRY_POINT FUNCTIONS void main() { diff --git a/Shader/ExposurePass.fragment b/Shader/ExposurePass.fragment index 7951833f3..bc8ed56a9 100644 --- a/Shader/ExposurePass.fragment +++ b/Shader/ExposurePass.fragment @@ -1,5 +1,7 @@ #version 400 +#pragma include "Includes/Configuration.include" + uniform sampler2D sceneTex; out vec4 result; @@ -9,12 +11,15 @@ void main() { vec3 sceneColor = texelFetch(sceneTex, coord, 0).xyz; - // SRGB - sceneColor = pow(sceneColor, vec3(1.0 / 2.2)); + #if !defined(DEBUG_VISUALIZATION_ACTIVE) + // SRGB + sceneColor = pow(sceneColor, vec3(1.0 / 2.2)); + + // Exposure + float exposure = 1.0; + sceneColor = 1.0 - exp(-exposure * sceneColor); - // Exposure - float exposure = 1.0; - sceneColor = 1.0 - exp(-exposure * sceneColor); + #endif result.xyz = sceneColor; result.w = 1.0; diff --git a/Shader/FinalPostprocessPass.fragment b/Shader/FinalPostprocessPass.fragment index 6f5b8470f..34cae58cb 100644 --- a/Shader/FinalPostprocessPass.fragment +++ b/Shader/FinalPostprocessPass.fragment @@ -56,10 +56,11 @@ void main() { // Vignett - // result.xyz = vec3(1); - result.xyz *= 1.0 - smoothstep(0, 1, - (length( (texcoord - vec2(0.5, 0.5)) * vec2(1.3, 1.0) * 1.1 ) - 0.1) ) * 0.9; - result.w = 1.0; + #if !defined(DEBUG_VISUALIZATION_ACTIVE) + result.xyz *= 1.0 - smoothstep(0, 1, + (length( (texcoord - vec2(0.5, 0.5)) * vec2(1.3, 1.0) * 1.1 ) - 0.2) ) * 0.9; + result.w = 1.0; + #endif #if defined(DEBUG_RM_VELOCITY) diff --git a/Shader/GI/ClearGrid.fragment b/Shader/GI/ClearGrid.fragment index 54a9d3f4a..71edc3038 100644 --- a/Shader/GI/ClearGrid.fragment +++ b/Shader/GI/ClearGrid.fragment @@ -6,10 +6,18 @@ uniform writeonly iimage3D voxelGenTexR; uniform writeonly iimage3D voxelGenTexG; uniform writeonly iimage3D voxelGenTexB; +#if defined(USE_DEBUG_ATTACHMENTS) +out vec4 color; +#endif + void main() { ivec2 coord = ivec2(gl_FragCoord.xy); ivec3 coord3D = convert_2d_to_3d(coord, GI_GRID_RESOLUTION, GI_SLIDE_COUNT); imageStore(voxelGenTexR, coord3D, ivec4(0)); imageStore(voxelGenTexG, coord3D, ivec4(0)); imageStore(voxelGenTexB, coord3D, ivec4(0)); + #if defined(USE_DEBUG_ATTACHMENTS) + color = vec4(coord3D / float(GI_GRID_RESOLUTION), 1); + #endif + } \ No newline at end of file diff --git a/Shader/GI/ConvertGrid.fragment b/Shader/GI/ConvertGrid.fragment index fb3bd809e..abc638658 100644 --- a/Shader/GI/ConvertGrid.fragment +++ b/Shader/GI/ConvertGrid.fragment @@ -27,7 +27,7 @@ struct VoxelDirections { VoxelDirections unpackData(int packedData) { VoxelDirections dir; - float scaleF = 2.0; + float scaleF = 0.01; dir.posX = ((packedData >> 0*5) & 0x1F) / 31.0 * scaleF; dir.negX = ((packedData >> 1*5) & 0x1F) / 31.0 * scaleF; dir.posY = ((packedData >> 2*5) & 0x1F) / 31.0 * scaleF; @@ -49,7 +49,7 @@ void main() { VoxelDirections voxelG = unpackData(valG); VoxelDirections voxelB = unpackData(valB); - float solid = step(1, valR+valG+valB); + float solid = step(1, max(valR, max(valG, valB))); imageStore(voxelDataDest0, coord3D, vec4(voxelR.posX, voxelG.posX, voxelB.posX, voxelR.negZ)); imageStore(voxelDataDest1, coord3D, vec4(voxelR.negX, voxelG.negX, voxelB.negX, voxelG.negZ)); @@ -61,7 +61,10 @@ void main() { color = vec4( voxelR.posX + voxelR.negX + voxelR.posY + voxelR.negY + voxelR.posZ + voxelR.negZ, voxelG.posX + voxelG.negX + voxelG.posY + voxelG.negY + voxelG.posZ + voxelG.negZ, - voxelB.posX + voxelB.negX + voxelB.posY + voxelB.negY + voxelB.posZ + voxelB.negZ, 1); + voxelB.posX + voxelB.negX + voxelB.posY + voxelB.negY + voxelB.posZ + voxelB.negZ, 1) * 10.0; + color += vec4(1,1, 0, 1) * solid; #endif + + } \ No newline at end of file diff --git a/Shader/GI/Distribute.fragment b/Shader/GI/Distribute.fragment index f115c0dbd..329b895d6 100644 --- a/Shader/GI/Distribute.fragment +++ b/Shader/GI/Distribute.fragment @@ -10,11 +10,11 @@ out vec4 color; #endif -uniform writeonly image3D dst0; -uniform writeonly image3D dst1; -uniform writeonly image3D dst2; -uniform writeonly image3D dst3; -uniform writeonly image3D dst4; +uniform coherent writeonly image3D dst0; +uniform coherent writeonly image3D dst1; +uniform coherent writeonly image3D dst2; +uniform coherent writeonly image3D dst3; +uniform coherent writeonly image3D dst4; uniform sampler3D src0; uniform sampler3D src1; @@ -56,49 +56,55 @@ Voxel fetchVoxel(vec3 coord) { } void storeVoxel(ivec3 coord, Voxel v) { - imageStore(dst0, coord, vec4(v.posX.r, v.posX.g, v.posX.b, v.negZ.r)); imageStore(dst1, coord, vec4(v.negX.r, v.negX.g, v.negX.b, v.negZ.g)); imageStore(dst2, coord, vec4(v.posY.r, v.posY.g, v.posY.b, v.negZ.b)); imageStore(dst3, coord, vec4(v.negY.r, v.negY.g, v.negY.b, 0)); imageStore(dst4, coord, vec4(v.posZ.r, v.posZ.g, v.posZ.b, v.solid ? 1.0 : 0.0)); - } // Preventing a lot of code duplicating by making this a define -#define EVALUATE_DIRECTION(DIR_NAME, TEMPL0, TEMPL1, TEMPL2) \ +#define EVALUATE_DIRECTION(DIR_NAME, NEG_DIR_NAME, TEMPL0, TEMPL1, TEMPL2) \ for (int c1 = -1; c1 <= 1; c1++) { \ for (int c2 = -1; c2 <= 1; c2++) { \ - v. DIR_NAME += fetchVoxel(floatCoord3D + vec3( TEMPL0, TEMPL1, TEMPL2 ) * voxelSize). DIR_NAME * distributionFactor * (saturate(1.0 - 0.4*(length(vec2(c1, c2))))); \ + Voxel tmp = fetchVoxel(floatCoord3D + vec3( TEMPL0, TEMPL1, TEMPL2 ) * voxelSize);\ + v. DIR_NAME += tmp. DIR_NAME * distributionFactor * (saturate(1.0 - 0.0*(length(vec2(c1, c2))))); \ + if (tmp.solid) {\ + v. DIR_NAME += v. NEG_DIR_NAME * bounceFactor;\ + }\ + \ } \ } +uniform bool isLastStep; + void main() { ivec2 coord = ivec2(gl_FragCoord.xy); ivec3 coord3D = convert_2d_to_3d(coord, GI_GRID_RESOLUTION, GI_SLIDE_COUNT); vec3 floatCoord3D = (coord3D+0.5) / GI_GRID_RESOLUTION; - float voxelSize = 0.5 / GI_GRID_RESOLUTION; + float voxelSize = 1.0 / GI_GRID_RESOLUTION; // Fetch current voxel Voxel v = fetchVoxel(floatCoord3D); - float distributionFactor = 0.02; + float distributionFactor = 0.03; + float bounceFactor = distributionFactor * 1.0; // Evaluate each direction - if (!v.solid) { - EVALUATE_DIRECTION(posX, -1, c1, c2 ); - EVALUATE_DIRECTION(negX, 1, c1, c2 ); - EVALUATE_DIRECTION(posY, c1, -1, c2 ); - EVALUATE_DIRECTION(negY, c1, 1, c2 ); - EVALUATE_DIRECTION(posZ, c1, c2, -1 ); - EVALUATE_DIRECTION(negZ, c1, c2, 1 ); + if (!v.solid || isLastStep) { + EVALUATE_DIRECTION(posX, negX, -1, c1, c2 ); + EVALUATE_DIRECTION(negX, posX, 1, c1, c2 ); + EVALUATE_DIRECTION(posY, negY, c1, -1, c2 ); + EVALUATE_DIRECTION(negY, posY, c1, 1, c2 ); + EVALUATE_DIRECTION(posZ, negZ, c1, c2, -1 ); + EVALUATE_DIRECTION(negZ, posZ, c1, c2, 1 ); } // Store the modified voxel storeVoxel(coord3D, v); #if defined(USE_DEBUG_ATTACHMENTS) - color = vec4(v.posX + v.negX + v.posZ + v.negZ + v.posY + v.negY, 1); + color = vec4(v.posX + v.negX + v.posZ + v.negZ + v.posY + v.negY, 1); #endif } \ No newline at end of file diff --git a/Shader/Includes/Ambient.include b/Shader/Includes/Ambient.include index ceeea7dde..f69da3970 100644 --- a/Shader/Includes/Ambient.include +++ b/Shader/Includes/Ambient.include @@ -78,7 +78,9 @@ vec3 computeAmbient(Material material, vec4 giAmbient, vec4 giSpecular, float oc #else vec3 scatteringReflected = ambientRefColor; vec3 scatteringAmbient = vec3(1); - #endif + #endif + + // return giAmbient.xyz;r @@ -89,7 +91,7 @@ vec3 computeAmbient(Material material, vec4 giAmbient, vec4 giSpecular, float oc vec3 result = vec3(0); - occlusionFactor = pow(occlusionFactor,5.0); + occlusionFactor = pow(occlusionFactor, 3.0); // occlusionFactor = pow(saturate(occlusionFactor - 0.4), 1.5) * 3.0; // occlusionFactor = 1.0; // giAmbient.xyz = vec3(1); @@ -120,14 +122,14 @@ vec3 computeAmbient(Material material, vec4 giAmbient, vec4 giSpecular, float oc material.baseColor * // Tint by material color saturate(1.0 - material.metallic) * // No diffuse ambient for metallic objects saturate(1.0 + giAmbient.w) * // Global Illumination Occlusion - 0.3 * vec3(1.0,1.2,1.4) // Color tint - *mix(iblColor*0.5, vec3(0.5), 0.6) * + 0.3 * vec3(1.0,1.0,1.0) // Color tint + *mix(iblColor*0.5, vec3(0.5), 1.0) * mix(scatteringAmbient*1.0, vec3(1), 1.0) ; result += borderFactor * environmentColor * - 0.4 * saturate(1.0+material.metallic) * + 0.1 * saturate(1.0+material.metallic) * material.specular * mix(pow(iblColor, vec3(1.0)), vec3(1), 1.0) * mix(occlusionFactor, 1.0, 0.0) * (1.0 - material.roughness) * mix(vec3(1.0),giAmbient.xyz, 1); @@ -140,7 +142,7 @@ vec3 computeAmbient(Material material, vec4 giAmbient, vec4 giSpecular, float oc vec3 metallicSpecularAmbient = mix(environmentColor, material.baseColor, material.translucency) - * mix(occlusionFactor, 1.0, 1.0) * material.specular * 2.0 * mix(vec3(1.0),giAmbient.xyz, 1) * 0.7; + * mix(occlusionFactor, 1.0, 1.0) * material.specular * 2.0 * mix(vec3(1.0),giAmbient.xyz, 1) * 0.05; // metallicSpecularAmbient = ambientRefColor * material.specular * 0.5; @@ -153,6 +155,8 @@ vec3 computeAmbient(Material material, vec4 giAmbient, vec4 giSpecular, float oc // Take ambient factor into account result *= GLOBAL_AMBIENT_FACTOR; + result *= 2.0 * attenuation; + // result *= (0.01 + pow(attenuation, vec3(1.0 / 2.2))); diff --git a/Shader/Includes/CommonFunctions.include b/Shader/Includes/CommonFunctions.include index 2f7f299ce..c9518eb81 100644 --- a/Shader/Includes/CommonFunctions.include +++ b/Shader/Includes/CommonFunctions.include @@ -30,4 +30,18 @@ vec3 mergeNormal(inout vec3 detailNormal, float detailFactor, vec3 normal, vec3 ivec3 convert_2d_to_3d(ivec2 coord, int slice_res, int slice_size) { return ivec3(coord % slice_res, int(coord.x / slice_res) + int(coord.y / slice_res) * slice_size); +} + + + +vec3 getCubemapCoordinate(int faceIndex, vec2 coord) { + vec3 baseDir = vec3(0); + if (faceIndex == 0) baseDir = vec3(1, -coord.y, coord.x); + else if (faceIndex == 1) baseDir = vec3(-1, -coord.y, -coord.x); + else if (faceIndex == 2) baseDir = vec3(coord.x, 1, -coord.y); + else if (faceIndex == 3) baseDir = vec3(coord.x, -1, coord.y); + else if (faceIndex == 4) baseDir = vec3(coord.x, -coord.y, -1); + else if (faceIndex == 5) baseDir = vec3(-coord.x, -coord.y, 1); + baseDir = normalize(baseDir); + return baseDir; } \ No newline at end of file diff --git a/Shader/Includes/Configuration.include b/Shader/Includes/Configuration.include index eb6e31788..ded66e1b1 100644 --- a/Shader/Includes/Configuration.include +++ b/Shader/Includes/Configuration.include @@ -27,3 +27,4 @@ // Include commonly used functinos #pragma include "Includes/CommonFunctions.include" + diff --git a/Shader/Includes/GlobalIllumination.include b/Shader/Includes/GlobalIllumination.include index 85a0c22e9..25fd33530 100644 --- a/Shader/Includes/GlobalIllumination.include +++ b/Shader/Includes/GlobalIllumination.include @@ -71,35 +71,43 @@ vec4 computeGlobalIllumination(vec3 pos, vec3 normal, vec3 viewVector, out vec4 if (!isInGrid) return vec4(0.4); // Bias position a bit, so self shadowing gets less strong - vec3 biasedPosition = pos + normal * voxelSize * 0.5; + vec3 biasedPosition = pos + normal * voxelSize * 1.0; // Compute coordinate in voxel space vec3 localCoord = (biasedPosition-giData.position + giData.size) / (2 * giData.size); - vec3 localCoordOffs = mod(localCoord, 1.0 / giData.resolution); + vec3 localCoordOffs = mod(localCoord+ 0.5/giData.resolution, 1.0 / giData.resolution) * giData.resolution; + + ivec3 localCoordInGrid = ivec3(localCoord * giData.resolution); specularColor = vec4(0.2, 0.6, 1.0, 0); Voxel v = fetchVoxel(localCoord, 0); vec3 resultSum = vec3(0); - resultSum += saturate(1.0 + 0.5 *(-normal.x)) * v.posX; - resultSum += saturate(1.0 + 0.5 *(normal.x)) * v.negX; - resultSum += saturate(1.0 + 0.5 *(-normal.y)) * v.posY; - resultSum += saturate(1.0 + 0.5 *(normal.y)) * v.negY; - resultSum += saturate(1.0 + 0.5 *(-normal.z)) * v.posZ; - resultSum += saturate(1.0 + 0.5 *(normal.z)) * v.negZ; + float mixFactor = 0.0; + + resultSum += saturate(1.0 + mixFactor * (-normal.x)) * v.posX; + resultSum += saturate(1.0 + mixFactor * (normal.x)) * v.negX; + resultSum += saturate(1.0 + mixFactor * (-normal.y)) * v.posY; + resultSum += saturate(1.0 + mixFactor * (normal.y)) * v.negY; + resultSum += saturate(1.0 + mixFactor * (-normal.z)) * v.posZ; + resultSum += saturate(1.0 + mixFactor * (normal.z)) * v.negZ; // resultSum = v.posX + v.negX + v.posY + v.negY + v.posZ + v.negZ; // resultSum = v.posZ * 1.0; resultSum *= 0.2; // resultSum *= 0.5; - - // SRGB // resultSum = pow(resultSum, vec3(1.0 / 4.2)); + // resultSum = vec3(1); + // resultSum += 0.3; + resultSum += vec3(0.021, 0.019, 0.014) * 0.5; + + // if (any(lessThan(localCoordOffs, vec3(0.05) ))) { + // resultSum = mix(resultSum, vec3(1, 0, 0), 0.05); + // } + - // resultSum += 0.5; - // resultSum += 0.04; return vec4(resultSum, 1); diff --git a/Shader/Includes/Material.include b/Shader/Includes/Material.include index 72502bb2c..57ed79ab0 100644 --- a/Shader/Includes/Material.include +++ b/Shader/Includes/Material.include @@ -27,7 +27,7 @@ Material unpackMaterial(vec4 data0, vec4 data1, vec4 data2, vec4 data3, sampler2 // Material debug render modes #if defined(DEBUG_RM_LIGHTING) - m.baseColor = vec3(1); + m.baseColor = vec3(0.3); #endif #if defined(DEBUG_RM_DIFFUSE_LIGHTING) diff --git a/Shader/Includes/PositionReconstruction.include b/Shader/Includes/PositionReconstruction.include index a2a506eb8..243d44f45 100644 --- a/Shader/Includes/PositionReconstruction.include +++ b/Shader/Includes/PositionReconstruction.include @@ -2,6 +2,7 @@ uniform mat4 trans_clip_of_mainCam_to_mainRender; +uniform mat4 currentProjMatInv; const float ndcNear = CAMERA_NEAR; const float ndcFar = CAMERA_FAR; @@ -62,3 +63,10 @@ vec3 calculateSurfacePos(float z, vec2 tcoord, float near, float far, mat4 clipT clipPos.xyz = ndcPos * clipPos.w; return (clipToRender * clipPos).xyz; } + + +vec3 calculateViewPos(float z, vec2 tcoord) { + vec3 ndc = vec3(tcoord, z) * 2.0 - 1.0; + vec4 sampleViewPos = currentProjMatInv * vec4(ndc, 1.0); + return (sampleViewPos.xzy * vec3(1,1,-1)) / sampleViewPos.w ; +} \ No newline at end of file diff --git a/Shader/Includes/VoxelGeneration.include b/Shader/Includes/VoxelGeneration.include index 8892dc765..10aeb17ca 100644 --- a/Shader/Includes/VoxelGeneration.include +++ b/Shader/Includes/VoxelGeneration.include @@ -18,21 +18,18 @@ int packContributions(vec3 normal, float factor) { (int(saturate(dot(dir.zxz, normal)) * factor * 31) & 0x1F) << 2*5 | (int(saturate(dot(dir.zyz, normal)) * factor * 31) & 0x1F) << 3*5 | (int(saturate(dot(dir.zzx, normal)) * factor * 31) & 0x1F) << 4*5 | - (int(saturate(dot(dir.zzy, normal)) * factor * 31) & 0x1F) << 5*5; + (int(saturate(dot(dir.zzy, normal)) * factor * 31) & 0x1F) << 5*5 | (0x1 << 30); } void spawnVoxel(vec3 position, vec3 normal, vec3 color) { - vec3 voxelPos = (position - giData.positionGeneration + giData.size) / (2.0 * giData.size); - // voxelPos += 0.5 / giData.resolution; - ivec3 voxelCoord = ivec3(voxelPos * giData.resolution); - - color = saturate(color); - normal = normalize(normal); - // normal = vec3(1, 0, 0); + vec3 voxelPos = (position - giData.positionGeneration + giData.size) / (2.0 * giData.size); + // voxelPos += normal * 0.2 / giData.resolution; + ivec3 voxelCoord = ivec3(voxelPos * giData.resolution + 0.001); + color = saturate(color); int packedR = packContributions(normal, color.r); int packedG = packContributions(normal, color.g); @@ -41,8 +38,4 @@ void spawnVoxel(vec3 position, vec3 normal, vec3 color) { imageAtomicOr(voxelGenDestR, voxelCoord, packedR); imageAtomicOr(voxelGenDestG, voxelCoord, packedG); imageAtomicOr(voxelGenDestB, voxelCoord, packedB); - // imageStore(voxelGenDestR, voxelCoord, ivec4(packedR)); - // imageStore(voxelGenDestG, voxelCoord, ivec4(packedG)); - // imageStore(voxelGenDestB, voxelCoord, ivec4(packedB)); - } \ No newline at end of file diff --git a/Shader/LightingPass.fragment b/Shader/LightingPass.fragment index cc466ce2e..444b82a35 100644 --- a/Shader/LightingPass.fragment +++ b/Shader/LightingPass.fragment @@ -125,7 +125,7 @@ void main() { // fogFactor *= saturate(-0.05 + max(0.0, material.position.z) / 800.0); fogFactor = smoothstep(0, 1, saturate(fogFactor)); // fogFactor = 0.0; - result = mix(vec3(result), scatteringResult*0.2, fogFactor); + // result = mix(vec3(result), scatteringResult*0.2, fogFactor); #endif } diff --git a/Shader/Occlusion/HBAO.include b/Shader/Occlusion/HBAO.include index b88d1e2b3..d47d989e7 100644 --- a/Shader/Occlusion/HBAO.include +++ b/Shader/Occlusion/HBAO.include @@ -5,19 +5,15 @@ // https://gist.github.com/fisch0920/6770346 // number of directions to sample in UV space -#define HBAO_NUM_SAMPLE_DIRECTIONS OCCLUSION_SAMPLES +#define HBAO_NUM_SAMPLE_DIRECTIONS (2*OCCLUSION_SAMPLES) #define HBAO_TANGENT_BIAS 0.2 -#define HBAO_NUM_SAMPLING_STEPS 4 -#define HBAO_SAMPLING_STEP 0.05 * OCCLUSION_RADIUS +#define HBAO_NUM_SAMPLING_STEPS 3 +#define HBAO_SAMPLING_STEP (1.0 * OCCLUSION_RADIUS) -#define HBAO_SCALE 3.6 * OCCLUSION_STRENGTH -#define HBAO_SAMPLING_RADIUS 2.9 * OCCLUSION_RADIUS +#define HBAO_SCALE (5.6 * OCCLUSION_STRENGTH) +#define HBAO_SAMPLING_RADIUS (0.1 * OCCLUSION_RADIUS) -uniform sampler2D viewSpaceNormals; -uniform sampler2D viewSpacePosition; - -uniform mat4 currentProjMatInv; uniform sampler2D depthTex; uniform sampler2D noiseTex; @@ -25,39 +21,54 @@ uniform vec3 cameraPosition; const float TWO_PI = 2.0 * M_PI; +vec3 hbao_getPositionVS(vec2 uv) { + float d = textureLod(depthTex, uv, 0).x; + return calculateViewPos(d, uv); +} + float computeOcclusion(vec2 coord, ivec2 coordInt, float distanceToCamera) { - vec3 viewPos = texture(viewSpacePosition, coord).xyz; - vec3 viewNorm = texture(viewSpaceNormals, coord).xyz; + vec3 viewPos = hbao_getPositionVS(coord); + + // Compute normal based on depth buffer + vec3 viewPosX1 = hbao_getPositionVS(coord + vec2(1.0 / WINDOW_WIDTH, 0)); + vec3 viewPosY1 = hbao_getPositionVS(coord + vec2(0, 1.0 / WINDOW_HEIGHT)); + + // vec3 normalVS = texture(viewSpaceNormals, coord).xyz; + vec3 viewNorm = normalize(cross(viewPos - viewPosX1, viewPos - viewPosY1)); float total = 0.0f; float sample_direction_increment = TWO_PI / HBAO_NUM_SAMPLE_DIRECTIONS; #if defined(USE_TEMPORAL_OCCLUSION) - float frame_angle_offset = sample_direction_increment * 0.5 * (frameIndex %2); + float frame_angle_offset = 0.2 * (frameIndex %2); #else - float frame_angle_offset = 0; + float frame_angle_offset = 0.0; #endif #if defined(USE_OCCLUSION_NOISE) - float noise = texelFetch(noiseTex, ivec2(gl_FragCoord) % 4, 0).x * 2.0 - 1.0; + float noise = texelFetch(noiseTex, ivec2(gl_FragCoord) % 4, 0).x; #else float noise = 0.0; #endif + // frame_angle_offset *= 0; + float pixelDepth = texture(depthTex, coord).x; float dist = getLinearZFromZ(pixelDepth); + vec2 pixelFactor = 1.0 / vec2(WINDOW_WIDTH, WINDOW_HEIGHT); + + // Scale the kernel size a bit to make it look more realistic, however clamp + // it to avoid huge kernel sizes (which destroy the texture cache) + pixelFactor *= clamp(20.0 / dist, 0.02, 3.0); - // float dist = distance(cameraPosition, texture(worldSpacePosition, coord).xyz); - float pixelFactor = 2.0 / dist; - // pixelFactor = 0.1; -// for(uint i = 0; i < HBAO_NUM_SAMPLE_DIRECTIONS; i++) { - float sampling_angle = i * sample_direction_increment + frame_angle_offset + noise * sample_direction_increment; // azimuth angle theta in the paper + float sampling_angle = (i + frame_angle_offset) * sample_direction_increment; vec2 sampleDir = vec2(cos(sampling_angle), sin(sampling_angle)); + // we will now march along sampleDir and calculate the horizon // horizon starts with the tangent plane to the surface, whose angle we can get from the normal float tangentAngle = acos(dot(vec3(sampleDir, 0), viewNorm)) - (0.5 * M_PI) + HBAO_TANGENT_BIAS; @@ -67,30 +78,19 @@ float computeOcclusion(vec2 coord, ivec2 coordInt, float distanceToCamera) { for (uint j = 0; j < HBAO_NUM_SAMPLING_STEPS; j++) { // march along the sampling direction and see what the horizon is - vec2 sampleOffset = float(j+1) * HBAO_SAMPLING_STEP * sampleDir * pixelFactor; - - + vec2 sampleOffset = float(j+1 + noise) * HBAO_SAMPLING_STEP * sampleDir * pixelFactor; vec2 offTex = coord + sampleOffset; // Fix issues at screen border if (any(greaterThan(offTex, vec2(1))) || any(lessThan(offTex, vec2(0)))) { continue; } - - #if 0 - // Sample precomputed view pos - vec3 sampleViewPos = textureLod(viewSpacePosition, offTex, 0).xyz; - #else - // Compute view pos from depth, faster for small kernels - float depth = textureLod(depthTex, offTex, 0).x; - vec3 ndc = vec3(offTex, depth) * 2.0 - 1.0; - vec4 sampleViewPos = currentProjMatInv * vec4(ndc, 1.0); - sampleViewPos.xyz = sampleViewPos.xzy / sampleViewPos.w * vec3(1,1,-1); - #endif + // Compute view pos from depth, faster for small kernels + vec3 sampleViewPos = hbao_getPositionVS(offTex); // we now have the view space position of the offset point - vec3 diff = sampleViewPos.xyz - viewPos; + vec3 diff = sampleViewPos - viewPos; if (length(diff) < HBAO_SAMPLING_RADIUS) { // skip samples which are outside of our local sampling radius @@ -98,7 +98,7 @@ float computeOcclusion(vec2 coord, ivec2 coordInt, float distanceToCamera) { float elevationAngle = atan(diff.z / length(diff.xy)); horizonAngle = max(horizonAngle, elevationAngle); } - } // sampling steps + } // float normDiff = length(lastDiff) / HBAO_SAMPLING_RADIUS; // float attenuation = 1 - normDiff*normDiff; diff --git a/Shader/Occlusion/SAO.include b/Shader/Occlusion/SAO.include index 6fe24be31..2b48b561e 100644 --- a/Shader/Occlusion/SAO.include +++ b/Shader/Occlusion/SAO.include @@ -6,25 +6,25 @@ #pragma include "Includes/PositionReconstruction.include" -uniform sampler2D viewSpaceNormals; -uniform sampler2D viewSpacePosition; +uniform sampler2D depthTex; #undef OCCLUSION_SAMPLES -#define OCCLUSION_SAMPLES 32 + #define OCCLUSION_SAMPLES 32 // total number of samples at each fragment -#define SAO_NUM_SPIRAL_TURNS 8 +#define SAO_NUM_SPIRAL_TURNS 4 #define SAO_VARIATION 1 -const float saoConstIntensity = 5.0; -const float saoSampleRadiusWS = 20.0; +const float saoConstIntensity = 4.0; +const float saoSampleRadiusWS = OCCLUSION_RADIUS * 1.0; const float saoBias = 0.05; const float saoEpsilon = 0.02; vec3 sao_getPositionVS(vec2 uv) { - return textureLod(viewSpacePosition, uv, 0).xyz; + float d = textureLod(depthTex, uv, 0).x; + return calculateViewPos(d, uv); } // returns a unit vector and a screen-space radius for the tap on a unit disk @@ -93,7 +93,13 @@ float computeOcclusion(vec2 coord, ivec2 coordInt, float distanceToCamera) { vec3 originVS = sao_getPositionVS(coord); - vec3 normalVS = texture(viewSpaceNormals, coord).xyz; + + // Compute normal based on depth buffer + vec3 originVSX1 = sao_getPositionVS(coord + vec2(1.0 / WINDOW_WIDTH, 0)); + vec3 originVSY1 = sao_getPositionVS(coord + vec2(0, 1.0 / WINDOW_HEIGHT)); + + // vec3 normalVS = texture(viewSpaceNormals, coord).xyz; + vec3 normalVS = normalize(cross(originVS - originVSX1, originVS - originVSY1)); #if defined(USE_TEMPORAL_OCCLUSION) float randomPatternRotationAngle = (frameIndex % 2); @@ -114,6 +120,8 @@ float computeOcclusion(vec2 coord, ivec2 coordInt, float distanceToCamera) { occlusion += sao_sampleAO(coord, originVS, normalVS, radiusSS, i, randomPatternRotationAngle); } + + occlusion = occlusion / float(OCCLUSION_SAMPLES) * saoConstIntensity; return occlusion; } \ No newline at end of file diff --git a/Shader/ScatteringCubemapPass.fragment b/Shader/ScatteringCubemapPass.fragment index 8a5bff895..4312c02fb 100644 --- a/Shader/ScatteringCubemapPass.fragment +++ b/Shader/ScatteringCubemapPass.fragment @@ -23,20 +23,13 @@ void main() { int faceIndex = coord.x / cubemapSize; // Compute cubemap direction - vec3 baseDir = vec3(0); - if (faceIndex == 0) baseDir = vec3(1, -floatCoord.y, floatCoord.x); - else if (faceIndex == 1) baseDir = vec3(-1, -floatCoord.y, -floatCoord.x); - else if (faceIndex == 2) baseDir = vec3(floatCoord.x, 1, -floatCoord.y); - else if (faceIndex == 3) baseDir = vec3(floatCoord.x, -1, floatCoord.y); - else if (faceIndex == 4) baseDir = vec3(floatCoord.x, -floatCoord.y, -1); - else if (faceIndex == 5) baseDir = vec3(-floatCoord.x, -floatCoord.y, 1); - - // Normalize cubemap direction to convert it to a coordinate - baseDir = normalize(baseDir); + vec3 baseDir = getCubemapCoordinate(faceIndex, floatCoord); // Compute scattering vec3 attenuation = vec3(0); float irradianceFactor = 0.0; + + // TODO: Verify the baseDir direction! baseDir.z = -baseDir.z; vec3 scatteringResult = scatteringComputeInscatteredLight( diff --git a/Shader/ScatteringPass.fragment b/Shader/ScatteringPass.fragment index a1585fd57..827ec413f 100644 --- a/Shader/ScatteringPass.fragment +++ b/Shader/ScatteringPass.fragment @@ -81,8 +81,8 @@ void main() { if (!isSkybox) { scatteringResult *= 1.2; } else { - scatteringResult *= 0.08; - scatteringResult = pow(scatteringResult, vec3(0.8)) * 1.3; + scatteringResult *= 0.4; + scatteringResult = pow(scatteringResult, vec3(0.5)) * 2.3; } diff --git a/Shader/ViewSpacePass.fragment b/Shader/ViewSpacePass.fragment index 17e21742c..bbcb546ed 100644 --- a/Shader/ViewSpacePass.fragment +++ b/Shader/ViewSpacePass.fragment @@ -7,36 +7,27 @@ in vec2 texcoord; uniform sampler2D depthTex; -uniform mat4 currentViewMat; + out vec4 outNormalVS; out vec4 outPositionVS; - -vec3 getPositionWorld(ivec2 coord) { - float z = texelFetch(depthTex, coord, 0).x; - return calculateSurfacePos(z, coord / vec2(WINDOW_WIDTH, WINDOW_HEIGHT)); +// Compute view pos from depth +vec3 computeViewSpacePos(vec2 coord) { + float depth = textureLod(depthTex, coord, 0).x; + return calculateViewPos(depth, coord); } uniform vec4 bufferSize; void main() { // This computes the view space normals and position from the world-space - // position buffer used to compute occlusions - ivec2 coord = ivec2(gl_FragCoord.xy); - - vec3 pixelW = vec3(bufferSize.xy, 0); - vec3 world = getPositionWorld(coord); - vec3 worldX1 = getPositionWorld(coord + ivec2(1, 0)); - vec3 worldY1 = getPositionWorld(coord + ivec2(0, 1)); - - vec3 worldDx = world - worldX1; - vec3 worldDy = world - worldY1; - - vec3 worldSpaceNormal = normalize(cross(worldDx, worldDy)); - vec4 viewSpaceNormal = normalize(currentViewMat * vec4(worldSpaceNormal, 0)); - vec4 viewSpacePosition = currentViewMat * vec4(world, 1); - - outNormalVS = vec4(viewSpaceNormal.xyz, 1); - outPositionVS = vec4(viewSpacePosition.xyz, 1); + // position buffer used to compute occlusion + vec3 viewPos = computeViewSpacePos(texcoord); + vec3 viewPosX1 = computeViewSpacePos(texcoord + vec2(1.0 / WINDOW_WIDTH, 0)); + vec3 viewPosY1 = computeViewSpacePos(texcoord + vec2(0, 1.0 / WINDOW_HEIGHT)); + vec3 viewNormal = normalize(cross(viewPos - viewPosX1, viewPos - viewPosY1)); + + outNormalVS = vec4(viewNormal.xyz, 1); + outPositionVS = vec4( viewPos.xyz, 1); } \ No newline at end of file diff --git a/main.py b/main.py index 217d5f684..7c04e8110 100644 --- a/main.py +++ b/main.py @@ -41,7 +41,6 @@ from direct.interval.IntervalGlobal import Sequence - class Main(ShowBase, DebugObject): """ This is the render pipeline testing showbase """ @@ -58,7 +57,6 @@ def __init__(self): # Init the showbase ShowBase.__init__(self) - # Show loading screen self.loadingScreen = PipelineLoadingScreen(self) self.loadingScreen.render() @@ -106,8 +104,8 @@ def __init__(self): # self.sceneSource = "Demoscene.ignore/DemoTerrain/Scene.egg" # self.sceneSource = "Demoscene.ignore/TransparencyTest/Scene.egg" # self.sceneSource = "Demoscene.ignore/SanMiguel/Scene.bam" - # self.sceneSource = "Demoscene.ignore/DabrovicSponza/Scene.egg"s - self.sceneSource = "Demoscene.ignore/Sponza/sponza.egg.bam" + self.sceneSource = "Demoscene.ignore/DabrovicSponza/Scene.egg" + # self.sceneSource = "Demoscene.ignore/Sponza/sponza.egg.bam" # self.sceneSource = "Demoscene.ignore/Avolition/level5.bam" # self.sceneSource = "Demoscene.ignore/Sphere/Scene.bam" # self.sceneSource = "Demoscene.ignore/Alphatest/Scene.bam" @@ -121,7 +119,7 @@ def __init__(self): # self.sceneSource = "Models/HDRTest/Scene.egg" # self.sceneSource = "Models/GITestScene/Scene.egg" # self.sceneSource = "Toolkit/Blender Material Library/MaterialLibrary.bam" - self.sceneSource = "panda" + # self.sceneSource = "panda" # Select surrounding scene here self.sceneSourceSurround = None @@ -130,8 +128,7 @@ def __init__(self): # self.sceneSourceSurround = "Models/LittleHouse/couch.bam" # Wheter to create the default ground plane - self.usePlane = True - + self.usePlane = False # Store a list of transparent objects @@ -144,9 +141,9 @@ def __init__(self): dirLight = DirectionalLight() dirLight.setPos(dPos * 100000.0) dirLight.setShadowMapResolution(2048) - dirLight.setColor(Vec3(1.1, 1.05, 0.9) * 6.0) + dirLight.setColor(Vec3(1.1, 1.05, 0.9) * 12.0) dirLight.setCastsShadows(True) - dirLight.setPssmDistance(180) + dirLight.setPssmDistance(140) self.renderPipeline.addLight(dirLight) self.dirLight = dirLight @@ -291,8 +288,9 @@ def onSceneLoaded(self, scene): self.loadingScreen.setStatus("Loading skybox", 70) self.scene = scene - # self.scene.hide(self.renderPipeline.getMainPassBitmask()) self.scene.prepareScene(self.win.getGsg()) + # render.hide(self.renderPipeline.getVoxelizePassBitmask()) + # self.scene.hide(self.renderPipeline.getVoxelizePassBitmask()) # Load surround scene if self.sceneSourceSurround is not None: @@ -339,10 +337,10 @@ def onSceneLoaded(self, scene): }) match.setAttrib(CullFaceAttrib.make(CullFaceAttrib.M_none)) - # for i in ["53", "54", "55", "56", "57"]: - # matches = self.scene.findAllMatches("**/" + i) - # for match in matches: - # match.remove() + # for i in ["53", "54", "55", "56", "57", "Sphere", "Cube.001"]: + # matches = self.scene.findAllMatches("**/" + i) + # for match in matches: + # match.remove() # Wheter to use a ground plane @@ -455,7 +453,7 @@ def setSunPos(self): if radial: rawValue = rawValue / 100.0 * 2.0 * math.pi dPos = Vec3( - math.sin(rawValue) * 30.0, math.cos(rawValue) * 30.0, 35.0) + math.sin(rawValue) * 30.0, math.cos(rawValue) * 30.0, 19.0) # dPos = Vec3(100, 100, self.lastSliderValue*2 10) else: dPos = Vec3(30, (rawValue - 50) * 1.5, 0) @@ -472,8 +470,10 @@ def toggleSceneWireframe(self): if self.sceneWireframe: render.setAttrib(RenderModeAttrib.make(RenderModeAttrib.MWireframe), 10) + render2d.setAttrib(RenderModeAttrib.make(RenderModeAttrib.MWireframe), 10) else: render.setAttrib(RenderModeAttrib.make(RenderModeAttrib.MFilled), 10) + render2d.setAttrib(RenderModeAttrib.make(RenderModeAttrib.MFilled), 10) self.skybox.setAttrib(RenderModeAttrib.make(RenderModeAttrib.MFilled), 20)