/* * Copyright 2016 MovingBlocks * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.terasology.rendering.dag.nodes; import org.terasology.assets.ResourceUrn; import org.terasology.config.Config; import org.terasology.config.RenderingConfig; import org.terasology.monitoring.PerformanceMonitor; import org.terasology.registry.In; import org.terasology.rendering.assets.material.Material; import org.terasology.rendering.dag.ConditionDependentNode; import org.terasology.rendering.dag.stateChanges.BindFBO; import org.terasology.rendering.dag.stateChanges.EnableMaterial; import org.terasology.rendering.dag.stateChanges.SetInputTextureFromFBO; import org.terasology.rendering.dag.stateChanges.SetViewportToSizeOf; import org.terasology.rendering.opengl.FBO; import org.terasology.rendering.opengl.FBOConfig; import static org.terasology.rendering.opengl.ScalingFactors.FULL_SCALE; import org.terasology.rendering.opengl.FBOManagerSubscriber; import org.terasology.rendering.opengl.fbms.DisplayResolutionDependentFBOs; import org.terasology.rendering.world.WorldRenderer; import static org.terasology.rendering.opengl.OpenGLUtils.renderFullscreenQuad; import static org.terasology.rendering.dag.stateChanges.SetInputTextureFromFBO.FboTexturesTypes.ColorTexture; /** * Instances of this node work in tandem with instances of the AmbientOcclusionNode class. * Together they constitute an ambient occlusion pass. * * This particular node blurs the ambient occlusion output produced by the AmbientOcclusionNode, * making it softer and more subtle. At this stage only the output of this node is used to enhance * the image eventually shown on screen to the user. It is currently not possible to use the (sharper) * output of the AmbientOcclusionNode alone, i.e. to have lower quality but faster ambient occlusion. * * Ambient occlusion is a subtle visual effect that makes the rendering of the world more pleasing * at the cost of some additional milliseconds per frame. Disabling it may lead to increased frame * rate while the gameplay remains unaffected. * * See http://en.wikipedia.org/wiki/Ambient_occlusion for more information on this technique. */ public class BlurredAmbientOcclusionNode extends ConditionDependentNode implements FBOManagerSubscriber { public static final ResourceUrn SSAO_BLURRED_FBO = new ResourceUrn("engine:ssaoBlurred"); private static final ResourceUrn SSAO_FBO = new ResourceUrn("engine:ssao"); private static final ResourceUrn SSAO_BLURRED_MATERIAL = new ResourceUrn("engine:prog.ssaoBlur"); private static final int TEXTURE_SLOT_0 = 0; @In private DisplayResolutionDependentFBOs displayResolutionDependentFBOs; @In private WorldRenderer worldRenderer; @In private Config config; private Material ssaoBlurredMaterial; private float outputFboWidth; private float outputFboHeight; /** * This method must be called once shortly after instantiation to fully initialize the node * and make it ready for rendering. */ @Override public void initialise() { RenderingConfig renderingConfig = config.getRendering(); renderingConfig.subscribe(RenderingConfig.SSAO, this); requiresCondition(renderingConfig::isSsao); addDesiredStateChange(new EnableMaterial(SSAO_BLURRED_MATERIAL.toString())); ssaoBlurredMaterial = getMaterial(SSAO_BLURRED_MATERIAL); requiresFBO(new FBOConfig(SSAO_FBO, FULL_SCALE, FBO.Type.DEFAULT), displayResolutionDependentFBOs); requiresFBO(new FBOConfig(SSAO_BLURRED_FBO, FULL_SCALE, FBO.Type.DEFAULT), displayResolutionDependentFBOs); addDesiredStateChange(new BindFBO(SSAO_BLURRED_FBO, displayResolutionDependentFBOs)); addDesiredStateChange(new SetViewportToSizeOf(SSAO_BLURRED_FBO, displayResolutionDependentFBOs)); addDesiredStateChange(new SetInputTextureFromFBO(TEXTURE_SLOT_0, SSAO_FBO, ColorTexture, displayResolutionDependentFBOs, SSAO_BLURRED_MATERIAL, "tex")); displayResolutionDependentFBOs.subscribe(this); update(); // initializing outputFboWidth/outputFboHeight } /** * If Ambient Occlusion is enabled in the render settings, this method generates and * stores the necessary images into their own FBOs. The stored images are eventually * combined with others to enhance the image shown on screen. * <p> * For further information on Ambient Occlusion see: http://en.wikipedia.org/wiki/Ambient_occlusion */ @Override public void process() { PerformanceMonitor.startActivity("rendering/blurredAmbientOcclusion"); ssaoBlurredMaterial.setFloat2("texelSize", 1.0f / outputFboWidth, 1.0f / outputFboHeight, true); renderFullscreenQuad(); PerformanceMonitor.endActivity(); } @Override public void update() { FBO ssaoBlurredFBO = displayResolutionDependentFBOs.get(SSAO_BLURRED_FBO); outputFboWidth = ssaoBlurredFBO.width(); outputFboHeight = ssaoBlurredFBO.height(); } }