• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
32 package com.jme3.post.filters;
33 
34 import com.jme3.asset.AssetManager;
35 import com.jme3.material.Material;
36 import com.jme3.math.ColorRGBA;
37 import com.jme3.post.Filter;
38 import com.jme3.post.Filter.Pass;
39 import com.jme3.renderer.RenderManager;
40 import com.jme3.renderer.Renderer;
41 import com.jme3.renderer.ViewPort;
42 import com.jme3.texture.Image.Format;
43 
44 /**
45  * Applies a cartoon-style edge detection filter to all objects in the scene.
46  *
47  * @author Kirill Vainer
48  */
49 public class CartoonEdgeFilter extends Filter {
50 
51     private Pass normalPass;
52     private float edgeWidth = 1.0f;
53     private float edgeIntensity = 1.0f;
54     private float normalThreshold = 0.5f;
55     private float depthThreshold = 0.1f;
56     private float normalSensitivity = 1.0f;
57     private float depthSensitivity = 10.0f;
58     private ColorRGBA edgeColor = new ColorRGBA(0, 0, 0, 1);
59 
60     /**
61      * Creates a CartoonEdgeFilter
62      */
CartoonEdgeFilter()63     public CartoonEdgeFilter() {
64         super("CartoonEdgeFilter");
65     }
66 
67     @Override
isRequiresDepthTexture()68     protected boolean isRequiresDepthTexture() {
69         return true;
70     }
71 
72     @Override
postQueue(RenderManager renderManager, ViewPort viewPort)73     protected void postQueue(RenderManager renderManager, ViewPort viewPort) {
74         Renderer r = renderManager.getRenderer();
75         r.setFrameBuffer(normalPass.getRenderFrameBuffer());
76         renderManager.getRenderer().clearBuffers(true, true, true);
77         renderManager.setForcedTechnique("PreNormalPass");
78         renderManager.renderViewPortQueues(viewPort, false);
79         renderManager.setForcedTechnique(null);
80         renderManager.getRenderer().setFrameBuffer(viewPort.getOutputFrameBuffer());
81     }
82 
83     @Override
getMaterial()84     protected Material getMaterial() {
85         material.setTexture("NormalsTexture", normalPass.getRenderedTexture());
86         return material;
87     }
88 
89     @Override
initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h)90     protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
91         normalPass = new Pass();
92         normalPass.init(renderManager.getRenderer(), w, h, Format.RGBA8, Format.Depth);
93         material = new Material(manager, "Common/MatDefs/Post/CartoonEdge.j3md");
94         material.setFloat("EdgeWidth", edgeWidth);
95         material.setFloat("EdgeIntensity", edgeIntensity);
96         material.setFloat("NormalThreshold", normalThreshold);
97         material.setFloat("DepthThreshold", depthThreshold);
98         material.setFloat("NormalSensitivity", normalSensitivity);
99         material.setFloat("DepthSensitivity", depthSensitivity);
100         material.setColor("EdgeColor", edgeColor);
101     }
102 
103     /**
104      * Return the depth sensitivity<br>
105      * for more details see {@link setDepthSensitivity(float depthSensitivity)}
106      * @return
107      */
getDepthSensitivity()108     public float getDepthSensitivity() {
109         return depthSensitivity;
110     }
111 
112     /**
113      * sets the depth sensitivity<br>
114      * defines how much depth will influence edges, default is 10
115      * @param depthSensitivity
116      */
setDepthSensitivity(float depthSensitivity)117     public void setDepthSensitivity(float depthSensitivity) {
118         this.depthSensitivity = depthSensitivity;
119         if (material != null) {
120             material.setFloat("DepthSensitivity", depthSensitivity);
121         }
122     }
123 
124     /**
125      * returns the depth threshold<br>
126      * for more details see {@link setDepthThreshold(float depthThreshold)}
127      * @return
128      */
getDepthThreshold()129     public float getDepthThreshold() {
130         return depthThreshold;
131     }
132 
133     /**
134      * sets the depth threshold<br>
135      * Defines at what threshold of difference of depth an edge is outlined default is 0.1f
136      * @param depthThreshold
137      */
setDepthThreshold(float depthThreshold)138     public void setDepthThreshold(float depthThreshold) {
139         this.depthThreshold = depthThreshold;
140         if (material != null) {
141             material.setFloat("DepthThreshold", depthThreshold);
142         }
143     }
144 
145     /**
146      * returns the edge intensity<br>
147      * for more details see {@link setEdgeIntensity(float edgeIntensity) }
148      * @return
149      */
getEdgeIntensity()150     public float getEdgeIntensity() {
151         return edgeIntensity;
152     }
153 
154     /**
155      * sets the edge intensity<br>
156      * Defineshow visilble will be the outlined edges
157      * @param edgeIntensity
158      */
setEdgeIntensity(float edgeIntensity)159     public void setEdgeIntensity(float edgeIntensity) {
160         this.edgeIntensity = edgeIntensity;
161         if (material != null) {
162             material.setFloat("EdgeIntensity", edgeIntensity);
163         }
164     }
165 
166     /**
167      * returns the width of the edges
168      * @return
169      */
getEdgeWidth()170     public float getEdgeWidth() {
171         return edgeWidth;
172     }
173 
174     /**
175      * sets the witdh of the edge in pixels default is 1
176      * @param edgeWidth
177      */
setEdgeWidth(float edgeWidth)178     public void setEdgeWidth(float edgeWidth) {
179         this.edgeWidth = edgeWidth;
180         if (material != null) {
181             material.setFloat("EdgeWidth", edgeWidth);
182         }
183 
184     }
185 
186     /**
187      * returns the normals sensitivity<br>
188      * form more details see {@link setNormalSensitivity(float normalSensitivity)}
189      * @return
190      */
getNormalSensitivity()191     public float getNormalSensitivity() {
192         return normalSensitivity;
193     }
194 
195     /**
196      * sets the normals sensitivity default is 1
197      * @param normalSensitivity
198      */
setNormalSensitivity(float normalSensitivity)199     public void setNormalSensitivity(float normalSensitivity) {
200         this.normalSensitivity = normalSensitivity;
201         if (material != null) {
202             material.setFloat("NormalSensitivity", normalSensitivity);
203         }
204     }
205 
206     /**
207      * returns the normal threshold<br>
208      * for more details see {@link setNormalThreshold(float normalThreshold)}
209      *
210      * @return
211      */
getNormalThreshold()212     public float getNormalThreshold() {
213         return normalThreshold;
214     }
215 
216     /**
217      * sets the normal threshold default is 0.5
218      * @param normalThreshold
219      */
setNormalThreshold(float normalThreshold)220     public void setNormalThreshold(float normalThreshold) {
221         this.normalThreshold = normalThreshold;
222         if (material != null) {
223             material.setFloat("NormalThreshold", normalThreshold);
224         }
225     }
226 
227     /**
228      * returns the edge color
229      * @return
230      */
getEdgeColor()231     public ColorRGBA getEdgeColor() {
232         return edgeColor;
233     }
234 
235     /**
236      * Sets the edge color, default is black
237      * @param edgeColor
238      */
setEdgeColor(ColorRGBA edgeColor)239     public void setEdgeColor(ColorRGBA edgeColor) {
240         this.edgeColor = edgeColor;
241         if (material != null) {
242             material.setColor("EdgeColor", edgeColor);
243         }
244     }
245 }
246