Package com.ardor3d.extension.effect

Source Code of com.ardor3d.extension.effect.HDREffect

/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/

package com.ardor3d.extension.effect;

import com.ardor3d.framework.DisplaySettings;
import com.ardor3d.image.TextureStoreFormat;
import com.ardor3d.image.Texture.MagnificationFilter;
import com.ardor3d.image.Texture.MinificationFilter;
import com.ardor3d.image.Texture.WrapMode;
import com.ardor3d.renderer.effect.EffectManager;
import com.ardor3d.renderer.effect.EffectStep_RenderScreenOverlay;
import com.ardor3d.renderer.effect.EffectStep_SetRenderTarget;
import com.ardor3d.renderer.effect.RenderEffect;
import com.ardor3d.renderer.effect.RenderTarget;
import com.ardor3d.renderer.effect.RenderTarget_Texture2D;
import com.ardor3d.renderer.state.GLSLShaderObjectsState;
import com.ardor3d.renderer.state.RenderState;
import com.ardor3d.renderer.state.RenderState.StateType;
import com.ardor3d.util.resource.ResourceLocatorTool;

public class HDREffect extends RenderEffect {
    private String shaderDirectory = "com/ardor3d/extension/effect/";

    protected static final String RT_DOWNSAMPLED = "HDREffect.DOWNSAMPLED";
    protected static final String RT_LUM64x64 = "HDREffect.LUM64x64";
    protected static final String RT_LUM16x16 = "HDREffect.LUM16x16";
    protected static final String RT_LUM1x1 = "HDREffect.LUM1x1";
    protected static final String RT_BRIGHTMAP = "HDREffect.BRIGHTMAP";
    protected static final String RT_BLOOM_HORIZONTAL = "HDREffect.BLOOM_HORIZONTAL";
    protected static final String RT_BLOOM = "HDREffect.BLOOM";

    protected float _downsampleRatio = 0.25f;

    @Override
    public void prepare(final EffectManager manager) {
        // init targets used in this effect
        initTargets(manager);

        _steps.clear();

        // step 1: downsample previous rendering in chain
        {
            _steps.add(new EffectStep_SetRenderTarget(RT_DOWNSAMPLED));
            final EffectStep_RenderScreenOverlay downsample = new EffectStep_RenderScreenOverlay();
            downsample.getTargetMap().put("*Previous", 0);
            _steps.add(downsample);
        }

        // step 2: extract our average luminance value
        {
            _steps.add(new EffectStep_SetRenderTarget(RT_LUM64x64));
            final EffectStep_RenderScreenOverlay extract64 = new EffectStep_RenderScreenOverlay();
            extract64.getEnforcedStates().put(StateType.GLSLShader, getLuminanceExtractionShader());
            extract64.getTargetMap().put(RT_DOWNSAMPLED, 0);
            _steps.add(extract64);

            _steps.add(new EffectStep_SetRenderTarget(RT_LUM16x16));
            final EffectStep_RenderScreenOverlay extract4 = new EffectStep_RenderScreenOverlay();
            extract4.getTargetMap().put(RT_LUM64x64, 0);
            _steps.add(extract4);

            _steps.add(new EffectStep_SetRenderTarget(RT_LUM1x1));
            final EffectStep_RenderScreenOverlay extract1 = new EffectStep_RenderScreenOverlay();
            extract1.getTargetMap().put(RT_LUM16x16, 0);
            _steps.add(extract1);
        }

        // step 3: apply bright pass, extracting the brighter than normal portions of the scene
        {
            _steps.add(new EffectStep_SetRenderTarget(RT_BRIGHTMAP));
            final EffectStep_RenderScreenOverlay bright = new EffectStep_RenderScreenOverlay();
            bright.getEnforcedStates().put(StateType.GLSLShader, getBrightMapShader());
            bright.getTargetMap().put(RT_DOWNSAMPLED, 0);
            bright.getTargetMap().put(RT_LUM1x1, 1);
            _steps.add(bright);
        }

        // finally: draw bloom texture and previous texture on fsq, blended.
        _steps.add(new EffectStep_SetRenderTarget("*Next"));

        final EffectStep_RenderScreenOverlay blendOverlay = new EffectStep_RenderScreenOverlay();
        blendOverlay.getTargetMap().put(RT_BRIGHTMAP, 0);
        _steps.add(blendOverlay);

        super.prepare(manager);
    }

    private RenderState getLuminanceExtractionShader() {
        final GLSLShaderObjectsState shader = new GLSLShaderObjectsState();
        try {
            shader.setVertexShader(ResourceLocatorTool.getClassPathResourceAsStream(ColorReplaceEffect.class,
                    shaderDirectory + "fsq.vert"));
            shader.setFragmentShader(ResourceLocatorTool.getClassPathResourceAsStream(ColorReplaceEffect.class,
                    shaderDirectory + "luminance.frag"));
        } catch (final Exception e) {
            e.printStackTrace();
        }
        shader.setUniform("inputTex", 0);
        return shader;
    }

    private RenderState getBrightMapShader() {
        final GLSLShaderObjectsState shader = new GLSLShaderObjectsState();
        try {
            shader.setVertexShader(ResourceLocatorTool.getClassPathResourceAsStream(ColorReplaceEffect.class,
                    shaderDirectory + "fsq.vert"));
            shader.setFragmentShader(ResourceLocatorTool.getClassPathResourceAsStream(ColorReplaceEffect.class,
                    shaderDirectory + "brightmap.frag"));
        } catch (final Exception e) {
            e.printStackTrace();
        }
        shader.setUniform("inputTex", 0);
        shader.setUniform("lum1x1Tex", 1);
        shader.setUniform("exposurePow", 3.0f);
        shader.setUniform("exposureCutoff", 0.0f);
        return shader;
    }

    private void initTargets(final EffectManager manager) {
        final DisplaySettings canvas = manager.getCanvasSettings();
        final int downsampledHeight = Math.round(canvas.getHeight() * _downsampleRatio);
        final int downsampledWidth = Math.round(canvas.getWidth() * _downsampleRatio);

        final RenderTarget_Texture2D downsampled = new RenderTarget_Texture2D(downsampledWidth, downsampledHeight,
                TextureStoreFormat.RGBA16F);
        downsampled.getTexture().setWrap(WrapMode.Clamp);
        manager.getRenderTargetMap().put(RT_DOWNSAMPLED, downsampled);

        manager.getRenderTargetMap().put(RT_LUM64x64, getLuminanceDownsampleTexture(64));
        manager.getRenderTargetMap().put(RT_LUM16x16, getLuminanceDownsampleTexture(16));
        manager.getRenderTargetMap().put(RT_LUM1x1, getLuminanceDownsampleTexture(1));

        final RenderTarget_Texture2D brightmap = new RenderTarget_Texture2D(downsampledWidth, downsampledHeight,
                TextureStoreFormat.RGBA16F);
        brightmap.getTexture().setWrap(WrapMode.Clamp);
        manager.getRenderTargetMap().put(RT_BRIGHTMAP, brightmap);

        final RenderTarget_Texture2D bloomHoriz = new RenderTarget_Texture2D(downsampledWidth, downsampledHeight,
                TextureStoreFormat.RGBA8);
        bloomHoriz.getTexture().setWrap(WrapMode.Clamp);
        manager.getRenderTargetMap().put(RT_BLOOM_HORIZONTAL, bloomHoriz);

        final RenderTarget_Texture2D bloom = new RenderTarget_Texture2D(downsampledWidth, downsampledHeight,
                TextureStoreFormat.RGBA8);
        bloom.getTexture().setWrap(WrapMode.Clamp);
        manager.getRenderTargetMap().put(RT_BLOOM, bloom);
    }

    private RenderTarget getLuminanceDownsampleTexture(final int size) {
        final RenderTarget_Texture2D target = new RenderTarget_Texture2D(size, size, TextureStoreFormat.RGBA16F);
        if (size != 1) {
            target.getTexture().setMinificationFilter(MinificationFilter.Trilinear);
            target.getTexture().setMagnificationFilter(MagnificationFilter.Bilinear);
        } else {
            target.getTexture().setMinificationFilter(MinificationFilter.NearestNeighborNoMipMaps);
            target.getTexture().setMagnificationFilter(MagnificationFilter.NearestNeighbor);
        }

        target.getTexture().setWrap(WrapMode.Clamp);
        return target;
    }

    public float getDownsampleRatio() {
        return _downsampleRatio;
    }

    public void setDownsampleRatio(final float downsampleRatio) {
        _downsampleRatio = downsampleRatio;
    }

    public String getShaderDirectory() {
        return shaderDirectory;
    }

    public void setShaderDirectory(final String shaderDirectory) {
        this.shaderDirectory = shaderDirectory;
    }
}
TOP

Related Classes of com.ardor3d.extension.effect.HDREffect

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.