1/*
2 * Copyright (c) 2009-2010 jMonkeyEngine
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 *   notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 *   notice, this list of conditions and the following disclaimer in the
14 *   documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17 *   may be used to endorse or promote products derived from this software
18 *   without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32package com.jme3.post.filters;
33
34import com.jme3.asset.AssetManager;
35import com.jme3.material.Material;
36import com.jme3.post.Filter;
37import com.jme3.renderer.RenderManager;
38import com.jme3.renderer.ViewPort;
39
40/**
41 *  A post-processing filter that performs a depth range
42 *  blur using a scaled convolution filter.
43 *
44 *  @version   $Revision: 779 $
45 *  @author    Paul Speed
46 */
47public class DepthOfFieldFilter extends Filter {
48
49    private float focusDistance = 50f;
50    private float focusRange = 10f;
51    private float blurScale = 1f;
52    // These values are set internally based on the
53    // viewport size.
54    private float xScale;
55    private float yScale;
56
57    /**
58     * Creates a DepthOfField filter
59     */
60    public DepthOfFieldFilter() {
61        super("Depth Of Field");
62    }
63
64    @Override
65    protected boolean isRequiresDepthTexture() {
66        return true;
67    }
68
69    @Override
70    protected Material getMaterial() {
71
72        return material;
73    }
74
75    @Override
76    protected void initFilter(AssetManager assets, RenderManager renderManager,
77            ViewPort vp, int w, int h) {
78        material = new Material(assets, "Common/MatDefs/Post/DepthOfField.j3md");
79        material.setFloat("FocusDistance", focusDistance);
80        material.setFloat("FocusRange", focusRange);
81
82
83        xScale = 1.0f / w;
84        yScale = 1.0f / h;
85
86        material.setFloat("XScale", blurScale * xScale);
87        material.setFloat("YScale", blurScale * yScale);
88    }
89
90    /**
91     *  Sets the distance at which objects are purely in focus.
92     */
93    public void setFocusDistance(float f) {
94
95        this.focusDistance = f;
96        if (material != null) {
97            material.setFloat("FocusDistance", focusDistance);
98        }
99
100    }
101
102    /**
103     * returns the focus distance
104     * @return
105     */
106    public float getFocusDistance() {
107        return focusDistance;
108    }
109
110    /**
111     *  Sets the range to either side of focusDistance where the
112     *  objects go gradually out of focus.  Less than focusDistance - focusRange
113     *  and greater than focusDistance + focusRange, objects are maximally "blurred".
114     */
115    public void setFocusRange(float f) {
116        this.focusRange = f;
117        if (material != null) {
118            material.setFloat("FocusRange", focusRange);
119        }
120
121    }
122
123    /**
124     * returns the focus range
125     * @return
126     */
127    public float getFocusRange() {
128        return focusRange;
129    }
130
131    /**
132     *  Sets the blur amount by scaling the convolution filter up or
133     *  down.  A value of 1 (the default) performs a sparse 5x5 evenly
134     *  distribubted convolution at pixel level accuracy.  Higher values skip
135     *  more pixels, and so on until you are no longer blurring the image
136     *  but simply hashing it.
137     *
138     *  The sparse convolution is as follows:
139     *%MINIFYHTMLc3d0cd9fab65de6875a381fd3f83e1b338%*
140     *  Where 'x' is the texel being modified.  Setting blur scale higher
141     *  than 1 spaces the samples out.
142     */
143    public void setBlurScale(float f) {
144        this.blurScale = f;
145        if (material != null) {
146            material.setFloat("XScale", blurScale * xScale);
147            material.setFloat("YScale", blurScale * yScale);
148        }
149    }
150
151    /**
152     * returns the blur scale
153     * @return
154     */
155    public float getBlurScale() {
156        return blurScale;
157    }
158}
159