diff --git a/engine/src/core-data/Common/ShaderLib/WaterUtil.glsllib b/engine/src/core-data/Common/ShaderLib/WaterUtil.glsllib new file mode 100644 index 000000000..51c4d8af8 --- /dev/null +++ b/engine/src/core-data/Common/ShaderLib/WaterUtil.glsllib @@ -0,0 +1,10 @@ +#ifdef ENABLE_AREA +bool isOverExtent(vec3 position,vec3 center,float radius){ + vec2 dist = position.xz-center.xz; + #ifdef SQUARE_AREA + return dist.x*dist.x >radius || dist.y*dist.y >radius; + #else + return dot(dist,dist)>radius; + #endif +} +#endif \ No newline at end of file diff --git a/engine/src/core-effects/Common/MatDefs/Water/Water.frag b/engine/src/core-effects/Common/MatDefs/Water/Water.frag index 867c335b3..1faaab07a 100644 --- a/engine/src/core-effects/Common/MatDefs/Water/Water.frag +++ b/engine/src/core-effects/Common/MatDefs/Water/Water.frag @@ -1,3 +1,4 @@ +#import "Common/ShaderLib/WaterUtil.glsllib" // Water pixel shader // Copyright (C) JMonkeyEngine 3.0 // by Remy Bouquet (nehon) for JMonkeyEngine 3.0 @@ -241,7 +242,7 @@ void main(){ if(level >= m_CameraPosition.y){ #ifdef ENABLE_AREA vec3 dist = m_CameraPosition-m_Center; - if(dot(dist,dist) >m_Radius){ + if(isOverExtent(m_CameraPosition, m_Center, m_Radius)){ gl_FragColor = vec4(color2, 1.0); return; } @@ -251,8 +252,7 @@ void main(){ } #ifdef ENABLE_AREA - vec3 dist = position-m_Center; - if(dot(dist,dist) >m_Radius){ + if(isOverExtent(position, m_Center, m_Radius)){ gl_FragColor = vec4(color2, 1.0); return; } diff --git a/engine/src/core-effects/Common/MatDefs/Water/Water.j3md b/engine/src/core-effects/Common/MatDefs/Water/Water.j3md index b09003a54..d1f0b17f2 100644 --- a/engine/src/core-effects/Common/MatDefs/Water/Water.j3md +++ b/engine/src/core-effects/Common/MatDefs/Water/Water.j3md @@ -47,6 +47,7 @@ MaterialDef Advanced Water { Float Radius Vector3 Center + Boolean SquareArea } @@ -68,7 +69,7 @@ MaterialDef Advanced Water { ENABLE_CAUSTICS : UseCaustics ENABLE_REFRACTION : UseRefraction ENABLE_AREA : Center - + SQUARE_AREA : SquareArea } } @@ -87,6 +88,7 @@ MaterialDef Advanced Water { ENABLE_CAUSTICS : UseCaustics ENABLE_REFRACTION : UseRefraction ENABLE_AREA : Center + SQUARE_AREA : SquareArea } } } \ No newline at end of file diff --git a/engine/src/core-effects/Common/MatDefs/Water/Water15.frag b/engine/src/core-effects/Common/MatDefs/Water/Water15.frag index 1acad4eb5..55881a0db 100644 --- a/engine/src/core-effects/Common/MatDefs/Water/Water15.frag +++ b/engine/src/core-effects/Common/MatDefs/Water/Water15.frag @@ -1,4 +1,5 @@ #import "Common/ShaderLib/MultiSample.glsllib" +#import "Common/ShaderLib/WaterUtil.glsllib" // Water pixel shader // Copyright (C) JMonkeyEngine 3.0 @@ -229,13 +230,14 @@ vec4 underWater(int sampleNum){ return vec4(color, 1.0); } + + // NOTE: This will be called even for single-sampling vec4 main_multiSample(int sampleNum){ // If we are underwater let's call the underwater function if(m_WaterHeight >= m_CameraPosition.y){ - #ifdef ENABLE_AREA - vec2 dist = m_CameraPosition.xz-m_Center.xz; - if(dot(dist,dist) >m_Radius){ + #ifdef ENABLE_AREA + if(isOverExtent(m_CameraPosition, m_Center, m_Radius)){ return fetchTextureSample(m_Texture, texCoord, sampleNum); } #endif @@ -248,10 +250,9 @@ vec4 main_multiSample(int sampleNum){ vec3 color = color2; vec3 position = getPosition(sceneDepth, texCoord); - #ifdef ENABLE_AREA - vec2 dist = position.xz-m_Center.xz; - if(dot(dist,dist) >m_Radius){ - return vec4(color2, 1.0); + #ifdef ENABLE_AREA + if(isOverExtent(position, m_Center, m_Radius)){ + return vec4(color2, 1.0); } #endif diff --git a/engine/src/core-effects/com/jme3/water/WaterFilter.java b/engine/src/core-effects/com/jme3/water/WaterFilter.java index d4cb8b410..39ebeccea 100644 --- a/engine/src/core-effects/com/jme3/water/WaterFilter.java +++ b/engine/src/core-effects/com/jme3/water/WaterFilter.java @@ -118,6 +118,12 @@ public class WaterFilter extends Filter { //positional attributes private Vector3f center; private float radius; + private AreaShape shapeType = AreaShape.Circular; + + public enum AreaShape{ + Circular, + Square + } /** * Create a Water Filter @@ -300,6 +306,7 @@ public class WaterFilter extends Filter { if (center != null) { material.setVector3("Center", center); material.setFloat("Radius", radius * radius); + material.setBoolean("SquareArea", shapeType==AreaShape.Square); } @@ -1055,6 +1062,10 @@ public class WaterFilter extends Filter { } } + /** + * returns the center of this effect + * @return the center of this effect + */ public Vector3f getCenter() { return center; } @@ -1072,6 +1083,10 @@ public class WaterFilter extends Filter { } } + /** + * returns the radius of this effect + * @return the radius of this effect + */ public float getRadius() { return radius; @@ -1089,4 +1104,26 @@ public class WaterFilter extends Filter { material.setFloat("Radius", radius * radius); } } + + /** + * returns the shape of the water area + * @return the shape of the water area + */ + public AreaShape getShapeType() { + return shapeType; + } + + /** + * Set the shape of the water area (Circular (default) or Square). + * if the shape is square the radius is considered as an extent. + * @param shapeType the shape type + */ + public void setShapeType(AreaShape shapeType) { + this.shapeType = shapeType; + if (material != null) { + material.setBoolean("SquareArea", shapeType==AreaShape.Square); + } + } + + }