Home | History | Annotate | Download | only in filters
      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 }