1 /* 2 * Copyright (c) 2009-2012 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.renderer.RenderManager; 39 import com.jme3.renderer.ViewPort; 40 41 /** 42 * A Post Processing filter that makes the screen look like it was drawn as 43 * diagonal lines with a pen. 44 * Try combining this with a cartoon edge filter to obtain manga style visuals. 45 * 46 * Based on an article from Geeks3D: 47 * <a href="http://www.geeks3d.com/20110219/shader-library-crosshatching-glsl-filter/" rel="nofollow">http://www.geeks3d.com/20110219/shader-library-crosshatching-glsl-filter/</a> 48 * 49 * @author Roy Straver a.k.a. Baal Garnaal 50 */ 51 public class CrossHatchFilter extends Filter { 52 53 private ColorRGBA lineColor = ColorRGBA.Black.clone(); 54 private ColorRGBA paperColor = ColorRGBA.White.clone(); 55 private float colorInfluenceLine = 0.8f; 56 private float colorInfluencePaper = 0.1f; 57 private float fillValue = 0.9f; 58 private float luminance1 = 0.9f; 59 private float luminance2 = 0.7f; 60 private float luminance3 = 0.5f; 61 private float luminance4 = 0.3f; 62 private float luminance5 = 0.0f; 63 private float lineThickness = 1.0f; 64 private float lineDistance = 4.0f; 65 66 /** 67 * Creates a crossHatch filter 68 */ 69 public CrossHatchFilter() { 70 super("CrossHatchFilter"); 71 } 72 73 /** 74 * Creates a crossHatch filter 75 * @param lineColor the colors of the lines 76 * @param paperColor the paper color 77 */ 78 public CrossHatchFilter(ColorRGBA lineColor, ColorRGBA paperColor) { 79 this(); 80 this.lineColor = lineColor; 81 this.paperColor = paperColor; 82 } 83 84 @Override 85 protected boolean isRequiresDepthTexture() { 86 return false; 87 } 88 89 @Override 90 protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) { 91 material = new Material(manager, "Common/MatDefs/Post/CrossHatch.j3md"); 92 material.setColor("LineColor", lineColor); 93 material.setColor("PaperColor", paperColor); 94 95 material.setFloat("ColorInfluenceLine", colorInfluenceLine); 96 material.setFloat("ColorInfluencePaper", colorInfluencePaper); 97 98 material.setFloat("FillValue", fillValue); 99 100 material.setFloat("Luminance1", luminance1); 101 material.setFloat("Luminance2", luminance2); 102 material.setFloat("Luminance3", luminance3); 103 material.setFloat("Luminance4", luminance4); 104 material.setFloat("Luminance5", luminance5); 105 106 material.setFloat("LineThickness", lineThickness); 107 material.setFloat("LineDistance", lineDistance); 108 } 109 110 @Override 111 protected Material getMaterial() { 112 return material; 113 } 114 115 /** 116 * Sets color used to draw lines 117 * @param lineColor 118 */ 119 public void setLineColor(ColorRGBA lineColor) { 120 this.lineColor = lineColor; 121 if (material != null) { 122 material.setColor("LineColor", lineColor); 123 } 124 } 125 126 /** 127 * Sets color used as background 128 * @param paperColor 129 */ 130 public void setPaperColor(ColorRGBA paperColor) { 131 this.paperColor = paperColor; 132 if (material != null) { 133 material.setColor("PaperColor", paperColor); 134 } 135 } 136 137 /** 138 * Sets color influence of original image on lines drawn 139 * @param colorInfluenceLine 140 */ 141 public void setColorInfluenceLine(float colorInfluenceLine) { 142 this.colorInfluenceLine = colorInfluenceLine; 143 if (material != null) { 144 material.setFloat("ColorInfluenceLine", colorInfluenceLine); 145 } 146 } 147 148 /** 149 * Sets color influence of original image on non-line areas 150 * @param colorInfluencePaper 151 */ 152 public void setColorInfluencePaper(float colorInfluencePaper) { 153 this.colorInfluencePaper = colorInfluencePaper; 154 if (material != null) { 155 material.setFloat("ColorInfluencePaper", colorInfluencePaper); 156 } 157 } 158 159 /** 160 * Sets line/paper color ratio for areas with values < luminance5, 161 * really dark areas get no lines but a filled blob instead 162 * @param fillValue 163 */ 164 public void setFillValue(float fillValue) { 165 this.fillValue = fillValue; 166 if (material != null) { 167 material.setFloat("FillValue", fillValue); 168 } 169 } 170 171 /** 172 * 173 * Sets minimum luminance levels for lines drawn 174 * @param luminance1 Top-left to down right 1 175 * @param luminance2 Top-right to bottom left 1 176 * @param luminance3 Top-left to down right 2 177 * @param luminance4 Top-right to bottom left 2 178 * @param luminance5 Blobs 179 */ 180 public void setLuminanceLevels(float luminance1, float luminance2, float luminance3, float luminance4, float luminance5) { 181 this.luminance1 = luminance1; 182 this.luminance2 = luminance2; 183 this.luminance3 = luminance3; 184 this.luminance4 = luminance4; 185 this.luminance5 = luminance5; 186 187 if (material != null) { 188 material.setFloat("Luminance1", luminance1); 189 material.setFloat("Luminance2", luminance2); 190 material.setFloat("Luminance3", luminance3); 191 material.setFloat("Luminance4", luminance4); 192 material.setFloat("Luminance5", luminance5); 193 } 194 } 195 196 /** 197 * Sets the thickness of lines drawn 198 * @param lineThickness 199 */ 200 public void setLineThickness(float lineThickness) { 201 this.lineThickness = lineThickness; 202 if (material != null) { 203 material.setFloat("LineThickness", lineThickness); 204 } 205 } 206 207 /** 208 * Sets minimum distance between lines drawn 209 * Primary lines are drawn at 2*lineDistance 210 * Secondary lines are drawn at lineDistance 211 * @param lineDistance 212 */ 213 public void setLineDistance(float lineDistance) { 214 this.lineDistance = lineDistance; 215 if (material != null) { 216 material.setFloat("LineDistance", lineDistance); 217 } 218 } 219 220 /** 221 * Returns line color 222 * @return 223 */ 224 public ColorRGBA getLineColor() { 225 return lineColor; 226 } 227 228 /** 229 * Returns paper background color 230 * @return 231 */ 232 public ColorRGBA getPaperColor() { 233 return paperColor; 234 } 235 236 /** 237 * Returns current influence of image colors on lines 238 */ 239 public float getColorInfluenceLine() { 240 return colorInfluenceLine; 241 } 242 243 /** 244 * Returns current influence of image colors on paper background 245 */ 246 public float getColorInfluencePaper() { 247 return colorInfluencePaper; 248 } 249 250 /** 251 * Returns line/paper color ratio for blobs 252 */ 253 public float getFillValue() { 254 return fillValue; 255 } 256 257 /** 258 * Returns the thickness of the lines drawn 259 */ 260 public float getLineThickness() { 261 return lineThickness; 262 } 263 264 /** 265 * Returns minimum distance between lines 266 */ 267 public float getLineDistance() { 268 return lineDistance; 269 } 270 271 /** 272 * Returns treshold for lines 1 273 */ 274 public float getLuminance1() { 275 return luminance1; 276 } 277 278 /** 279 * Returns treshold for lines 2 280 */ 281 public float getLuminance2() { 282 return luminance2; 283 } 284 285 /** 286 * Returns treshold for lines 3 287 */ 288 public float getLuminance3() { 289 return luminance3; 290 } 291 292 /** 293 * Returns treshold for lines 4 294 */ 295 public float getLuminance4() { 296 return luminance4; 297 } 298 299 /** 300 * Returns treshold for blobs 301 */ 302 public float getLuminance5() { 303 return luminance5; 304 } 305 }