- move effects and networking to separate jar files
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9190 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
<target name="-do-compile" description="Overrides default compile target to separate the build into folders" depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources">
|
<target name="-do-compile" description="Overrides default compile target to separate the build into folders" depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources">
|
||||||
<mkdir dir="${build.dir}/core"/>
|
<mkdir dir="${build.dir}/core"/>
|
||||||
|
<mkdir dir="${build.dir}/effects"/>
|
||||||
|
<mkdir dir="${build.dir}/networking"/>
|
||||||
<mkdir dir="${build.dir}/plugins"/>
|
<mkdir dir="${build.dir}/plugins"/>
|
||||||
<mkdir dir="${build.dir}/jogg"/>
|
<mkdir dir="${build.dir}/jogg"/>
|
||||||
<mkdir dir="${build.dir}/blender"/>
|
<mkdir dir="${build.dir}/blender"/>
|
||||||
@ -35,7 +37,7 @@
|
|||||||
<echo>Compile Core</echo>
|
<echo>Compile Core</echo>
|
||||||
<j2seproject3:javac
|
<j2seproject3:javac
|
||||||
destdir="${build.dir}/core"
|
destdir="${build.dir}/core"
|
||||||
srcdir="${src.core.dir}:${src.core-data.dir}:${src.core-plugins.dir}:${src.tools.dir}:${src.networking.dir}"
|
srcdir="${src.core.dir}:${src.core-data.dir}:${src.core-plugins.dir}:${src.tools.dir}"
|
||||||
gensrcdir="${build.generated.sources.dir}"/>
|
gensrcdir="${build.generated.sources.dir}"/>
|
||||||
<copy todir="${build.dir}/core">
|
<copy todir="${build.dir}/core">
|
||||||
<fileset dir="${src.core.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
<fileset dir="${src.core.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
||||||
@ -44,6 +46,26 @@
|
|||||||
<fileset dir="${src.tools.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
<fileset dir="${src.tools.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
||||||
</copy>
|
</copy>
|
||||||
|
|
||||||
|
<echo>Compile Effects</echo>
|
||||||
|
<j2seproject3:javac
|
||||||
|
destdir="${build.dir}/effects"
|
||||||
|
srcdir="${src.core-effects.dir}"
|
||||||
|
classpath="${javac.classpath}:${build.dir}/core"
|
||||||
|
gensrcdir="${build.generated.sources.dir}"/>
|
||||||
|
<copy todir="${build.dir}/effects">
|
||||||
|
<fileset dir="${src.core-effects.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
||||||
|
</copy>
|
||||||
|
|
||||||
|
<echo>Compile Networking</echo>
|
||||||
|
<j2seproject3:javac
|
||||||
|
destdir="${build.dir}/networking"
|
||||||
|
srcdir="${src.networking.dir}"
|
||||||
|
classpath="${javac.classpath}:${build.dir}/core"
|
||||||
|
gensrcdir="${build.generated.sources.dir}"/>
|
||||||
|
<copy todir="${build.dir}/networking">
|
||||||
|
<fileset dir="${src.networking.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
||||||
|
</copy>
|
||||||
|
|
||||||
<echo>Compile Plugins (Ogre, XML)</echo>
|
<echo>Compile Plugins (Ogre, XML)</echo>
|
||||||
<j2seproject3:javac
|
<j2seproject3:javac
|
||||||
destdir="${build.dir}/plugins"
|
destdir="${build.dir}/plugins"
|
||||||
@ -153,7 +175,7 @@
|
|||||||
<j2seproject3:javac
|
<j2seproject3:javac
|
||||||
destdir="${build.classes.dir}"
|
destdir="${build.classes.dir}"
|
||||||
srcdir="${src.test.dir}"
|
srcdir="${src.test.dir}"
|
||||||
classpath="${javac.classpath}:${build.dir}/core:${build.dir}/plugins:${build.dir}/jogg:${build.dir}/desktop:${build.dir}/blender:${build.dir}/terrain:${build.dir}/jbullet:${build.dir}/niftygui"
|
classpath="${javac.classpath}:${build.dir}/core:${build.dir}/effects:${build.dir}/networking:${build.dir}/plugins:${build.dir}/jogg:${build.dir}/desktop:${build.dir}/blender:${build.dir}/terrain:${build.dir}/jbullet:${build.dir}/niftygui"
|
||||||
gensrcdir="${build.generated.sources.dir}"/>
|
gensrcdir="${build.generated.sources.dir}"/>
|
||||||
<copy todir="${build.classes.dir}">
|
<copy todir="${build.classes.dir}">
|
||||||
<fileset dir="${src.test.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
<fileset dir="${src.test.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
||||||
@ -163,6 +185,8 @@
|
|||||||
<target name="-pre-jar" description="Prepares the separate jME3-xxx.jar files and modifies properties for libraries to be used for lib/ folder, Manifest etc.">
|
<target name="-pre-jar" description="Prepares the separate jME3-xxx.jar files and modifies properties for libraries to be used for lib/ folder, Manifest etc.">
|
||||||
<echo>Building Engine JAR files..</echo>
|
<echo>Building Engine JAR files..</echo>
|
||||||
<jar jarfile="${build.dir}/jME3-core.jar" basedir="${build.dir}/core" compress="true"/>
|
<jar jarfile="${build.dir}/jME3-core.jar" basedir="${build.dir}/core" compress="true"/>
|
||||||
|
<jar jarfile="${build.dir}/jME3-effects.jar" basedir="${build.dir}/effects" compress="true"/>
|
||||||
|
<jar jarfile="${build.dir}/jME3-networking.jar" basedir="${build.dir}/networking" compress="true"/>
|
||||||
<jar jarfile="${build.dir}/jME3-plugins.jar" basedir="${build.dir}/plugins" compress="true"/>
|
<jar jarfile="${build.dir}/jME3-plugins.jar" basedir="${build.dir}/plugins" compress="true"/>
|
||||||
<jar jarfile="${build.dir}/jME3-jogg.jar" basedir="${build.dir}/jogg" compress="true"/>
|
<jar jarfile="${build.dir}/jME3-jogg.jar" basedir="${build.dir}/jogg" compress="true"/>
|
||||||
<jar jarfile="${build.dir}/jME3-desktop.jar" basedir="${build.dir}/desktop" compress="true"/>
|
<jar jarfile="${build.dir}/jME3-desktop.jar" basedir="${build.dir}/desktop" compress="true"/>
|
||||||
@ -183,6 +207,8 @@
|
|||||||
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
|
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
|
||||||
|
|
||||||
<property location="${build.dir}/core" name="build.core.dir.resolved"/>
|
<property location="${build.dir}/core" name="build.core.dir.resolved"/>
|
||||||
|
<property location="${build.dir}/effects" name="build.effects.dir.resolved"/>
|
||||||
|
<property location="${build.dir}/networking" name="build.networking.dir.resolved"/>
|
||||||
<property location="${build.dir}/plugins" name="build.plugins.dir.resolved"/>
|
<property location="${build.dir}/plugins" name="build.plugins.dir.resolved"/>
|
||||||
<property location="${build.dir}/jogg" name="build.jogg.dir.resolved"/>
|
<property location="${build.dir}/jogg" name="build.jogg.dir.resolved"/>
|
||||||
<property location="${build.dir}/desktop" name="build.desktop.dir.resolved"/>
|
<property location="${build.dir}/desktop" name="build.desktop.dir.resolved"/>
|
||||||
@ -199,6 +225,8 @@
|
|||||||
<map from="${build.classes.dir.resolved}" to=""/>
|
<map from="${build.classes.dir.resolved}" to=""/>
|
||||||
|
|
||||||
<map from="${build.core.dir.resolved}" to=""/>
|
<map from="${build.core.dir.resolved}" to=""/>
|
||||||
|
<map from="${build.effects.dir.resolved}" to=""/>
|
||||||
|
<map from="${build.networking.dir.resolved}" to=""/>
|
||||||
<map from="${build.plugins.dir.resolved}" to=""/>
|
<map from="${build.plugins.dir.resolved}" to=""/>
|
||||||
<map from="${build.jogg.dir.resolved}" to=""/>
|
<map from="${build.jogg.dir.resolved}" to=""/>
|
||||||
<map from="${build.desktop.dir.resolved}" to=""/>
|
<map from="${build.desktop.dir.resolved}" to=""/>
|
||||||
@ -214,6 +242,8 @@
|
|||||||
<map from="${android.jar.resolved}" to=""/>
|
<map from="${android.jar.resolved}" to=""/>
|
||||||
|
|
||||||
<path path="${build.dir}/jME3-core.jar"/>
|
<path path="${build.dir}/jME3-core.jar"/>
|
||||||
|
<path path="${build.dir}/jME3-effects.jar"/>
|
||||||
|
<path path="${build.dir}/jME3-networking.jar"/>
|
||||||
<path path="${build.dir}/jME3-plugins.jar"/>
|
<path path="${build.dir}/jME3-plugins.jar"/>
|
||||||
<path path="${build.dir}/jME3-jogg.jar"/>
|
<path path="${build.dir}/jME3-jogg.jar"/>
|
||||||
<path path="${build.dir}/jME3-desktop.jar"/>
|
<path path="${build.dir}/jME3-desktop.jar"/>
|
||||||
@ -328,6 +358,7 @@
|
|||||||
<zip destfile="${dist.dir}/jMonkeyEngine3-sources.zip">
|
<zip destfile="${dist.dir}/jMonkeyEngine3-sources.zip">
|
||||||
<zipfileset dir="${src.core.dir}"/>
|
<zipfileset dir="${src.core.dir}"/>
|
||||||
<zipfileset dir="${src.core-data.dir}"/>
|
<zipfileset dir="${src.core-data.dir}"/>
|
||||||
|
<zipfileset dir="${src.core-effects.dir}"/>
|
||||||
<zipfileset dir="${src.core-plugins.dir}"/>
|
<zipfileset dir="${src.core-plugins.dir}"/>
|
||||||
<zipfileset dir="${src.desktop.dir}"/>
|
<zipfileset dir="${src.desktop.dir}"/>
|
||||||
<zipfileset dir="${src.jbullet.dir}"/>
|
<zipfileset dir="${src.jbullet.dir}"/>
|
||||||
@ -385,6 +416,7 @@
|
|||||||
<zipfileset dir="${dist.dir}/javadoc" prefix="javadoc"/>
|
<zipfileset dir="${dist.dir}/javadoc" prefix="javadoc"/>
|
||||||
<zipfileset dir="${src.core.dir}" prefix="source"/>
|
<zipfileset dir="${src.core.dir}" prefix="source"/>
|
||||||
<zipfileset dir="${src.core-data.dir}" prefix="source"/>
|
<zipfileset dir="${src.core-data.dir}" prefix="source"/>
|
||||||
|
<zipfileset dir="${src.core-effects.dir}" prefix="source"/>
|
||||||
<zipfileset dir="${src.core-plugins.dir}" prefix="source"/>
|
<zipfileset dir="${src.core-plugins.dir}" prefix="source"/>
|
||||||
<zipfileset dir="${src.desktop.dir}" prefix="source"/>
|
<zipfileset dir="${src.desktop.dir}" prefix="source"/>
|
||||||
<zipfileset dir="${src.jbullet.dir}" prefix="source"/>
|
<zipfileset dir="${src.jbullet.dir}" prefix="source"/>
|
||||||
|
@ -168,6 +168,7 @@ is divided into following sections:
|
|||||||
<or>
|
<or>
|
||||||
<available file="${src.core.dir}"/>
|
<available file="${src.core.dir}"/>
|
||||||
<available file="${src.core-data.dir}"/>
|
<available file="${src.core-data.dir}"/>
|
||||||
|
<available file="${src.core-effects.dir}"/>
|
||||||
<available file="${src.core-plugins.dir}"/>
|
<available file="${src.core-plugins.dir}"/>
|
||||||
<available file="${src.desktop.dir}"/>
|
<available file="${src.desktop.dir}"/>
|
||||||
<available file="${src.terrain.dir}"/>
|
<available file="${src.terrain.dir}"/>
|
||||||
@ -251,6 +252,7 @@ is divided into following sections:
|
|||||||
<target depends="-pre-init,-init-private,-init-libraries,-init-user,-init-project,-do-init" name="-init-check">
|
<target depends="-pre-init,-init-private,-init-libraries,-init-user,-init-project,-do-init" name="-init-check">
|
||||||
<fail unless="src.core.dir">Must set src.core.dir</fail>
|
<fail unless="src.core.dir">Must set src.core.dir</fail>
|
||||||
<fail unless="src.core-data.dir">Must set src.core-data.dir</fail>
|
<fail unless="src.core-data.dir">Must set src.core-data.dir</fail>
|
||||||
|
<fail unless="src.core-effects.dir">Must set src.core-effects.dir</fail>
|
||||||
<fail unless="src.core-plugins.dir">Must set src.core-plugins.dir</fail>
|
<fail unless="src.core-plugins.dir">Must set src.core-plugins.dir</fail>
|
||||||
<fail unless="src.desktop.dir">Must set src.desktop.dir</fail>
|
<fail unless="src.desktop.dir">Must set src.desktop.dir</fail>
|
||||||
<fail unless="src.terrain.dir">Must set src.terrain.dir</fail>
|
<fail unless="src.terrain.dir">Must set src.terrain.dir</fail>
|
||||||
@ -289,7 +291,7 @@ is divided into following sections:
|
|||||||
</target>
|
</target>
|
||||||
<target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">
|
<target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">
|
||||||
<macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
|
<macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||||
<attribute default="${src.core.dir}:${src.core-data.dir}:${src.core-plugins.dir}:${src.desktop.dir}:${src.terrain.dir}:${src.jbullet.dir}:${src.bullet.dir}:${src.bullet-native.dir}:${src.bullet-common.dir}:${src.networking.dir}:${src.niftygui.dir}:${src.jogg.dir}:${src.ogre.dir}:${src.blender.dir}:${src.xml.dir}:${src.tools.dir}:${src.test.dir}:${src.lwjgl.dir}:${src.android.dir}" name="srcdir"/>
|
<attribute default="${src.core.dir}:${src.core-data.dir}:${src.core-effects.dir}:${src.core-plugins.dir}:${src.desktop.dir}:${src.terrain.dir}:${src.jbullet.dir}:${src.bullet.dir}:${src.bullet-native.dir}:${src.bullet-common.dir}:${src.networking.dir}:${src.niftygui.dir}:${src.jogg.dir}:${src.ogre.dir}:${src.blender.dir}:${src.xml.dir}:${src.tools.dir}:${src.test.dir}:${src.lwjgl.dir}:${src.android.dir}" name="srcdir"/>
|
||||||
<attribute default="${build.classes.dir}" name="destdir"/>
|
<attribute default="${build.classes.dir}" name="destdir"/>
|
||||||
<attribute default="${javac.classpath}" name="classpath"/>
|
<attribute default="${javac.classpath}" name="classpath"/>
|
||||||
<attribute default="${javac.processorpath}" name="processorpath"/>
|
<attribute default="${javac.processorpath}" name="processorpath"/>
|
||||||
@ -329,7 +331,7 @@ is divided into following sections:
|
|||||||
</target>
|
</target>
|
||||||
<target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
|
<target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
|
||||||
<macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
|
<macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||||
<attribute default="${src.core.dir}:${src.core-data.dir}:${src.core-plugins.dir}:${src.desktop.dir}:${src.terrain.dir}:${src.jbullet.dir}:${src.bullet.dir}:${src.bullet-native.dir}:${src.bullet-common.dir}:${src.networking.dir}:${src.niftygui.dir}:${src.jogg.dir}:${src.ogre.dir}:${src.blender.dir}:${src.xml.dir}:${src.tools.dir}:${src.test.dir}:${src.lwjgl.dir}:${src.android.dir}" name="srcdir"/>
|
<attribute default="${src.core.dir}:${src.core-data.dir}:${src.core-effects.dir}:${src.core-plugins.dir}:${src.desktop.dir}:${src.terrain.dir}:${src.jbullet.dir}:${src.bullet.dir}:${src.bullet-native.dir}:${src.bullet-common.dir}:${src.networking.dir}:${src.niftygui.dir}:${src.jogg.dir}:${src.ogre.dir}:${src.blender.dir}:${src.xml.dir}:${src.tools.dir}:${src.test.dir}:${src.lwjgl.dir}:${src.android.dir}" name="srcdir"/>
|
||||||
<attribute default="${build.classes.dir}" name="destdir"/>
|
<attribute default="${build.classes.dir}" name="destdir"/>
|
||||||
<attribute default="${javac.classpath}" name="classpath"/>
|
<attribute default="${javac.classpath}" name="classpath"/>
|
||||||
<attribute default="${javac.processorpath}" name="processorpath"/>
|
<attribute default="${javac.processorpath}" name="processorpath"/>
|
||||||
@ -361,7 +363,7 @@ is divided into following sections:
|
|||||||
</target>
|
</target>
|
||||||
<target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
|
<target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
|
||||||
<macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
|
<macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||||
<attribute default="${src.core.dir}:${src.core-data.dir}:${src.core-plugins.dir}:${src.desktop.dir}:${src.terrain.dir}:${src.jbullet.dir}:${src.bullet.dir}:${src.bullet-native.dir}:${src.bullet-common.dir}:${src.networking.dir}:${src.niftygui.dir}:${src.jogg.dir}:${src.ogre.dir}:${src.blender.dir}:${src.xml.dir}:${src.tools.dir}:${src.test.dir}:${src.lwjgl.dir}:${src.android.dir}" name="srcdir"/>
|
<attribute default="${src.core.dir}:${src.core-data.dir}:${src.core-effects.dir}:${src.core-plugins.dir}:${src.desktop.dir}:${src.terrain.dir}:${src.jbullet.dir}:${src.bullet.dir}:${src.bullet-native.dir}:${src.bullet-common.dir}:${src.networking.dir}:${src.niftygui.dir}:${src.jogg.dir}:${src.ogre.dir}:${src.blender.dir}:${src.xml.dir}:${src.tools.dir}:${src.test.dir}:${src.lwjgl.dir}:${src.android.dir}" name="srcdir"/>
|
||||||
<attribute default="${build.classes.dir}" name="destdir"/>
|
<attribute default="${build.classes.dir}" name="destdir"/>
|
||||||
<attribute default="${javac.classpath}" name="classpath"/>
|
<attribute default="${javac.classpath}" name="classpath"/>
|
||||||
<sequential>
|
<sequential>
|
||||||
@ -659,13 +661,14 @@ is divided into following sections:
|
|||||||
<include name="*"/>
|
<include name="*"/>
|
||||||
</dirset>
|
</dirset>
|
||||||
</pathconvert>
|
</pathconvert>
|
||||||
<j2seproject3:depend srcdir="${src.core.dir}:${src.core-data.dir}:${src.core-plugins.dir}:${src.desktop.dir}:${src.terrain.dir}:${src.jbullet.dir}:${src.bullet.dir}:${src.bullet-native.dir}:${src.bullet-common.dir}:${src.networking.dir}:${src.niftygui.dir}:${src.jogg.dir}:${src.ogre.dir}:${src.blender.dir}:${src.xml.dir}:${src.tools.dir}:${src.test.dir}:${src.lwjgl.dir}:${src.android.dir}:${build.generated.subdirs}"/>
|
<j2seproject3:depend srcdir="${src.core.dir}:${src.core-data.dir}:${src.core-effects.dir}:${src.core-plugins.dir}:${src.desktop.dir}:${src.terrain.dir}:${src.jbullet.dir}:${src.bullet.dir}:${src.bullet-native.dir}:${src.bullet-common.dir}:${src.networking.dir}:${src.niftygui.dir}:${src.jogg.dir}:${src.ogre.dir}:${src.blender.dir}:${src.xml.dir}:${src.tools.dir}:${src.test.dir}:${src.lwjgl.dir}:${src.android.dir}:${build.generated.subdirs}"/>
|
||||||
</target>
|
</target>
|
||||||
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile">
|
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile">
|
||||||
<j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
|
<j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
|
||||||
<copy todir="${build.classes.dir}">
|
<copy todir="${build.classes.dir}">
|
||||||
<fileset dir="${src.core.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
<fileset dir="${src.core.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
||||||
<fileset dir="${src.core-data.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
<fileset dir="${src.core-data.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
||||||
|
<fileset dir="${src.core-effects.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
||||||
<fileset dir="${src.core-plugins.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
<fileset dir="${src.core-plugins.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
||||||
<fileset dir="${src.desktop.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
<fileset dir="${src.desktop.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
||||||
<fileset dir="${src.terrain.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
<fileset dir="${src.terrain.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
||||||
@ -703,7 +706,7 @@ is divided into following sections:
|
|||||||
<target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
|
<target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
|
||||||
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
|
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
|
||||||
<j2seproject3:force-recompile/>
|
<j2seproject3:force-recompile/>
|
||||||
<j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.core.dir}:${src.core-data.dir}:${src.core-plugins.dir}:${src.desktop.dir}:${src.terrain.dir}:${src.jbullet.dir}:${src.bullet.dir}:${src.bullet-native.dir}:${src.bullet-common.dir}:${src.networking.dir}:${src.niftygui.dir}:${src.jogg.dir}:${src.ogre.dir}:${src.blender.dir}:${src.xml.dir}:${src.tools.dir}:${src.test.dir}:${src.lwjgl.dir}:${src.android.dir}"/>
|
<j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.core.dir}:${src.core-data.dir}:${src.core-effects.dir}:${src.core-plugins.dir}:${src.desktop.dir}:${src.terrain.dir}:${src.jbullet.dir}:${src.bullet.dir}:${src.bullet-native.dir}:${src.bullet-common.dir}:${src.networking.dir}:${src.niftygui.dir}:${src.jogg.dir}:${src.ogre.dir}:${src.blender.dir}:${src.xml.dir}:${src.tools.dir}:${src.test.dir}:${src.lwjgl.dir}:${src.android.dir}"/>
|
||||||
</target>
|
</target>
|
||||||
<target name="-post-compile-single">
|
<target name="-post-compile-single">
|
||||||
<!-- Empty placeholder for easier customization. -->
|
<!-- Empty placeholder for easier customization. -->
|
||||||
@ -929,6 +932,9 @@ is divided into following sections:
|
|||||||
<fileset dir="${src.core-data.dir}" excludes="*.java,${excludes}" includes="${includes}">
|
<fileset dir="${src.core-data.dir}" excludes="*.java,${excludes}" includes="${includes}">
|
||||||
<filename name="**/*.java"/>
|
<filename name="**/*.java"/>
|
||||||
</fileset>
|
</fileset>
|
||||||
|
<fileset dir="${src.core-effects.dir}" excludes="*.java,${excludes}" includes="${includes}">
|
||||||
|
<filename name="**/*.java"/>
|
||||||
|
</fileset>
|
||||||
<fileset dir="${src.core-plugins.dir}" excludes="*.java,${excludes}" includes="${includes}">
|
<fileset dir="${src.core-plugins.dir}" excludes="*.java,${excludes}" includes="${includes}">
|
||||||
<filename name="**/*.java"/>
|
<filename name="**/*.java"/>
|
||||||
</fileset>
|
</fileset>
|
||||||
@ -992,6 +998,9 @@ is divided into following sections:
|
|||||||
<fileset dir="${src.core-data.dir}" excludes="${excludes}" includes="${includes}">
|
<fileset dir="${src.core-data.dir}" excludes="${excludes}" includes="${includes}">
|
||||||
<filename name="**/doc-files/**"/>
|
<filename name="**/doc-files/**"/>
|
||||||
</fileset>
|
</fileset>
|
||||||
|
<fileset dir="${src.core-effects.dir}" excludes="${excludes}" includes="${includes}">
|
||||||
|
<filename name="**/doc-files/**"/>
|
||||||
|
</fileset>
|
||||||
<fileset dir="${src.core-plugins.dir}" excludes="${excludes}" includes="${includes}">
|
<fileset dir="${src.core-plugins.dir}" excludes="${excludes}" includes="${includes}">
|
||||||
<filename name="**/doc-files/**"/>
|
<filename name="**/doc-files/**"/>
|
||||||
</fileset>
|
</fileset>
|
||||||
|
@ -3,8 +3,8 @@ build.xml.script.CRC32=34d4c2f2
|
|||||||
build.xml.stylesheet.CRC32=958a1d3e
|
build.xml.stylesheet.CRC32=958a1d3e
|
||||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||||
nbproject/build-impl.xml.data.CRC32=5d760efd
|
nbproject/build-impl.xml.data.CRC32=ba8f4e88
|
||||||
nbproject/build-impl.xml.script.CRC32=a73ff29f
|
nbproject/build-impl.xml.script.CRC32=9dc03a5e
|
||||||
nbproject/build-impl.xml.stylesheet.CRC32=0ae3a408@1.44.1.45
|
nbproject/build-impl.xml.stylesheet.CRC32=0ae3a408@1.44.1.45
|
||||||
nbproject/profiler-build-impl.xml.data.CRC32=aff514c1
|
nbproject/profiler-build-impl.xml.data.CRC32=aff514c1
|
||||||
nbproject/profiler-build-impl.xml.script.CRC32=abda56ed
|
nbproject/profiler-build-impl.xml.script.CRC32=abda56ed
|
||||||
|
@ -1,123 +1,126 @@
|
|||||||
annotation.processing.enabled=false
|
annotation.processing.enabled=false
|
||||||
annotation.processing.enabled.in.editor=false
|
annotation.processing.enabled.in.editor=false
|
||||||
annotation.processing.run.all.processors=true
|
annotation.processing.run.all.processors=true
|
||||||
ant.customtasks.libs=JWSAntTasks
|
ant.customtasks.libs=JWSAntTasks
|
||||||
application.homepage=http://www.jmonkeyengine.com/
|
application.homepage=http://www.jmonkeyengine.com/
|
||||||
application.title=jMonkeyEngine 3.0
|
application.title=jMonkeyEngine 3.0
|
||||||
application.vendor=jMonkeyEngine
|
application.vendor=jMonkeyEngine
|
||||||
build.classes.dir=${build.dir}/classes
|
build.classes.dir=${build.dir}/classes
|
||||||
build.classes.excludes=**/*.java,**/*.form
|
build.classes.excludes=**/*.java,**/*.form
|
||||||
# This directory is removed when the project is cleaned:
|
# This directory is removed when the project is cleaned:
|
||||||
build.dir=build
|
build.dir=build
|
||||||
build.generated.dir=${build.dir}/generated
|
build.generated.dir=${build.dir}/generated
|
||||||
build.generated.sources.dir=${build.dir}/generated-sources
|
build.generated.sources.dir=${build.dir}/generated-sources
|
||||||
# Only compile against the classpath explicitly listed here:
|
# Only compile against the classpath explicitly listed here:
|
||||||
build.sysclasspath=ignore
|
build.sysclasspath=ignore
|
||||||
build.test.classes.dir=${build.dir}/test/classes
|
build.test.classes.dir=${build.dir}/test/classes
|
||||||
build.test.results.dir=${build.dir}/test/results
|
build.test.results.dir=${build.dir}/test/results
|
||||||
# Uncomment to specify the preferred debugger connection transport:
|
# Uncomment to specify the preferred debugger connection transport:
|
||||||
#debug.transport=dt_socket
|
#debug.transport=dt_socket
|
||||||
debug.classpath=\
|
debug.classpath=\
|
||||||
${run.classpath}
|
${run.classpath}
|
||||||
debug.test.classpath=\
|
debug.test.classpath=\
|
||||||
${run.test.classpath}
|
${run.test.classpath}
|
||||||
# This directory is removed when the project is cleaned:
|
# This directory is removed when the project is cleaned:
|
||||||
dist.dir=dist
|
dist.dir=dist
|
||||||
dist.jar=${dist.dir}/jMonkeyEngine3.jar
|
dist.jar=${dist.dir}/jMonkeyEngine3.jar
|
||||||
dist.javadoc.dir=${dist.dir}/javadoc
|
dist.javadoc.dir=${dist.dir}/javadoc
|
||||||
endorsed.classpath=
|
endorsed.classpath=
|
||||||
excludes=
|
excludes=
|
||||||
file.reference.src-test-data=src/test-data
|
file.reference.src-test-data=src/test-data
|
||||||
includes=**
|
includes=**
|
||||||
jar.archive.disabled=${jnlp.enabled}
|
jar.archive.disabled=${jnlp.enabled}
|
||||||
jar.compress=true
|
jar.compress=true
|
||||||
jar.index=${jnlp.enabled}
|
jar.index=${jnlp.enabled}
|
||||||
javac.classpath=\
|
javac.classpath=\
|
||||||
${libs.jogg.classpath}:\
|
${libs.jogg.classpath}:\
|
||||||
${libs.jbullet.classpath}:\
|
${libs.jbullet.classpath}:\
|
||||||
${libs.lwjgl.classpath}:\
|
${libs.lwjgl.classpath}:\
|
||||||
${libs.niftygui1.3.classpath}:\
|
${libs.niftygui1.3.classpath}:\
|
||||||
${libs.jme3-test-data.classpath}:\
|
${libs.jme3-test-data.classpath}:\
|
||||||
${libs.android.classpath}:\
|
${libs.android.classpath}:\
|
||||||
${libs.bullet.classpath}
|
${libs.bullet.classpath}
|
||||||
# Space-separated list of extra javac options
|
# Space-separated list of extra javac options
|
||||||
javac.compilerargs=
|
javac.compilerargs=
|
||||||
javac.deprecation=false
|
javac.deprecation=false
|
||||||
javac.processorpath=\
|
javac.processorpath=\
|
||||||
${javac.classpath}
|
${javac.classpath}
|
||||||
javac.source=1.5
|
javac.source=1.5
|
||||||
javac.target=1.5
|
javac.target=1.5
|
||||||
javac.test.classpath=\
|
javac.test.classpath=\
|
||||||
${javac.classpath}:\
|
${javac.classpath}:\
|
||||||
${build.classes.dir}:\
|
${build.classes.dir}:\
|
||||||
${libs.junit_4.classpath}
|
${libs.junit_4.classpath}
|
||||||
javadoc.additionalparam=-public
|
javadoc.additionalparam=-public
|
||||||
javadoc.author=false
|
javadoc.author=false
|
||||||
javadoc.encoding=${source.encoding}
|
javadoc.encoding=${source.encoding}
|
||||||
javadoc.noindex=false
|
javadoc.noindex=false
|
||||||
javadoc.nonavbar=false
|
javadoc.nonavbar=false
|
||||||
javadoc.notree=false
|
javadoc.notree=false
|
||||||
javadoc.private=false
|
javadoc.private=false
|
||||||
javadoc.splitindex=true
|
javadoc.splitindex=true
|
||||||
javadoc.use=true
|
javadoc.use=true
|
||||||
javadoc.version=false
|
javadoc.version=false
|
||||||
javadoc.windowtitle=jMonkeyEngine3
|
javadoc.windowtitle=jMonkeyEngine3
|
||||||
jaxbwiz.endorsed.dirs="${netbeans.home}/../ide12/modules/ext/jaxb/api"
|
jaxbwiz.endorsed.dirs="${netbeans.home}/../ide12/modules/ext/jaxb/api"
|
||||||
jnlp.applet.class=jme3test.awt.AppHarness
|
jnlp.applet.class=jme3test.awt.AppHarness
|
||||||
jnlp.applet.height=300
|
jnlp.applet.height=300
|
||||||
jnlp.applet.width=300
|
jnlp.applet.width=300
|
||||||
jnlp.codebase.type=user
|
jnlp.codebase.type=user
|
||||||
jnlp.codebase.user=http://jmonkeyengine.com/javawebstart/
|
jnlp.codebase.user=http://jmonkeyengine.com/javawebstart/
|
||||||
jnlp.descriptor=application
|
jnlp.descriptor=application
|
||||||
jnlp.enabled=false
|
jnlp.enabled=false
|
||||||
jnlp.icon=/Users/normenhansen/Pictures/jme/icons/jme-logo48.png
|
jnlp.icon=/Users/normenhansen/Pictures/jme/icons/jme-logo48.png
|
||||||
jnlp.mixed.code=default
|
jnlp.mixed.code=default
|
||||||
jnlp.offline-allowed=true
|
jnlp.offline-allowed=true
|
||||||
jnlp.signed=true
|
jnlp.signed=true
|
||||||
jnlp.signing=generated
|
jnlp.signing=generated
|
||||||
jnlp.signing.alias=
|
jnlp.signing.alias=
|
||||||
jnlp.signing.keystore=
|
jnlp.signing.keystore=
|
||||||
main.class=jme3test.TestChooser
|
main.class=jme3test.TestChooser
|
||||||
manifest.file=MANIFEST.MF
|
manifest.file=MANIFEST.MF
|
||||||
meta.inf.dir=${src.dir}/META-INF
|
meta.inf.dir=${src.dir}/META-INF
|
||||||
mkdist.disabled=false
|
mkdist.disabled=false
|
||||||
platform.active=default_platform
|
platform.active=default_platform
|
||||||
run.classpath=\
|
run.classpath=\
|
||||||
${javac.classpath}:\
|
${javac.classpath}:\
|
||||||
${build.classes.dir}:\
|
${build.classes.dir}:\
|
||||||
${build.dir}/core:\
|
${build.dir}/core:\
|
||||||
${build.dir}/plugins:\
|
${build.dir}/effects:\
|
||||||
${build.dir}/jogg:\
|
${build.dir}/networking:\
|
||||||
${build.dir}/desktop:\
|
${build.dir}/plugins:\
|
||||||
${build.dir}/blender:\
|
${build.dir}/jogg:\
|
||||||
${build.dir}/terrain:\
|
${build.dir}/desktop:\
|
||||||
${build.dir}/jbullet:\
|
${build.dir}/blender:\
|
||||||
${build.dir}/bullet:\
|
${build.dir}/terrain:\
|
||||||
${build.dir}/niftygui:\
|
${build.dir}/jbullet:\
|
||||||
${build.dir}/lwjgl:\
|
${build.dir}/bullet:\
|
||||||
${build.dir}/android
|
${build.dir}/niftygui:\
|
||||||
run.jvmargs=-Xms128m -Xmx128m -XX:MaxDirectMemorySize=256M
|
${build.dir}/lwjgl:\
|
||||||
run.test.classpath=\
|
${build.dir}/android
|
||||||
${javac.test.classpath}:\
|
run.jvmargs=-Xms128m -Xmx128m -XX:MaxDirectMemorySize=256M
|
||||||
${build.test.classes.dir}
|
run.test.classpath=\
|
||||||
source.encoding=UTF-8
|
${javac.test.classpath}:\
|
||||||
src.android.dir=src/android
|
${build.test.classes.dir}
|
||||||
src.blender.dir=src/blender
|
source.encoding=UTF-8
|
||||||
src.bullet-common.dir=src/bullet-common
|
src.android.dir=src/android
|
||||||
src.bullet-native.dir=src/bullet-native
|
src.blender.dir=src/blender
|
||||||
src.bullet.dir=src/bullet
|
src.bullet-common.dir=src/bullet-common
|
||||||
src.core-data.dir=src/core-data
|
src.bullet-native.dir=src/bullet-native
|
||||||
src.core-plugins.dir=src/core-plugins
|
src.bullet.dir=src/bullet
|
||||||
src.core.dir=src/core
|
src.core-data.dir=src/core-data
|
||||||
src.desktop.dir=src/desktop
|
src.core-effects.dir=src/core-effects
|
||||||
src.jbullet.dir=src/jbullet
|
src.core-plugins.dir=src/core-plugins
|
||||||
src.jogg.dir=src/jogg
|
src.core.dir=src/core
|
||||||
src.lwjgl.dir=src/lwjgl
|
src.desktop.dir=src/desktop
|
||||||
src.networking.dir=src\\networking
|
src.jbullet.dir=src/jbullet
|
||||||
src.niftygui.dir=src/niftygui
|
src.jogg.dir=src/jogg
|
||||||
src.ogre.dir=src/ogre
|
src.lwjgl.dir=src/lwjgl
|
||||||
src.terrain.dir=src/terrain
|
src.networking.dir=src/networking
|
||||||
src.test.dir=src/test
|
src.niftygui.dir=src/niftygui
|
||||||
src.tools.dir=src/tools
|
src.ogre.dir=src/ogre
|
||||||
src.xml.dir=src/xml
|
src.terrain.dir=src/terrain
|
||||||
test.test.dir=test
|
src.test.dir=src/test
|
||||||
|
src.tools.dir=src/tools
|
||||||
|
src.xml.dir=src/xml
|
||||||
|
test.test.dir=test
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
<source-roots>
|
<source-roots>
|
||||||
<root id="src.core.dir" name="Core"/>
|
<root id="src.core.dir" name="Core"/>
|
||||||
<root id="src.core-data.dir" name="Core-Data"/>
|
<root id="src.core-data.dir" name="Core-Data"/>
|
||||||
|
<root id="src.core-effects.dir" name="Core-Effects"/>
|
||||||
<root id="src.core-plugins.dir" name="Core-Plugins"/>
|
<root id="src.core-plugins.dir" name="Core-Plugins"/>
|
||||||
<root id="src.desktop.dir" name="Desktop"/>
|
<root id="src.desktop.dir" name="Desktop"/>
|
||||||
<root id="src.terrain.dir" name="Terrain"/>
|
<root id="src.terrain.dir" name="Terrain"/>
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
MaterialDef Bloom {
|
||||||
|
|
||||||
|
MaterialParameters {
|
||||||
|
Int NumSamples
|
||||||
|
Texture2D Texture
|
||||||
|
Float ExposurePow
|
||||||
|
Float ExposureCutoff
|
||||||
|
Boolean Extract
|
||||||
|
Texture2D GlowMap
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL150: Common/MatDefs/Post/Post15.vert
|
||||||
|
FragmentShader GLSL150: Common/MatDefs/Post/bloomExtract15.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
HAS_GLOWMAP : GlowMap
|
||||||
|
DO_EXTRACT : Extract
|
||||||
|
RESOLVE_MS : NumSamples
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL100: Common/MatDefs/Post/Post.vert
|
||||||
|
FragmentShader GLSL100: Common/MatDefs/Post/bloomExtract.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
HAS_GLOWMAP : GlowMap
|
||||||
|
DO_EXTRACT : Extract
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique FixedFunc {
|
||||||
|
}
|
||||||
|
}
|
36
engine/src/core-effects/Common/MatDefs/Post/BloomFinal.j3md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
MaterialDef Bloom Final {
|
||||||
|
|
||||||
|
MaterialParameters {
|
||||||
|
Int NumSamples
|
||||||
|
Texture2D Texture
|
||||||
|
Texture2D BloomTex
|
||||||
|
Float BloomIntensity
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL100: Common/MatDefs/Post/Post15.vert
|
||||||
|
FragmentShader GLSL150: Common/MatDefs/Post/bloomFinal15.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
RESOLVE_MS : NumSamples
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL100: Common/MatDefs/Post/Post.vert
|
||||||
|
FragmentShader GLSL100: Common/MatDefs/Post/bloomFinal.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Technique FixedFunc {
|
||||||
|
}
|
||||||
|
}
|
55
engine/src/core-effects/Common/MatDefs/Post/CartoonEdge.frag
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
uniform vec4 m_EdgeColor;
|
||||||
|
|
||||||
|
uniform float m_EdgeWidth;
|
||||||
|
uniform float m_EdgeIntensity;
|
||||||
|
|
||||||
|
uniform float m_NormalThreshold;
|
||||||
|
uniform float m_DepthThreshold;
|
||||||
|
|
||||||
|
uniform float m_NormalSensitivity;
|
||||||
|
uniform float m_DepthSensitivity;
|
||||||
|
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
uniform sampler2D m_Texture;
|
||||||
|
uniform sampler2D m_NormalsTexture;
|
||||||
|
uniform sampler2D m_DepthTexture;
|
||||||
|
|
||||||
|
uniform vec2 g_Resolution;
|
||||||
|
|
||||||
|
vec4 fetchNormalDepth(vec2 tc){
|
||||||
|
vec4 nd;
|
||||||
|
nd.xyz = texture2D(m_NormalsTexture, tc).rgb;
|
||||||
|
nd.w = texture2D(m_DepthTexture, tc).r;
|
||||||
|
return nd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec3 color = texture2D(m_Texture, texCoord).rgb;
|
||||||
|
|
||||||
|
vec2 edgeOffset = vec2(m_EdgeWidth) / g_Resolution;
|
||||||
|
|
||||||
|
vec4 n1 = fetchNormalDepth(texCoord + vec2(-1.0, -1.0) * edgeOffset);
|
||||||
|
vec4 n2 = fetchNormalDepth(texCoord + vec2( 1.0, 1.0) * edgeOffset);
|
||||||
|
vec4 n3 = fetchNormalDepth(texCoord + vec2(-1.0, 1.0) * edgeOffset);
|
||||||
|
vec4 n4 = fetchNormalDepth(texCoord + vec2( 1.0, -1.0) * edgeOffset);
|
||||||
|
|
||||||
|
// Work out how much the normal and depth values are changing.
|
||||||
|
vec4 diagonalDelta = abs(n1 - n2) + abs(n3 - n4);
|
||||||
|
|
||||||
|
float normalDelta = dot(diagonalDelta.xyz, vec3(1.0));
|
||||||
|
float depthDelta = diagonalDelta.w;
|
||||||
|
|
||||||
|
// Filter out very small changes, in order to produce nice clean results.
|
||||||
|
normalDelta = clamp((normalDelta - m_NormalThreshold) * m_NormalSensitivity, 0.0, 1.0);
|
||||||
|
depthDelta = clamp((depthDelta - m_DepthThreshold) * m_DepthSensitivity, 0.0, 1.0);
|
||||||
|
|
||||||
|
// Does this pixel lie on an edge?
|
||||||
|
float edgeAmount = clamp(normalDelta + depthDelta, 0.0, 1.0) * m_EdgeIntensity;
|
||||||
|
|
||||||
|
// Apply the edge detection result to the main scene color.
|
||||||
|
//color *= (1.0 - edgeAmount);
|
||||||
|
color = mix (color,m_EdgeColor.rgb,edgeAmount);
|
||||||
|
|
||||||
|
gl_FragColor = vec4(color, 1.0);
|
||||||
|
}
|
48
engine/src/core-effects/Common/MatDefs/Post/CartoonEdge.j3md
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
MaterialDef Cartoon Edge {
|
||||||
|
|
||||||
|
MaterialParameters {
|
||||||
|
Int NumSamples
|
||||||
|
Int NumSamplesDepth
|
||||||
|
Texture2D Texture
|
||||||
|
Texture2D NormalsTexture
|
||||||
|
Texture2D DepthTexture
|
||||||
|
Color EdgeColor
|
||||||
|
Float EdgeWidth
|
||||||
|
Float EdgeIntensity
|
||||||
|
Float NormalThreshold
|
||||||
|
Float DepthThreshold
|
||||||
|
Float NormalSensitivity
|
||||||
|
Float DepthSensitivity
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL150: Common/MatDefs/Post/Post15.vert
|
||||||
|
FragmentShader GLSL150: Common/MatDefs/Post/CartoonEdge15.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
WorldViewMatrix
|
||||||
|
Resolution
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
RESOLVE_MS : NumSamples
|
||||||
|
RESOLVE_DEPTH_MS : NumSamplesDepth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL100: Common/MatDefs/Post/Post.vert
|
||||||
|
FragmentShader GLSL100: Common/MatDefs/Post/CartoonEdge.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
WorldViewMatrix
|
||||||
|
Resolution
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique FixedFunc {
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
#import "Common/ShaderLib/MultiSample.glsllib"
|
||||||
|
|
||||||
|
uniform COLORTEXTURE m_Texture;
|
||||||
|
uniform DEPTHTEXTURE m_DepthTexture;
|
||||||
|
|
||||||
|
uniform sampler2D m_NormalsTexture;
|
||||||
|
uniform vec2 g_Resolution;
|
||||||
|
|
||||||
|
uniform vec4 m_EdgeColor;
|
||||||
|
|
||||||
|
uniform float m_EdgeWidth;
|
||||||
|
uniform float m_EdgeIntensity;
|
||||||
|
|
||||||
|
uniform float m_NormalThreshold;
|
||||||
|
uniform float m_DepthThreshold;
|
||||||
|
|
||||||
|
uniform float m_NormalSensitivity;
|
||||||
|
uniform float m_DepthSensitivity;
|
||||||
|
|
||||||
|
in vec2 texCoord;
|
||||||
|
out vec4 outFragColor;
|
||||||
|
|
||||||
|
vec4 fetchNormalDepth(vec2 tc){
|
||||||
|
vec4 nd;
|
||||||
|
nd.xyz = texture2D(m_NormalsTexture, tc).rgb;
|
||||||
|
nd.w = fetchTextureSample(m_DepthTexture, tc,0).r;
|
||||||
|
return nd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec3 color = getColor(m_Texture, texCoord).rgb;
|
||||||
|
|
||||||
|
vec2 edgeOffset = vec2(m_EdgeWidth) / textureSize(m_NormalsTexture, 0);
|
||||||
|
vec4 n1 = fetchNormalDepth(texCoord + vec2(-1.0, -1.0) * edgeOffset);
|
||||||
|
vec4 n2 = fetchNormalDepth(texCoord + vec2( 1.0, 1.0) * edgeOffset);
|
||||||
|
vec4 n3 = fetchNormalDepth(texCoord + vec2(-1.0, 1.0) * edgeOffset);
|
||||||
|
vec4 n4 = fetchNormalDepth(texCoord + vec2( 1.0, -1.0) * edgeOffset);
|
||||||
|
|
||||||
|
// Work out how much the normal and depth values are changing.
|
||||||
|
vec4 diagonalDelta = abs(n1 - n2) + abs(n3 - n4);
|
||||||
|
|
||||||
|
float normalDelta = dot(diagonalDelta.xyz, vec3(1.0));
|
||||||
|
float depthDelta = diagonalDelta.w;
|
||||||
|
|
||||||
|
// Filter out very small changes, in order to produce nice clean results.
|
||||||
|
normalDelta = clamp((normalDelta - m_NormalThreshold) * m_NormalSensitivity, 0.0, 1.0);
|
||||||
|
depthDelta = clamp((depthDelta - m_DepthThreshold) * m_DepthSensitivity, 0.0, 1.0);
|
||||||
|
|
||||||
|
// Does this pixel lie on an edge?
|
||||||
|
float edgeAmount = clamp(normalDelta + depthDelta, 0.0, 1.0) * m_EdgeIntensity;
|
||||||
|
|
||||||
|
// Apply the edge detection result to the main scene color.
|
||||||
|
//color *= (1.0 - edgeAmount);
|
||||||
|
color = mix (color,m_EdgeColor.rgb,edgeAmount);
|
||||||
|
|
||||||
|
outFragColor = vec4(color, 1.0);
|
||||||
|
}
|
51
engine/src/core-effects/Common/MatDefs/Post/CrossHatch.frag
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
uniform sampler2D m_Texture;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
uniform vec4 m_LineColor;
|
||||||
|
uniform vec4 m_PaperColor;
|
||||||
|
uniform float m_ColorInfluenceLine;
|
||||||
|
uniform float m_ColorInfluencePaper;
|
||||||
|
|
||||||
|
uniform float m_FillValue;
|
||||||
|
uniform float m_Luminance1;
|
||||||
|
uniform float m_Luminance2;
|
||||||
|
uniform float m_Luminance3;
|
||||||
|
uniform float m_Luminance4;
|
||||||
|
uniform float m_Luminance5;
|
||||||
|
|
||||||
|
uniform float m_LineDistance;
|
||||||
|
uniform float m_LineThickness;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 texVal = texture2D(m_Texture, texCoord);
|
||||||
|
float linePixel = 0.0;
|
||||||
|
|
||||||
|
float lum = texVal.r*0.2126 + texVal.g*0.7152 + texVal.b*0.0722;
|
||||||
|
|
||||||
|
if (lum < m_Luminance1){
|
||||||
|
if (mod(gl_FragCoord.x + gl_FragCoord.y, m_LineDistance * 2.0) < m_LineThickness)
|
||||||
|
linePixel = 1.0;
|
||||||
|
}
|
||||||
|
if (lum < m_Luminance2){
|
||||||
|
if (mod(gl_FragCoord.x - gl_FragCoord.y, m_LineDistance * 2.0) < m_LineThickness)
|
||||||
|
linePixel = 1.0;
|
||||||
|
}
|
||||||
|
if (lum < m_Luminance3){
|
||||||
|
if (mod(gl_FragCoord.x + gl_FragCoord.y - m_LineDistance, m_LineDistance) < m_LineThickness)
|
||||||
|
linePixel = 1.0;
|
||||||
|
}
|
||||||
|
if (lum < m_Luminance4){
|
||||||
|
if (mod(gl_FragCoord.x - gl_FragCoord.y - m_LineDistance, m_LineDistance) < m_LineThickness)
|
||||||
|
linePixel = 1.0;
|
||||||
|
}
|
||||||
|
if (lum < m_Luminance5){ // No line, make a blob instead
|
||||||
|
linePixel = m_FillValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mix line color with existing color information
|
||||||
|
vec4 lineColor = mix(m_LineColor, texVal, m_ColorInfluenceLine);
|
||||||
|
// Mix paper color with existing color information
|
||||||
|
vec4 paperColor = mix(m_PaperColor, texVal, m_ColorInfluencePaper);
|
||||||
|
|
||||||
|
gl_FragColor = mix(paperColor, lineColor, linePixel);
|
||||||
|
}
|
41
engine/src/core-effects/Common/MatDefs/Post/CrossHatch.j3md
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
MaterialDef CrossHatch {
|
||||||
|
|
||||||
|
MaterialParameters {
|
||||||
|
Int NumSamples
|
||||||
|
Texture2D Texture;
|
||||||
|
Vector4 LineColor;
|
||||||
|
Vector4 PaperColor;
|
||||||
|
Float ColorInfluenceLine;
|
||||||
|
Float ColorInfluencePaper;
|
||||||
|
Float FillValue;
|
||||||
|
Float Luminance1;
|
||||||
|
Float Luminance2;
|
||||||
|
Float Luminance3;
|
||||||
|
Float Luminance4;
|
||||||
|
Float Luminance5;
|
||||||
|
Float LineThickness;
|
||||||
|
Float LineDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL150: Common/MatDefs/Post/Post15.vert
|
||||||
|
FragmentShader GLSL150: Common/MatDefs/Post/CrossHatch15.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL100: Common/MatDefs/Post/Post.vert
|
||||||
|
FragmentShader GLSL100: Common/MatDefs/Post/CrossHatch.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique FixedFunc {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
#import "Common/ShaderLib/MultiSample.glsllib"
|
||||||
|
|
||||||
|
uniform COLORTEXTURE m_Texture;
|
||||||
|
in vec2 texCoord;
|
||||||
|
|
||||||
|
uniform vec4 m_LineColor;
|
||||||
|
uniform vec4 m_PaperColor;
|
||||||
|
uniform float m_ColorInfluenceLine;
|
||||||
|
uniform float m_ColorInfluencePaper;
|
||||||
|
|
||||||
|
uniform float m_FillValue;
|
||||||
|
uniform float m_Luminance1;
|
||||||
|
uniform float m_Luminance2;
|
||||||
|
uniform float m_Luminance3;
|
||||||
|
uniform float m_Luminance4;
|
||||||
|
uniform float m_Luminance5;
|
||||||
|
|
||||||
|
uniform float m_LineDistance;
|
||||||
|
uniform float m_LineThickness;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 texVal = getColor(m_Texture, texCoord);
|
||||||
|
float linePixel = 0;
|
||||||
|
|
||||||
|
float lum = texVal.r*0.2126 + texVal.g*0.7152 + texVal.b*0.0722;
|
||||||
|
|
||||||
|
if (lum < m_Luminance1){
|
||||||
|
if (mod(gl_FragCoord.x + gl_FragCoord.y, m_LineDistance * 2.0) < m_LineThickness)
|
||||||
|
linePixel = 1;
|
||||||
|
}
|
||||||
|
if (lum < m_Luminance2){
|
||||||
|
if (mod(gl_FragCoord.x - gl_FragCoord.y, m_LineDistance * 2.0) < m_LineThickness)
|
||||||
|
linePixel = 1;
|
||||||
|
}
|
||||||
|
if (lum < m_Luminance3){
|
||||||
|
if (mod(gl_FragCoord.x + gl_FragCoord.y - m_LineDistance, m_LineDistance) < m_LineThickness)
|
||||||
|
linePixel = 1;
|
||||||
|
}
|
||||||
|
if (lum < m_Luminance4){
|
||||||
|
if (mod(gl_FragCoord.x - gl_FragCoord.y - m_LineDistance, m_LineDistance) < m_LineThickness)
|
||||||
|
linePixel = 1;
|
||||||
|
}
|
||||||
|
if (lum < m_Luminance5){ // No line, make a blob instead
|
||||||
|
linePixel = m_FillValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mix line color with existing color information
|
||||||
|
vec4 lineColor = mix(m_LineColor, texVal, m_ColorInfluenceLine);
|
||||||
|
// Mix paper color with existing color information
|
||||||
|
vec4 paperColor = mix(m_PaperColor, texVal, m_ColorInfluencePaper);
|
||||||
|
|
||||||
|
gl_FragColor = mix(paperColor, lineColor, linePixel);
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
uniform sampler2D m_Texture;
|
||||||
|
uniform sampler2D m_DepthTexture;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
uniform float m_FocusRange;
|
||||||
|
uniform float m_FocusDistance;
|
||||||
|
uniform float m_XScale;
|
||||||
|
uniform float m_YScale;
|
||||||
|
|
||||||
|
vec2 m_NearFar = vec2( 0.1, 1000.0 );
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
vec4 texVal = texture2D( m_Texture, texCoord );
|
||||||
|
|
||||||
|
float zBuffer = texture2D( m_DepthTexture, texCoord ).r;
|
||||||
|
|
||||||
|
//
|
||||||
|
// z_buffer_value = a + b / z;
|
||||||
|
//
|
||||||
|
// Where:
|
||||||
|
// a = zFar / ( zFar - zNear )
|
||||||
|
// b = zFar * zNear / ( zNear - zFar )
|
||||||
|
// z = distance from the eye to the object
|
||||||
|
//
|
||||||
|
// Which means:
|
||||||
|
// zb - a = b / z;
|
||||||
|
// z * (zb - a) = b
|
||||||
|
// z = b / (zb - a)
|
||||||
|
//
|
||||||
|
float a = m_NearFar.y / (m_NearFar.y - m_NearFar.x);
|
||||||
|
float b = m_NearFar.y * m_NearFar.x / (m_NearFar.x - m_NearFar.y);
|
||||||
|
float z = b / (zBuffer - a);
|
||||||
|
|
||||||
|
// Above could be the same for any depth-based filter
|
||||||
|
|
||||||
|
// We want to be purely focused right at
|
||||||
|
// m_FocusDistance and be purely unfocused
|
||||||
|
// at +/- m_FocusRange to either side of that.
|
||||||
|
float unfocus = min( 1.0, abs( z - m_FocusDistance ) / m_FocusRange );
|
||||||
|
|
||||||
|
if( unfocus < 0.2 ) {
|
||||||
|
// If we are mostly in focus then don't bother with the
|
||||||
|
// convolution filter
|
||||||
|
gl_FragColor = texVal;
|
||||||
|
} else {
|
||||||
|
// Perform a wide convolution filter and we scatter it
|
||||||
|
// a bit to avoid some texture look-ups. Instead of
|
||||||
|
// a full 5x5 (25-1 lookups) we'll skip every other one
|
||||||
|
// to only perform 12.
|
||||||
|
// 1 0 1 0 1
|
||||||
|
// 0 1 0 1 0
|
||||||
|
// 1 0 x 0 1
|
||||||
|
// 0 1 0 1 0
|
||||||
|
// 1 0 1 0 1
|
||||||
|
//
|
||||||
|
// You can get away with 8 just around the outside but
|
||||||
|
// it looks more jittery to me.
|
||||||
|
|
||||||
|
vec4 sum = vec4(0.0);
|
||||||
|
|
||||||
|
float x = texCoord.x;
|
||||||
|
float y = texCoord.y;
|
||||||
|
|
||||||
|
float xScale = m_XScale;
|
||||||
|
float yScale = m_YScale;
|
||||||
|
|
||||||
|
// In order from lower left to right, depending on how you look at it
|
||||||
|
sum += texture2D( m_Texture, vec2(x - 2.0 * xScale, y - 2.0 * yScale) );
|
||||||
|
sum += texture2D( m_Texture, vec2(x - 0.0 * xScale, y - 2.0 * yScale) );
|
||||||
|
sum += texture2D( m_Texture, vec2(x + 2.0 * xScale, y - 2.0 * yScale) );
|
||||||
|
sum += texture2D( m_Texture, vec2(x - 1.0 * xScale, y - 1.0 * yScale) );
|
||||||
|
sum += texture2D( m_Texture, vec2(x + 1.0 * xScale, y - 1.0 * yScale) );
|
||||||
|
sum += texture2D( m_Texture, vec2(x - 2.0 * xScale, y - 0.0 * yScale) );
|
||||||
|
sum += texture2D( m_Texture, vec2(x + 2.0 * xScale, y - 0.0 * yScale) );
|
||||||
|
sum += texture2D( m_Texture, vec2(x - 1.0 * xScale, y + 1.0 * yScale) );
|
||||||
|
sum += texture2D( m_Texture, vec2(x + 1.0 * xScale, y + 1.0 * yScale) );
|
||||||
|
sum += texture2D( m_Texture, vec2(x - 2.0 * xScale, y + 2.0 * yScale) );
|
||||||
|
sum += texture2D( m_Texture, vec2(x - 0.0 * xScale, y + 2.0 * yScale) );
|
||||||
|
sum += texture2D( m_Texture, vec2(x + 2.0 * xScale, y + 2.0 * yScale) );
|
||||||
|
|
||||||
|
sum = sum / 12.0;
|
||||||
|
|
||||||
|
gl_FragColor = mix( texVal, sum, unfocus );
|
||||||
|
|
||||||
|
// I used this for debugging the range
|
||||||
|
// gl_FragColor.r = unfocus;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
MaterialDef Depth Of Field {
|
||||||
|
|
||||||
|
MaterialParameters {
|
||||||
|
Int NumSamples
|
||||||
|
Int NumSamplesDepth
|
||||||
|
Texture2D Texture
|
||||||
|
Texture2D DepthTexture
|
||||||
|
Float FocusRange;
|
||||||
|
Float FocusDistance;
|
||||||
|
Float XScale;
|
||||||
|
Float YScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL100: Common/MatDefs/Post/Post.vert
|
||||||
|
FragmentShader GLSL100: Common/MatDefs/Post/DepthOfField.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique FixedFunc {
|
||||||
|
}
|
||||||
|
}
|
88
engine/src/core-effects/Common/MatDefs/Post/FXAA.frag
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#extension GL_EXT_gpu_shader4 : enable
|
||||||
|
|
||||||
|
uniform sampler2D m_Texture;
|
||||||
|
uniform vec2 g_Resolution;
|
||||||
|
|
||||||
|
uniform float m_VxOffset;
|
||||||
|
uniform float m_SpanMax;
|
||||||
|
uniform float m_ReduceMul;
|
||||||
|
|
||||||
|
varying vec2 texCoord;
|
||||||
|
varying vec4 posPos;
|
||||||
|
|
||||||
|
#define FxaaTex(t, p) texture2D(t, p)
|
||||||
|
|
||||||
|
#if __VERSION__ >= 130
|
||||||
|
#define OffsetVec(a, b) ivec2(a, b)
|
||||||
|
#define FxaaTexOff(t, p, o, r) textureOffset(t, p, o)
|
||||||
|
#elif defined(GL_EXT_gpu_shader4)
|
||||||
|
#define OffsetVec(a, b) ivec2(a, b)
|
||||||
|
#define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)
|
||||||
|
#else
|
||||||
|
#define OffsetVec(a, b) vec2(a, b)
|
||||||
|
#define FxaaTexOff(t, p, o, r) texture2D(t, p + o * r)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec3 FxaaPixelShader(
|
||||||
|
vec4 posPos, // Output of FxaaVertexShader interpolated across screen.
|
||||||
|
sampler2D tex, // Input texture.
|
||||||
|
vec2 rcpFrame) // Constant {1.0/frameWidth, 1.0/frameHeight}.
|
||||||
|
{
|
||||||
|
|
||||||
|
#define FXAA_REDUCE_MIN (1.0/128.0)
|
||||||
|
//#define FXAA_REDUCE_MUL (1.0/8.0)
|
||||||
|
//#define FXAA_SPAN_MAX 8.0
|
||||||
|
|
||||||
|
vec3 rgbNW = FxaaTex(tex, posPos.zw).xyz;
|
||||||
|
vec3 rgbNE = FxaaTexOff(tex, posPos.zw, OffsetVec(1,0), rcpFrame.xy).xyz;
|
||||||
|
vec3 rgbSW = FxaaTexOff(tex, posPos.zw, OffsetVec(0,1), rcpFrame.xy).xyz;
|
||||||
|
vec3 rgbSE = FxaaTexOff(tex, posPos.zw, OffsetVec(1,1), rcpFrame.xy).xyz;
|
||||||
|
|
||||||
|
vec3 rgbM = FxaaTex(tex, posPos.xy).xyz;
|
||||||
|
|
||||||
|
vec3 luma = vec3(0.299, 0.587, 0.114);
|
||||||
|
float lumaNW = dot(rgbNW, luma);
|
||||||
|
float lumaNE = dot(rgbNE, luma);
|
||||||
|
float lumaSW = dot(rgbSW, luma);
|
||||||
|
float lumaSE = dot(rgbSE, luma);
|
||||||
|
float lumaM = dot(rgbM, luma);
|
||||||
|
|
||||||
|
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
|
||||||
|
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
|
||||||
|
|
||||||
|
vec2 dir;
|
||||||
|
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
|
||||||
|
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
|
||||||
|
|
||||||
|
float dirReduce = max(
|
||||||
|
(lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * m_ReduceMul),
|
||||||
|
FXAA_REDUCE_MIN);
|
||||||
|
float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);
|
||||||
|
dir = min(vec2( m_SpanMax, m_SpanMax),
|
||||||
|
max(vec2(-m_SpanMax, -m_SpanMax),
|
||||||
|
dir * rcpDirMin)) * rcpFrame.xy;
|
||||||
|
|
||||||
|
vec3 rgbA = (1.0/2.0) * (
|
||||||
|
FxaaTex(tex, posPos.xy + dir * vec2(1.0/3.0 - 0.5)).xyz +
|
||||||
|
FxaaTex(tex, posPos.xy + dir * vec2(2.0/3.0 - 0.5)).xyz);
|
||||||
|
vec3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (
|
||||||
|
FxaaTex(tex, posPos.xy + dir * vec2(0.0/3.0 - 0.5)).xyz +
|
||||||
|
FxaaTex(tex, posPos.xy + dir * vec2(3.0/3.0 - 0.5)).xyz);
|
||||||
|
|
||||||
|
float lumaB = dot(rgbB, luma);
|
||||||
|
|
||||||
|
if ((lumaB < lumaMin) || (lumaB > lumaMax))
|
||||||
|
{
|
||||||
|
return rgbA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return rgbB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 rcpFrame = vec2(1.0) / g_Resolution;
|
||||||
|
gl_FragColor = vec4(FxaaPixelShader(posPos, m_Texture, rcpFrame), 1.0);
|
||||||
|
}
|
20
engine/src/core-effects/Common/MatDefs/Post/FXAA.j3md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
MaterialDef FXAA {
|
||||||
|
MaterialParameters {
|
||||||
|
Int NumSamples
|
||||||
|
Texture2D Texture
|
||||||
|
Float SubPixelShift
|
||||||
|
Float VxOffset
|
||||||
|
Float SpanMax
|
||||||
|
Float ReduceMul
|
||||||
|
}
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL100: Common/MatDefs/Post/FXAA.vert
|
||||||
|
FragmentShader GLSL100: Common/MatDefs/Post/FXAA.frag
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
Resolution
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Technique FixedFunc {
|
||||||
|
}
|
||||||
|
}
|
18
engine/src/core-effects/Common/MatDefs/Post/FXAA.vert
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
uniform mat4 g_WorldViewProjectionMatrix;
|
||||||
|
uniform vec2 g_Resolution;
|
||||||
|
|
||||||
|
uniform float m_SubPixelShift;
|
||||||
|
|
||||||
|
attribute vec4 inPosition;
|
||||||
|
attribute vec2 inTexCoord;
|
||||||
|
|
||||||
|
varying vec2 texCoord;
|
||||||
|
varying vec4 posPos;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = inPosition * 2.0 - 1.0; //vec4(pos, 0.0, 1.0);
|
||||||
|
texCoord = inTexCoord;
|
||||||
|
vec2 rcpFrame = vec2(1.0) / g_Resolution;
|
||||||
|
posPos.xy = inTexCoord.xy;
|
||||||
|
posPos.zw = inTexCoord.xy - (rcpFrame * vec2(0.5 + m_SubPixelShift));
|
||||||
|
}
|
11
engine/src/core-effects/Common/MatDefs/Post/Fade.frag
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
uniform sampler2D m_Texture;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
uniform float m_Value;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 texVal = texture2D(m_Texture, texCoord);
|
||||||
|
|
||||||
|
gl_FragColor = texVal * m_Value;
|
||||||
|
|
||||||
|
}
|
34
engine/src/core-effects/Common/MatDefs/Post/Fade.j3md
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
MaterialDef Fade {
|
||||||
|
|
||||||
|
MaterialParameters {
|
||||||
|
Int NumSamples
|
||||||
|
Texture2D Texture
|
||||||
|
Float Value
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL150: Common/MatDefs/Post/Post15.vert
|
||||||
|
FragmentShader GLSL150: Common/MatDefs/Post/Fade15.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
RESOLVE_MS : NumSamples
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL100: Common/MatDefs/Post/Post.vert
|
||||||
|
FragmentShader GLSL100: Common/MatDefs/Post/Fade.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique FixedFunc {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
engine/src/core-effects/Common/MatDefs/Post/Fade15.frag
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#import "Common/ShaderLib/MultiSample.glsllib"
|
||||||
|
|
||||||
|
uniform COLORTEXTURE m_Texture;
|
||||||
|
uniform float m_Value;
|
||||||
|
|
||||||
|
in vec2 texCoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 texVal = getColor(m_Texture, texCoord);
|
||||||
|
gl_FragColor = texVal * m_Value;
|
||||||
|
}
|
21
engine/src/core-effects/Common/MatDefs/Post/Fog.frag
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
uniform sampler2D m_Texture;
|
||||||
|
uniform sampler2D m_DepthTexture;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
uniform vec4 m_FogColor;
|
||||||
|
uniform float m_FogDensity;
|
||||||
|
uniform float m_FogDistance;
|
||||||
|
|
||||||
|
vec2 m_FrustumNearFar=vec2(1.0,m_FogDistance);
|
||||||
|
const float LOG2 = 1.442695;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 texVal = texture2D(m_Texture, texCoord);
|
||||||
|
float fogVal =texture2D(m_DepthTexture,texCoord).r;
|
||||||
|
float depth= (2.0 * m_FrustumNearFar.x) / (m_FrustumNearFar.y + m_FrustumNearFar.x - fogVal* (m_FrustumNearFar.y-m_FrustumNearFar.x));
|
||||||
|
|
||||||
|
float fogFactor = exp2( -m_FogDensity * m_FogDensity * depth * depth * LOG2 );
|
||||||
|
fogFactor = clamp(fogFactor, 0.0, 1.0);
|
||||||
|
gl_FragColor =mix(m_FogColor,texVal,fogFactor);
|
||||||
|
|
||||||
|
}
|
39
engine/src/core-effects/Common/MatDefs/Post/Fog.j3md
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
MaterialDef Fade {
|
||||||
|
|
||||||
|
MaterialParameters {
|
||||||
|
Int NumSamples
|
||||||
|
Int NumSamplesDepth
|
||||||
|
Texture2D Texture
|
||||||
|
Texture2D DepthTexture
|
||||||
|
Vector4 FogColor;
|
||||||
|
Float FogDensity;
|
||||||
|
Float FogDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL150: Common/MatDefs/Post/Post15.vert
|
||||||
|
FragmentShader GLSL150: Common/MatDefs/Post/Fog15.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
RESOLVE_MS : NumSamples
|
||||||
|
RESOLVE_DEPTH_MS : NumSamplesDepth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL100: Common/MatDefs/Post/Post.vert
|
||||||
|
FragmentShader GLSL100: Common/MatDefs/Post/Fog.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique FixedFunc {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
24
engine/src/core-effects/Common/MatDefs/Post/Fog15.frag
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#import "Common/ShaderLib/MultiSample.glsllib"
|
||||||
|
|
||||||
|
uniform COLORTEXTURE m_Texture;
|
||||||
|
uniform DEPTHTEXTURE m_DepthTexture;
|
||||||
|
|
||||||
|
uniform vec4 m_FogColor;
|
||||||
|
uniform float m_FogDensity;
|
||||||
|
uniform float m_FogDistance;
|
||||||
|
|
||||||
|
in vec2 texCoord;
|
||||||
|
|
||||||
|
vec2 m_FrustumNearFar=vec2(1.0,m_FogDistance);
|
||||||
|
const float LOG2 = 1.442695;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 texVal = getColor(m_Texture, texCoord);
|
||||||
|
float fogVal = getDepth(m_DepthTexture,texCoord).r;
|
||||||
|
float depth= (2.0 * m_FrustumNearFar.x) / (m_FrustumNearFar.y + m_FrustumNearFar.x - fogVal* (m_FrustumNearFar.y-m_FrustumNearFar.x));
|
||||||
|
|
||||||
|
float fogFactor = exp2( -m_FogDensity * m_FogDensity * depth * depth * LOG2 );
|
||||||
|
fogFactor = clamp(fogFactor, 0.0, 1.0);
|
||||||
|
gl_FragColor =mix(m_FogColor,texVal,fogFactor);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
uniform sampler2D m_Texture;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
uniform float m_gamma;
|
||||||
|
|
||||||
|
vec3 gamma(vec3 L,float gamma)
|
||||||
|
{
|
||||||
|
return pow(L, vec3(1.0 / gamma));
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 texVal = texture2D(m_Texture, texCoord);
|
||||||
|
|
||||||
|
if(m_gamma > 0.0)
|
||||||
|
{
|
||||||
|
texVal.rgb = gamma(texVal.rgb , m_gamma);
|
||||||
|
}
|
||||||
|
#ifdef COMPUTE_LUMA
|
||||||
|
texVal.a = dot(texVal.rgb, vec3(0.299, 0.587, 0.114));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gl_FragColor = texVal;
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
MaterialDef GammaCorrection {
|
||||||
|
|
||||||
|
MaterialParameters {
|
||||||
|
Int NumSamples
|
||||||
|
Texture2D Texture
|
||||||
|
Float gamma
|
||||||
|
Boolean computeLuma
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL150: Common/MatDefs/Post/Post15.vert
|
||||||
|
FragmentShader GLSL150: Common/MatDefs/Post/GammaCorrection15.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
COMPUTE_LUMA : computeLuma
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL100: Common/MatDefs/Post/Post.vert
|
||||||
|
FragmentShader GLSL100: Common/MatDefs/Post/GammaCorrection.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
COMPUTE_LUMA : computeLuma
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique FixedFunc {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
#import "Common/ShaderLib/MultiSample.glsllib"
|
||||||
|
|
||||||
|
uniform COLORTEXTURE m_Texture;
|
||||||
|
in vec2 texCoord;
|
||||||
|
|
||||||
|
uniform float m_gamma;
|
||||||
|
|
||||||
|
vec3 gamma(vec3 L,float gamma)
|
||||||
|
{
|
||||||
|
return pow(L, vec3(1.0 / gamma));
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 texVal = texture2D(m_Texture, texCoord);
|
||||||
|
|
||||||
|
if(m_gamma > 0.0)
|
||||||
|
{
|
||||||
|
texVal.rgb = gamma(texVal.rgb , m_gamma);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef COMPUTE_LUMA
|
||||||
|
texVal.a = dot(texVal.rgb, vec3(0.299, 0.587, 0.114));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gl_FragColor = texVal;
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
uniform sampler2D m_Texture;
|
||||||
|
uniform sampler2D m_DepthTexture;
|
||||||
|
uniform int m_NbSamples;
|
||||||
|
uniform float m_BlurStart;
|
||||||
|
uniform float m_BlurWidth;
|
||||||
|
uniform float m_LightDensity;
|
||||||
|
uniform bool m_Display;
|
||||||
|
|
||||||
|
varying vec2 lightPos;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
if(m_Display){
|
||||||
|
|
||||||
|
vec4 colorRes= texture2D(m_Texture,texCoord);
|
||||||
|
float factor=(m_BlurWidth/float(m_NbSamples-1.0));
|
||||||
|
float scale;
|
||||||
|
vec2 texCoo=texCoord-lightPos;
|
||||||
|
vec2 scaledCoord;
|
||||||
|
vec4 res = vec4(0.0);
|
||||||
|
for(int i=0; i<m_NbSamples; i++) {
|
||||||
|
scale = i * factor + m_BlurStart ;
|
||||||
|
scaledCoord=texCoo*scale+lightPos;
|
||||||
|
if(texture2D(m_DepthTexture,scaledCoord).r==1.0){
|
||||||
|
res += texture2D(m_Texture,scaledCoord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res /= m_NbSamples;
|
||||||
|
|
||||||
|
//Blend the original color with the averaged pixels
|
||||||
|
gl_FragColor =mix( colorRes, res, m_LightDensity);
|
||||||
|
}else{
|
||||||
|
gl_FragColor= texture2D(m_Texture,texCoord);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
MaterialDef Light Scattering {
|
||||||
|
MaterialParameters {
|
||||||
|
Int NumSamples
|
||||||
|
Int NumSamplesDepth
|
||||||
|
Texture2D Texture
|
||||||
|
Texture2D DepthTexture
|
||||||
|
Vector3 LightPosition
|
||||||
|
Int NbSamples
|
||||||
|
Float BlurStart
|
||||||
|
Float BlurWidth
|
||||||
|
Float LightDensity
|
||||||
|
Boolean Display
|
||||||
|
Boolean multiSampledDepth
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL150: Common/MatDefs/Post/LightScattering15.vert
|
||||||
|
FragmentShader GLSL150: Common/MatDefs/Post/LightScattering15.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
RESOLVE_MS : NumSamples
|
||||||
|
RESOLVE_DEPTH_MS : NumSamplesDepth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL120: Common/MatDefs/Post/LightScattering.vert
|
||||||
|
FragmentShader GLSL120: Common/MatDefs/Post/LightScattering.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique FixedFunc {
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
uniform mat4 g_WorldViewProjectionMatrix;
|
||||||
|
uniform vec3 m_LightPosition;
|
||||||
|
|
||||||
|
attribute vec4 inPosition;
|
||||||
|
attribute vec2 inTexCoord;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
varying vec2 lightPos;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 pos = (g_WorldViewProjectionMatrix * inPosition).xy;
|
||||||
|
gl_Position = vec4(pos, 0.0, 1.0);
|
||||||
|
lightPos=m_LightPosition.xy;
|
||||||
|
texCoord = inTexCoord;
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
#import "Common/ShaderLib/MultiSample.glsllib"
|
||||||
|
|
||||||
|
uniform COLORTEXTURE m_Texture;
|
||||||
|
uniform DEPTHTEXTURE m_DepthTexture;
|
||||||
|
|
||||||
|
uniform int m_NbSamples;
|
||||||
|
uniform float m_BlurStart;
|
||||||
|
uniform float m_BlurWidth;
|
||||||
|
uniform float m_LightDensity;
|
||||||
|
uniform bool m_Display;
|
||||||
|
|
||||||
|
in vec2 lightPos;
|
||||||
|
in vec2 texCoord;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
if(m_Display){
|
||||||
|
|
||||||
|
vec4 colorRes= getColor(m_Texture,texCoord);
|
||||||
|
float factor=(m_BlurWidth/float(m_NbSamples-1.0));
|
||||||
|
float scale;
|
||||||
|
vec2 texCoo=texCoord-lightPos;
|
||||||
|
vec2 scaledCoord;
|
||||||
|
vec4 res = vec4(0.0);
|
||||||
|
for(int i=0; i<m_NbSamples; i++) {
|
||||||
|
scale = i * factor + m_BlurStart ;
|
||||||
|
scaledCoord=texCoo*scale+lightPos;
|
||||||
|
if(fetchTextureSample(m_DepthTexture, scaledCoord,0).r==1.0){
|
||||||
|
res += fetchTextureSample(m_Texture,scaledCoord,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res /= m_NbSamples;
|
||||||
|
|
||||||
|
//Blend the original color with the averaged pixels
|
||||||
|
gl_FragColor =mix( colorRes, res, m_LightDensity);
|
||||||
|
}else{
|
||||||
|
gl_FragColor= getColor(m_Texture,texCoord);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
uniform mat4 g_WorldViewProjectionMatrix;
|
||||||
|
uniform vec3 m_LightPosition;
|
||||||
|
|
||||||
|
in vec4 inPosition;
|
||||||
|
in vec2 inTexCoord;
|
||||||
|
out vec2 texCoord;
|
||||||
|
out vec2 lightPos;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 pos = (g_WorldViewProjectionMatrix * inPosition).xy;
|
||||||
|
gl_Position = vec4(pos, 0.0, 1.0);
|
||||||
|
lightPos=m_LightPosition.xy;
|
||||||
|
texCoord = inTexCoord;
|
||||||
|
}
|
9
engine/src/core-effects/Common/MatDefs/Post/Overlay.frag
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
uniform sampler2D m_Texture;
|
||||||
|
uniform vec4 m_Color;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 texVal = texture2D(m_Texture, texCoord);
|
||||||
|
gl_FragColor = texVal * m_Color;
|
||||||
|
}
|
||||||
|
|
36
engine/src/core-effects/Common/MatDefs/Post/Overlay.j3md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
MaterialDef Default GUI {
|
||||||
|
|
||||||
|
MaterialParameters {
|
||||||
|
Int NumSamples
|
||||||
|
Texture2D Texture
|
||||||
|
Color Color
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL150: Common/MatDefs/Post/Post15.vert
|
||||||
|
FragmentShader GLSL150: Common/MatDefs/Post/Overlay15.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
RESOLVE_MS : NumSamples
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL100: Common/MatDefs/Post/Post.vert
|
||||||
|
FragmentShader GLSL100: Common/MatDefs/Post/Overlay.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique FixedFunc {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
engine/src/core-effects/Common/MatDefs/Post/Overlay15.frag
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#import "Common/ShaderLib/MultiSample.glsllib"
|
||||||
|
|
||||||
|
uniform COLORTEXTURE m_Texture;
|
||||||
|
uniform vec4 m_Color;
|
||||||
|
in vec2 texCoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 texVal = getColor(m_Texture, texCoord);
|
||||||
|
gl_FragColor = texVal * m_Color;
|
||||||
|
}
|
||||||
|
|
10
engine/src/core-effects/Common/MatDefs/Post/Post.vert
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
uniform mat4 g_WorldViewProjectionMatrix;
|
||||||
|
|
||||||
|
attribute vec4 inPosition;
|
||||||
|
attribute vec2 inTexCoord;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = inPosition * 2.0 - 1.0; //vec4(pos, 0.0, 1.0);
|
||||||
|
texCoord = inTexCoord;
|
||||||
|
}
|
12
engine/src/core-effects/Common/MatDefs/Post/Post15.vert
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
uniform mat4 g_WorldViewProjectionMatrix;
|
||||||
|
|
||||||
|
in vec4 inPosition;
|
||||||
|
in vec2 inTexCoord;
|
||||||
|
|
||||||
|
out vec2 texCoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 pos = (g_WorldViewProjectionMatrix * inPosition).xy;
|
||||||
|
gl_Position = vec4(pos, 0.0, 1.0);
|
||||||
|
texCoord = inTexCoord;
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
uniform sampler2D m_Texture;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
uniform int m_NumColors;
|
||||||
|
uniform float m_Gamma;
|
||||||
|
uniform float m_Strength;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 texVal = texture2D(m_Texture, texCoord);
|
||||||
|
|
||||||
|
texVal = pow(texVal, vec4(m_Gamma));
|
||||||
|
texVal = texVal * vec4(m_NumColors);
|
||||||
|
texVal = floor(texVal);
|
||||||
|
texVal = texVal / vec4(m_NumColors);
|
||||||
|
texVal = pow(texVal, vec4(1.0/m_Gamma));
|
||||||
|
|
||||||
|
gl_FragColor = mix(texture2D(m_Texture, texCoord), texVal, m_Strength);
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
MaterialDef Posterization {
|
||||||
|
|
||||||
|
MaterialParameters {
|
||||||
|
Int NumSamples
|
||||||
|
Texture2D Texture;
|
||||||
|
Int NumColors;
|
||||||
|
Float Gamma;
|
||||||
|
Float Strength;
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL150: Common/MatDefs/Post/Post15.vert
|
||||||
|
FragmentShader GLSL150: Common/MatDefs/Post/Posterization15.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL100: Common/MatDefs/Post/Post.vert
|
||||||
|
FragmentShader GLSL100: Common/MatDefs/Post/Posterization.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique FixedFunc {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
#import "Common/ShaderLib/MultiSample.glsllib"
|
||||||
|
|
||||||
|
uniform COLORTEXTURE m_Texture;
|
||||||
|
in vec2 texCoord;
|
||||||
|
|
||||||
|
uniform int m_NumColors;
|
||||||
|
uniform float m_Gamma;
|
||||||
|
uniform float m_Strength;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 texVal = getColor(m_Texture, texCoord);
|
||||||
|
|
||||||
|
texVal = pow(texVal, vec4(m_Gamma));
|
||||||
|
texVal = texVal * m_NumColors;
|
||||||
|
texVal = floor(texVal);
|
||||||
|
texVal = texVal / m_NumColors;
|
||||||
|
texVal = pow(texVal, vec4(1.0/m_Gamma));
|
||||||
|
|
||||||
|
gl_FragColor = mix(getColor(m_Texture, texCoord), texVal, m_Strength);
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
uniform float m_ExposurePow;
|
||||||
|
uniform float m_ExposureCutoff;
|
||||||
|
uniform sampler2D m_Texture;
|
||||||
|
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
#ifdef HAS_GLOWMAP
|
||||||
|
uniform sampler2D m_GlowMap;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec4 color = vec4(0.0);
|
||||||
|
#ifdef DO_EXTRACT
|
||||||
|
color = texture2D( m_Texture, texCoord );
|
||||||
|
if ( (color.r+color.g+color.b)/3.0 < m_ExposureCutoff ) {
|
||||||
|
color = vec4(0.0);
|
||||||
|
}else{
|
||||||
|
color = pow(color,vec4(m_ExposurePow));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAS_GLOWMAP
|
||||||
|
vec4 glowColor = texture2D(m_GlowMap, texCoord);
|
||||||
|
glowColor = pow(glowColor, vec4(m_ExposurePow));
|
||||||
|
color += glowColor;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gl_FragColor = color;
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
#import "Common/ShaderLib/MultiSample.glsllib"
|
||||||
|
|
||||||
|
uniform COLORTEXTURE m_Texture;
|
||||||
|
|
||||||
|
uniform float m_ExposurePow;
|
||||||
|
uniform float m_ExposureCutoff;
|
||||||
|
|
||||||
|
in vec2 texCoord;
|
||||||
|
out vec4 outFragColor;
|
||||||
|
|
||||||
|
#ifdef HAS_GLOWMAP
|
||||||
|
uniform sampler2D m_GlowMap;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec4 color = vec4(0.0);
|
||||||
|
#ifdef DO_EXTRACT
|
||||||
|
color = getColorSingle(m_Texture, texCoord);
|
||||||
|
if ( (color.r + color.g + color.b) / 3.0 >= m_ExposureCutoff ) {
|
||||||
|
color = pow(color, vec4(m_ExposurePow));
|
||||||
|
}else{
|
||||||
|
color = vec4(0.0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAS_GLOWMAP
|
||||||
|
vec4 glowColor = texture2D( m_GlowMap, texCoord );
|
||||||
|
glowColor = pow(glowColor, vec4(m_ExposurePow));
|
||||||
|
color += glowColor;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
outFragColor = color;
|
||||||
|
}
|
12
engine/src/core-effects/Common/MatDefs/Post/bloomFinal.frag
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
uniform sampler2D m_Texture;
|
||||||
|
uniform sampler2D m_BloomTex;
|
||||||
|
uniform float m_BloomIntensity;
|
||||||
|
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec4 colorRes = texture2D(m_Texture, texCoord);
|
||||||
|
vec4 bloom = texture2D(m_BloomTex, texCoord);
|
||||||
|
gl_FragColor = bloom * m_BloomIntensity + colorRes;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
|||||||
|
#import "Common/ShaderLib/MultiSample.glsllib"
|
||||||
|
|
||||||
|
uniform COLORTEXTURE m_Texture;
|
||||||
|
|
||||||
|
uniform sampler2D m_BloomTex;
|
||||||
|
uniform float m_BloomIntensity;
|
||||||
|
|
||||||
|
in vec2 texCoord;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec4 colorRes = getColor(m_Texture,texCoord);
|
||||||
|
vec4 bloom = texture2D(m_BloomTex, texCoord);
|
||||||
|
gl_FragColor = bloom * m_BloomIntensity + colorRes;
|
||||||
|
}
|
||||||
|
|
BIN
engine/src/core-effects/Common/MatDefs/SSAO/Textures/random.png
Normal file
After Width: | Height: | Size: 42 KiB |
21
engine/src/core-effects/Common/MatDefs/SSAO/normal.frag
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
varying vec3 normal;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DIFFUSEMAP_ALPHA
|
||||||
|
uniform sampler2D m_DiffuseMap;
|
||||||
|
uniform float m_AlphaDiscardThreshold;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef DIFFUSEMAP_ALPHA
|
||||||
|
if(texture2D(m_DiffuseMap,texCoord).a<m_AlphaDiscardThreshold){
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
gl_FragColor = vec4(normal.xy* 0.5 + 0.5,-normal.z* 0.5 + 0.5, 1.0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
16
engine/src/core-effects/Common/MatDefs/SSAO/normal.vert
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
uniform mat4 g_WorldViewProjectionMatrix;
|
||||||
|
uniform mat3 g_NormalMatrix;
|
||||||
|
|
||||||
|
attribute vec3 inPosition;
|
||||||
|
attribute vec3 inNormal;
|
||||||
|
attribute vec4 inTexCoord;
|
||||||
|
|
||||||
|
varying vec3 normal;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
texCoord=inTexCoord.xy;
|
||||||
|
normal = normalize(g_NormalMatrix * inNormal);
|
||||||
|
gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition,1.0);
|
||||||
|
}
|
104
engine/src/core-effects/Common/MatDefs/SSAO/ssao.frag
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
uniform vec2 g_Resolution;
|
||||||
|
uniform vec2 m_FrustumNearFar;
|
||||||
|
uniform sampler2D m_Texture;
|
||||||
|
uniform sampler2D m_Normals;
|
||||||
|
uniform sampler2D m_DepthTexture;
|
||||||
|
uniform vec3 m_FrustumCorner;
|
||||||
|
uniform float m_SampleRadius;
|
||||||
|
uniform float m_Intensity;
|
||||||
|
uniform float m_Scale;
|
||||||
|
uniform float m_Bias;
|
||||||
|
uniform bool m_UseOnlyAo;
|
||||||
|
uniform bool m_UseAo;
|
||||||
|
uniform vec2[4] m_Samples;
|
||||||
|
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
float depthv;
|
||||||
|
|
||||||
|
vec3 getPosition(in vec2 uv){
|
||||||
|
//Reconstruction from depth
|
||||||
|
depthv =texture2D(m_DepthTexture,uv).r;
|
||||||
|
float depth= (2.0 * m_FrustumNearFar.x) / (m_FrustumNearFar.y + m_FrustumNearFar.x - depthv* (m_FrustumNearFar.y-m_FrustumNearFar.x));
|
||||||
|
|
||||||
|
//one frustum corner method
|
||||||
|
float x = mix(-m_FrustumCorner.x, m_FrustumCorner.x, uv.x);
|
||||||
|
float y = mix(-m_FrustumCorner.y, m_FrustumCorner.y, uv.y);
|
||||||
|
|
||||||
|
return depth* vec3(x, y, m_FrustumCorner.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 getNormal(in vec2 uv){
|
||||||
|
return normalize(texture2D(m_Normals, uv).xyz * 2.0 - 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 getRandom(in vec2 uv){
|
||||||
|
float rand=(fract(uv.x*(g_Resolution.x/2.0))*0.25)+(fract(uv.y*(g_Resolution.y/2.0))*0.5);
|
||||||
|
return normalize(vec2(rand,rand));
|
||||||
|
}
|
||||||
|
|
||||||
|
float doAmbientOcclusion(in vec2 tc, in vec3 pos, in vec3 norm){
|
||||||
|
vec3 diff = getPosition(tc)- pos;
|
||||||
|
vec3 v = normalize(diff);
|
||||||
|
float d = length(diff) * m_Scale;
|
||||||
|
|
||||||
|
return max(0.0, dot(norm, v) - m_Bias) * ( 1.0/(1.0 + d) ) * m_Intensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 getColor(in float result){
|
||||||
|
|
||||||
|
if(m_UseOnlyAo){
|
||||||
|
return vec4(result,result,result, 1.0);
|
||||||
|
}
|
||||||
|
if(m_UseAo){
|
||||||
|
return texture2D(m_Texture,texCoord)* vec4(result,result,result, 1.0);
|
||||||
|
}else{
|
||||||
|
return texture2D(m_Texture,texCoord);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 reflection(in vec2 v1,in vec2 v2){
|
||||||
|
vec2 result= 2.0 * dot(v2, v1) * v2;
|
||||||
|
result=v1-result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//const vec2 vec[4] = vec2[4](vec2(1.0,0.0), vec2(-1.0,0.0), vec2(0.0,1.0), vec2(0.0,-1.0));
|
||||||
|
void main(){
|
||||||
|
|
||||||
|
float result;
|
||||||
|
|
||||||
|
//vec2 vec[4] = { vec2(1.0, 0.0), vec2(-1.0, 0.0), vec2(0.0, 1.0), vec2(0.0, -1.0) };
|
||||||
|
vec3 position = getPosition(texCoord);
|
||||||
|
//optimization, do not calculate AO if depth is 1
|
||||||
|
if(depthv==1.0){
|
||||||
|
gl_FragColor=getColor(1.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vec3 normal = getNormal(texCoord);
|
||||||
|
vec2 rand = getRandom(texCoord);
|
||||||
|
|
||||||
|
float ao = 0.0;
|
||||||
|
float rad =m_SampleRadius / position.z;
|
||||||
|
|
||||||
|
|
||||||
|
int iterations = 4;
|
||||||
|
for (int j = 0; j < iterations; ++j){
|
||||||
|
vec2 coord1 = reflection(vec2(m_Samples[j]), vec2(rand)) * vec2(rad,rad);
|
||||||
|
vec2 coord2 = vec2(coord1.x* 0.707 - coord1.y* 0.707, coord1.x* 0.707 + coord1.y* 0.707) ;
|
||||||
|
|
||||||
|
ao += doAmbientOcclusion(texCoord + coord1.xy * 0.25, position, normal);
|
||||||
|
ao += doAmbientOcclusion(texCoord + coord2 * 0.50, position, normal);
|
||||||
|
ao += doAmbientOcclusion(texCoord + coord1.xy * 0.75, position, normal);
|
||||||
|
ao += doAmbientOcclusion(texCoord + coord2 * 1.00, position, normal);
|
||||||
|
|
||||||
|
}
|
||||||
|
ao /= float(iterations) * 4.0;
|
||||||
|
result = 1.0-ao;
|
||||||
|
|
||||||
|
gl_FragColor=getColor(result);
|
||||||
|
|
||||||
|
//gl_FragColor=vec4(normal,1.0);
|
||||||
|
}
|
51
engine/src/core-effects/Common/MatDefs/SSAO/ssao.j3md
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
MaterialDef SSAO {
|
||||||
|
|
||||||
|
MaterialParameters {
|
||||||
|
Int NumSamples
|
||||||
|
Int NumSamplesDepth
|
||||||
|
Texture2D Texture
|
||||||
|
Texture2D RandomMap
|
||||||
|
Texture2D Normals
|
||||||
|
Texture2D DepthTexture
|
||||||
|
Vector3 FrustumCorner
|
||||||
|
Float SampleRadius
|
||||||
|
Float Intensity
|
||||||
|
Float Scale
|
||||||
|
Float Bias
|
||||||
|
Vector2 FrustumNearFar
|
||||||
|
Vector2Array Samples
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL150: Common/MatDefs/Post/Post15.vert
|
||||||
|
FragmentShader GLSL150: Common/MatDefs/SSAO/ssao15.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
WorldViewMatrix
|
||||||
|
Resolution
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
RESOLVE_MS : NumSamples
|
||||||
|
RESOLVE_DEPTH_MS : NumSamplesDepth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL120: Common/MatDefs/Post/Post.vert
|
||||||
|
FragmentShader GLSL120: Common/MatDefs/SSAO/ssao.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
WorldViewMatrix
|
||||||
|
Resolution
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Technique FixedFunc {
|
||||||
|
}
|
||||||
|
}
|
96
engine/src/core-effects/Common/MatDefs/SSAO/ssao15.frag
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
#import "Common/ShaderLib/MultiSample.glsllib"
|
||||||
|
|
||||||
|
uniform COLORTEXTURE m_Texture;
|
||||||
|
uniform DEPTHTEXTURE m_DepthTexture;
|
||||||
|
|
||||||
|
uniform vec2 g_Resolution;
|
||||||
|
uniform vec2 m_FrustumNearFar;
|
||||||
|
uniform sampler2D m_Normals;
|
||||||
|
uniform sampler2D m_RandomMap;
|
||||||
|
uniform vec3 m_FrustumCorner;
|
||||||
|
uniform float m_SampleRadius;
|
||||||
|
uniform float m_Intensity;
|
||||||
|
uniform float m_Scale;
|
||||||
|
uniform float m_Bias;
|
||||||
|
uniform vec2[4] m_Samples;
|
||||||
|
|
||||||
|
in vec2 texCoord;
|
||||||
|
|
||||||
|
float depthv;
|
||||||
|
|
||||||
|
vec3 getPosition(in vec2 uv){
|
||||||
|
//Reconstruction from depth
|
||||||
|
depthv =getDepth(m_DepthTexture,uv).r;
|
||||||
|
float depth= (2.0 * m_FrustumNearFar.x) / (m_FrustumNearFar.y + m_FrustumNearFar.x - depthv* (m_FrustumNearFar.y-m_FrustumNearFar.x));
|
||||||
|
|
||||||
|
//one frustum corner method
|
||||||
|
float x = mix(-m_FrustumCorner.x, m_FrustumCorner.x, uv.x);
|
||||||
|
float y = mix(-m_FrustumCorner.y, m_FrustumCorner.y, uv.y);
|
||||||
|
|
||||||
|
return depth* vec3(x, y, m_FrustumCorner.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 getNormal(in vec2 uv){
|
||||||
|
return normalize(texture2D(m_Normals, uv).xyz * 2.0 - 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 getRandom(in vec2 uv){
|
||||||
|
//float rand=(fract(uv.x*(g_Resolution.x/2.0))*0.25)+(fract(uv.y*(g_Resolution.y/2.0))*0.5);
|
||||||
|
vec4 rand=texture2D(m_RandomMap,g_Resolution * uv / 128.0 * 3.0)*2.0 -1.0;
|
||||||
|
|
||||||
|
return normalize(rand.xy);
|
||||||
|
}
|
||||||
|
|
||||||
|
float doAmbientOcclusion(in vec2 tc, in vec3 pos, in vec3 norm){
|
||||||
|
vec3 diff = getPosition(tc)- pos;
|
||||||
|
vec3 v = normalize(diff);
|
||||||
|
float d = length(diff) * m_Scale;
|
||||||
|
|
||||||
|
return max(0.0, dot(norm, v) - m_Bias) * ( 1.0/(1.0 + d) ) * m_Intensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec2 reflection(in vec2 v1,in vec2 v2){
|
||||||
|
vec2 result= 2.0 * dot(v2, v1) * v2;
|
||||||
|
result=v1-result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//const vec2 vec[4] = vec2[4](vec2(1.0,0.0), vec2(-1.0,0.0), vec2(0.0,1.0), vec2(0.0,-1.0));
|
||||||
|
void main(){
|
||||||
|
|
||||||
|
float result;
|
||||||
|
|
||||||
|
//vec2 vec[4] = { vec2(1.0, 0.0), vec2(-1.0, 0.0), vec2(0.0, 1.0), vec2(0.0, -1.0) };
|
||||||
|
vec3 position = getPosition(texCoord);
|
||||||
|
//optimization, do not calculate AO if depth is 1
|
||||||
|
if(depthv==1.0){
|
||||||
|
gl_FragColor=vec4(1.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vec3 normal = getNormal(texCoord);
|
||||||
|
vec2 rand = getRandom(texCoord);
|
||||||
|
|
||||||
|
float ao = 0.0;
|
||||||
|
float rad =m_SampleRadius / position.z;
|
||||||
|
|
||||||
|
|
||||||
|
int iterations = 4;
|
||||||
|
for (int j = 0; j < iterations; ++j){
|
||||||
|
vec2 coord1 = reflection(vec2(m_Samples[j]), rand) * vec2(rad,rad);
|
||||||
|
vec2 coord2 = vec2(coord1.x* 0.707 - coord1.y* 0.707, coord1.x* 0.707 + coord1.y* 0.707) ;
|
||||||
|
|
||||||
|
ao += doAmbientOcclusion(texCoord + coord1.xy * 0.25, position, normal);
|
||||||
|
ao += doAmbientOcclusion(texCoord + coord2 * 0.50, position, normal);
|
||||||
|
ao += doAmbientOcclusion(texCoord + coord1.xy * 0.75, position, normal);
|
||||||
|
ao += doAmbientOcclusion(texCoord + coord2 * 1.00, position, normal);
|
||||||
|
|
||||||
|
}
|
||||||
|
ao /= float(iterations) * 4.0;
|
||||||
|
result = 1.0-ao;
|
||||||
|
|
||||||
|
gl_FragColor=vec4(result,result,result, 1.0);
|
||||||
|
//gl_FragColor=vec4(depthv,depthv,depthv, 1.0);
|
||||||
|
|
||||||
|
}
|
159
engine/src/core-effects/Common/MatDefs/SSAO/ssaoBlur.frag
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
uniform sampler2D m_Texture;
|
||||||
|
uniform sampler2D m_DepthTexture;
|
||||||
|
uniform sampler2D m_SSAOMap;
|
||||||
|
uniform vec2 g_Resolution;
|
||||||
|
uniform bool m_UseOnlyAo;
|
||||||
|
uniform bool m_UseAo;
|
||||||
|
uniform float m_XScale;
|
||||||
|
uniform float m_YScale;
|
||||||
|
uniform vec2 m_FrustumNearFar;
|
||||||
|
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
vec4 getColor(vec4 color){
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_ONLY_AO
|
||||||
|
return color;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_AO
|
||||||
|
return texture2D(m_Texture,texCoord)* color;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return texture2D(m_Texture,texCoord);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
float readDepth(in vec2 uv){
|
||||||
|
float depthv =texture2D(m_DepthTexture,uv).r;
|
||||||
|
return (2.0 * m_FrustumNearFar.x) / (m_FrustumNearFar.y + m_FrustumNearFar.x - depthv* (m_FrustumNearFar.y-m_FrustumNearFar.x));
|
||||||
|
}
|
||||||
|
|
||||||
|
const float epsilon = 0.005;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
const int kernelSize=7;
|
||||||
|
|
||||||
|
vec4 bilateralFilter() {
|
||||||
|
vec4 color = vec4(0.0);
|
||||||
|
|
||||||
|
vec2 sample;
|
||||||
|
float sum = 0.0;
|
||||||
|
float coefZ;
|
||||||
|
float Zp = readDepth(texCoord);
|
||||||
|
|
||||||
|
for(int i = -(kernelSize-1); i <= (kernelSize-1); i+=2) {
|
||||||
|
for(int j = -(kernelSize-1); j <= (kernelSize-1); j+=2) {
|
||||||
|
sample = texCoord + vec2(i,j) / g_Resolution;
|
||||||
|
float zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
sum += coefZ;
|
||||||
|
|
||||||
|
color += coefZ * texture2D(m_SSAOMap,sample);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return color / sum;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
vec4 convolutionFilter(){
|
||||||
|
vec4 sum = vec4(0.0);
|
||||||
|
|
||||||
|
float x = texCoord.x;
|
||||||
|
float y = texCoord.y;
|
||||||
|
|
||||||
|
float xScale = m_XScale;
|
||||||
|
float yScale = m_YScale;
|
||||||
|
|
||||||
|
float zsum = 1.0;
|
||||||
|
float Zp =readDepth(texCoord);
|
||||||
|
|
||||||
|
|
||||||
|
vec2 sample = vec2(x - 2.0 * xScale, y - 2.0 * yScale);
|
||||||
|
float zTmp =readDepth(sample);
|
||||||
|
float coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x - 0.0 * xScale, y - 2.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x + 2.0 * xScale, y - 2.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x - 1.0 * xScale, y - 1.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x + 1.0 * xScale, y - 1.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x - 2.0 * xScale, y - 0.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x + 2.0 * xScale, y - 0.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x - 1.0 * xScale, y + 1.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x + 1.0 * xScale, y + 1.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x - 2.0 * xScale, y + 2.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x - 0.0 * xScale, y + 2.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x + 2.0 * xScale, y + 2.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
|
||||||
|
return sum / zsum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
// float depth =texture2D(m_DepthTexture,uv).r;
|
||||||
|
|
||||||
|
gl_FragColor=getColor(convolutionFilter());
|
||||||
|
// gl_FragColor=getColor(bilateralFilter());
|
||||||
|
// gl_FragColor=texture2D(m_SSAOMap,texCoord);
|
||||||
|
|
||||||
|
}
|
57
engine/src/core-effects/Common/MatDefs/SSAO/ssaoBlur.j3md
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
MaterialDef SSAOBlur {
|
||||||
|
|
||||||
|
MaterialParameters {
|
||||||
|
Int NumSamples
|
||||||
|
Int NumSamplesDepth
|
||||||
|
Texture2D Texture
|
||||||
|
Texture2D SSAOMap
|
||||||
|
Texture2D DepthTexture
|
||||||
|
Vector2 FrustumNearFar
|
||||||
|
Boolean UseAo
|
||||||
|
Boolean UseOnlyAo
|
||||||
|
Float XScale
|
||||||
|
Float YScale
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL150: Common/MatDefs/Post/Post15.vert
|
||||||
|
FragmentShader GLSL150: Common/MatDefs/SSAO/ssaoBlur15.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
WorldViewMatrix
|
||||||
|
Resolution
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
USE_AO : UseAo
|
||||||
|
USE_ONLY_AO : UseOnlyAo
|
||||||
|
RESOLVE_MS : NumSamples
|
||||||
|
RESOLVE_DEPTH_MS : NumSamplesDepth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL120: Common/MatDefs/Post/Post.vert
|
||||||
|
FragmentShader GLSL120: Common/MatDefs/SSAO/ssaoBlur.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
WorldViewMatrix
|
||||||
|
Resolution
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
USE_AO : UseAo
|
||||||
|
USE_ONLY_AO : UseOnlyAo
|
||||||
|
RESOLVE_MS : NumSamples
|
||||||
|
RESOLVE_DEPTH_MS : NumSamplesDepth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Technique FixedFunc {
|
||||||
|
}
|
||||||
|
}
|
160
engine/src/core-effects/Common/MatDefs/SSAO/ssaoBlur15.frag
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
#import "Common/ShaderLib/MultiSample.glsllib"
|
||||||
|
|
||||||
|
uniform COLORTEXTURE m_Texture;
|
||||||
|
uniform DEPTHTEXTURE m_DepthTexture;
|
||||||
|
uniform sampler2D m_SSAOMap;
|
||||||
|
uniform vec2 g_Resolution;
|
||||||
|
uniform bool m_UseOnlyAo;
|
||||||
|
uniform bool m_UseAo;
|
||||||
|
uniform float m_XScale;
|
||||||
|
uniform float m_YScale;
|
||||||
|
uniform vec2 m_FrustumNearFar;
|
||||||
|
|
||||||
|
in vec2 texCoord;
|
||||||
|
|
||||||
|
vec4 getResult(vec4 color){
|
||||||
|
|
||||||
|
#ifdef USE_ONLY_AO
|
||||||
|
return color;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_AO
|
||||||
|
return getColor(m_Texture,texCoord)* color;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return getColor(m_Texture,texCoord);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
float readDepth(in vec2 uv){
|
||||||
|
float depthv =fetchTextureSample(m_DepthTexture,uv,0).r;
|
||||||
|
return (2.0 * m_FrustumNearFar.x) / (m_FrustumNearFar.y + m_FrustumNearFar.x - depthv* (m_FrustumNearFar.y-m_FrustumNearFar.x));
|
||||||
|
}
|
||||||
|
|
||||||
|
const float epsilon = 0.005;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
const int kernelSize=7;
|
||||||
|
|
||||||
|
vec4 bilateralFilter() {
|
||||||
|
vec4 color = vec4(0.0);
|
||||||
|
|
||||||
|
vec2 sample;
|
||||||
|
float sum = 0.0;
|
||||||
|
float coefZ;
|
||||||
|
float Zp = readDepth(texCoord);
|
||||||
|
|
||||||
|
for(int i = -(kernelSize-1); i <= (kernelSize-1); i+=2) {
|
||||||
|
for(int j = -(kernelSize-1); j <= (kernelSize-1); j+=2) {
|
||||||
|
sample = texCoord + vec2(i,j) / g_Resolution;
|
||||||
|
float zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
sum += coefZ;
|
||||||
|
|
||||||
|
color += coefZ * texture2D(m_SSAOMap,sample);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return color / sum;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
vec4 convolutionFilter(){
|
||||||
|
vec4 sum = vec4(0.0);
|
||||||
|
|
||||||
|
float x = texCoord.x;
|
||||||
|
float y = texCoord.y;
|
||||||
|
|
||||||
|
float xScale = m_XScale;
|
||||||
|
float yScale = m_YScale;
|
||||||
|
|
||||||
|
float zsum = 1.0;
|
||||||
|
float Zp =readDepth(texCoord);
|
||||||
|
|
||||||
|
|
||||||
|
vec2 sample = vec2(x - 2.0 * xScale, y - 2.0 * yScale);
|
||||||
|
float zTmp =readDepth(sample);
|
||||||
|
float coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x - 0.0 * xScale, y - 2.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x + 2.0 * xScale, y - 2.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x - 1.0 * xScale, y - 1.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x + 1.0 * xScale, y - 1.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x - 2.0 * xScale, y - 0.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x + 2.0 * xScale, y - 0.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x - 1.0 * xScale, y + 1.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x + 1.0 * xScale, y + 1.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x - 2.0 * xScale, y + 2.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x - 0.0 * xScale, y + 2.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
sample = vec2(x + 2.0 * xScale, y + 2.0 * yScale);
|
||||||
|
zTmp =readDepth(sample);
|
||||||
|
coefZ = 1.0 / (epsilon + abs(Zp - zTmp));
|
||||||
|
zsum += coefZ;
|
||||||
|
sum += coefZ* texture2D( m_SSAOMap, sample);
|
||||||
|
|
||||||
|
|
||||||
|
return sum / zsum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
// float depth =texture2D(m_DepthTexture,uv).r;
|
||||||
|
|
||||||
|
gl_FragColor=getResult(convolutionFilter());
|
||||||
|
// gl_FragColor=getResult(bilateralFilter());
|
||||||
|
// gl_FragColor=getColor(m_SSAOMap,texCoord);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
MaterialDef Simple Water {
|
||||||
|
|
||||||
|
MaterialParameters {
|
||||||
|
Texture2D water_reflection
|
||||||
|
Texture2D water_refraction
|
||||||
|
Texture2D water_depthmap
|
||||||
|
Texture2D water_normalmap
|
||||||
|
Texture2D water_dudvmap
|
||||||
|
Vector4 waterColor
|
||||||
|
Vector3 lightPos
|
||||||
|
Float time
|
||||||
|
Float waterDepth
|
||||||
|
Vector4 distortionScale
|
||||||
|
Vector4 distortionMix
|
||||||
|
Vector4 texScale
|
||||||
|
Vector2 FrustumNearFar
|
||||||
|
Float waterTransparency
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL100: Common/MatDefs/Water/simple_water.vert
|
||||||
|
FragmentShader GLSL100: Common/MatDefs/Water/simple_water.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
WorldViewMatrix
|
||||||
|
Resolution
|
||||||
|
CameraPosition
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique FixedFunc {
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 39 KiB |
BIN
engine/src/core-effects/Common/MatDefs/Water/Textures/foam.jpg
Normal file
After Width: | Height: | Size: 64 KiB |
BIN
engine/src/core-effects/Common/MatDefs/Water/Textures/foam2.jpg
Normal file
After Width: | Height: | Size: 79 KiB |
BIN
engine/src/core-effects/Common/MatDefs/Water/Textures/foam3.jpg
Normal file
After Width: | Height: | Size: 98 KiB |
After Width: | Height: | Size: 24 KiB |
402
engine/src/core-effects/Common/MatDefs/Water/Water.frag
Normal file
@ -0,0 +1,402 @@
|
|||||||
|
// Water pixel shader
|
||||||
|
// Copyright (C) JMonkeyEngine 3.0
|
||||||
|
// by Remy Bouquet (nehon) for JMonkeyEngine 3.0
|
||||||
|
// original HLSL version by Wojciech Toman 2009
|
||||||
|
|
||||||
|
uniform sampler2D m_HeightMap;
|
||||||
|
uniform sampler2D m_Texture;
|
||||||
|
uniform sampler2D m_DepthTexture;
|
||||||
|
uniform sampler2D m_NormalMap;
|
||||||
|
uniform sampler2D m_FoamMap;
|
||||||
|
uniform sampler2D m_CausticsMap;
|
||||||
|
uniform sampler2D m_ReflectionMap;
|
||||||
|
|
||||||
|
uniform mat4 m_ViewProjectionMatrixInverse;
|
||||||
|
uniform mat4 m_TextureProjMatrix;
|
||||||
|
uniform vec3 m_CameraPosition;
|
||||||
|
|
||||||
|
uniform float m_WaterHeight;
|
||||||
|
uniform float m_Time;
|
||||||
|
uniform float m_WaterTransparency;
|
||||||
|
uniform float m_NormalScale;
|
||||||
|
uniform float m_R0;
|
||||||
|
uniform float m_MaxAmplitude;
|
||||||
|
uniform vec3 m_LightDir;
|
||||||
|
uniform vec4 m_LightColor;
|
||||||
|
uniform float m_ShoreHardness;
|
||||||
|
uniform float m_FoamHardness;
|
||||||
|
uniform float m_RefractionStrength;
|
||||||
|
uniform vec3 m_FoamExistence;
|
||||||
|
uniform vec3 m_ColorExtinction;
|
||||||
|
uniform float m_Shininess;
|
||||||
|
uniform vec4 m_WaterColor;
|
||||||
|
uniform vec4 m_DeepWaterColor;
|
||||||
|
uniform vec2 m_WindDirection;
|
||||||
|
uniform float m_SunScale;
|
||||||
|
uniform float m_WaveScale;
|
||||||
|
uniform float m_UnderWaterFogDistance;
|
||||||
|
uniform float m_CausticsIntensity;
|
||||||
|
|
||||||
|
vec2 scale = vec2(m_WaveScale, m_WaveScale);
|
||||||
|
float refractionScale = m_WaveScale;
|
||||||
|
|
||||||
|
// Modifies 4 sampled normals. Increase first values to have more
|
||||||
|
// smaller "waves" or last to have more bigger "waves"
|
||||||
|
const vec4 normalModifier = vec4(3.0, 2.0, 4.0, 10.0);
|
||||||
|
// Strength of displacement along normal.
|
||||||
|
// Strength of displacement along normal.
|
||||||
|
uniform float m_ReflectionDisplace;
|
||||||
|
// Water transparency along eye vector.
|
||||||
|
const float visibility = 3.0;
|
||||||
|
// foam intensity
|
||||||
|
uniform float m_FoamIntensity ;
|
||||||
|
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
mat3 MatrixInverse(in mat3 inMatrix){
|
||||||
|
float det = dot(cross(inMatrix[0], inMatrix[1]), inMatrix[2]);
|
||||||
|
mat3 T = transpose(inMatrix);
|
||||||
|
return mat3(cross(T[1], T[2]),
|
||||||
|
cross(T[2], T[0]),
|
||||||
|
cross(T[0], T[1])) / det;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mat3 computeTangentFrame(in vec3 N, in vec3 P, in vec2 UV) {
|
||||||
|
vec3 dp1 = dFdx(P);
|
||||||
|
vec3 dp2 = dFdy(P);
|
||||||
|
vec2 duv1 = dFdx(UV);
|
||||||
|
vec2 duv2 = dFdy(UV);
|
||||||
|
|
||||||
|
// solve the linear system
|
||||||
|
mat3 M = mat3(dp1, dp2, cross(dp1, dp2));
|
||||||
|
//vec3 dp1xdp2 = cross(dp1, dp2);
|
||||||
|
mat3 inverseM = MatrixInverse(M);
|
||||||
|
//mat2x3 inverseM = mat2x3(cross(dp2, dp1xdp2), cross(dp1xdp2, dp1));
|
||||||
|
|
||||||
|
vec3 T = inverseM * vec3(duv1.x, duv2.x, 0.0);
|
||||||
|
vec3 B = inverseM * vec3(duv1.y, duv2.y, 0.0);
|
||||||
|
|
||||||
|
//vec3 T = inverseM * vec2(duv1.x, duv2.x);
|
||||||
|
//vec3 B = inverseM * vec2(duv1.y, duv2.y);
|
||||||
|
|
||||||
|
// construct tangent frame
|
||||||
|
float maxLength = max(length(T), length(B));
|
||||||
|
T = T / maxLength;
|
||||||
|
B = B / maxLength;
|
||||||
|
|
||||||
|
//vec3 tangent = normalize(T);
|
||||||
|
//vec3 binormal = normalize(B);
|
||||||
|
|
||||||
|
return mat3(T, B, N);
|
||||||
|
}
|
||||||
|
|
||||||
|
float saturate(in float val){
|
||||||
|
return clamp(val,0.0,1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 saturate(in vec3 val){
|
||||||
|
return clamp(val,vec3(0.0),vec3(1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec3 getPosition(in float depth, in vec2 uv){
|
||||||
|
vec4 pos = vec4(uv, depth, 1.0) * 2.0 - 1.0;
|
||||||
|
pos = m_ViewProjectionMatrixInverse * pos;
|
||||||
|
return pos.xyz / pos.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function calculating fresnel term.
|
||||||
|
// - normal - normalized normal vector
|
||||||
|
// - eyeVec - normalized eye vector
|
||||||
|
float fresnelTerm(in vec3 normal,in vec3 eyeVec){
|
||||||
|
float angle = 1.0 - saturate(dot(normal, eyeVec));
|
||||||
|
float fresnel = angle * angle;
|
||||||
|
fresnel = fresnel * fresnel;
|
||||||
|
fresnel = fresnel * angle;
|
||||||
|
return saturate(fresnel * (1.0 - saturate(m_R0)) + m_R0 - m_RefractionStrength);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 m_FrustumNearFar=vec2(1.0,m_UnderWaterFogDistance);
|
||||||
|
const float LOG2 = 1.442695;
|
||||||
|
|
||||||
|
vec4 underWater(){
|
||||||
|
|
||||||
|
|
||||||
|
float sceneDepth = texture2D(m_DepthTexture, texCoord).r;
|
||||||
|
vec3 color2 = texture2D(m_Texture, texCoord).rgb;
|
||||||
|
|
||||||
|
vec3 position = getPosition(sceneDepth, texCoord);
|
||||||
|
float level = m_WaterHeight;
|
||||||
|
|
||||||
|
vec3 eyeVec = position - m_CameraPosition;
|
||||||
|
|
||||||
|
// Find intersection with water surface
|
||||||
|
vec3 eyeVecNorm = normalize(eyeVec);
|
||||||
|
float t = (level - m_CameraPosition.y) / eyeVecNorm.y;
|
||||||
|
vec3 surfacePoint = m_CameraPosition + eyeVecNorm * t;
|
||||||
|
|
||||||
|
vec2 texC = vec2(0.0);
|
||||||
|
|
||||||
|
float cameraDepth = length(m_CameraPosition - surfacePoint);
|
||||||
|
texC = (surfacePoint.xz + eyeVecNorm.xz) * scale + m_Time * 0.03 * m_WindDirection;
|
||||||
|
float bias = texture2D(m_HeightMap, texC).r;
|
||||||
|
level += bias * m_MaxAmplitude;
|
||||||
|
t = (level - m_CameraPosition.y) / eyeVecNorm.y;
|
||||||
|
surfacePoint = m_CameraPosition + eyeVecNorm * t;
|
||||||
|
eyeVecNorm = normalize(m_CameraPosition - surfacePoint);
|
||||||
|
|
||||||
|
// Find normal of water surface
|
||||||
|
float normal1 = texture2D(m_HeightMap, (texC + vec2(-1.0, 0.0) / 256.0)).r;
|
||||||
|
float normal2 = texture2D(m_HeightMap, (texC + vec2(1.0, 0.0) / 256.0)).r;
|
||||||
|
float normal3 = texture2D(m_HeightMap, (texC + vec2(0.0, -1.0) / 256.0)).r;
|
||||||
|
float normal4 = texture2D(m_HeightMap, (texC + vec2(0.0, 1.0) / 256.0)).r;
|
||||||
|
|
||||||
|
vec3 myNormal = normalize(vec3((normal1 - normal2) * m_MaxAmplitude,m_NormalScale,(normal3 - normal4) * m_MaxAmplitude));
|
||||||
|
vec3 normal = myNormal*-1.0;
|
||||||
|
float fresnel = fresnelTerm(normal, eyeVecNorm);
|
||||||
|
|
||||||
|
vec3 refraction = color2;
|
||||||
|
#ifdef ENABLE_REFRACTION
|
||||||
|
texC = texCoord.xy *sin (fresnel+1.0);
|
||||||
|
refraction = texture2D(m_Texture, texC).rgb;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float waterCol = saturate(length(m_LightColor.rgb) / m_SunScale);
|
||||||
|
refraction = mix(mix(refraction, m_DeepWaterColor.rgb * waterCol, m_WaterTransparency), m_WaterColor.rgb* waterCol,m_WaterTransparency);
|
||||||
|
|
||||||
|
vec3 foam = vec3(0.0);
|
||||||
|
#ifdef ENABLE_FOAM
|
||||||
|
texC = (surfacePoint.xz + eyeVecNorm.xz * 0.1) * 0.05 + m_Time * 0.05 * m_WindDirection + sin(m_Time * 0.001 + position.x) * 0.005;
|
||||||
|
vec2 texCoord2 = (surfacePoint.xz + eyeVecNorm.xz * 0.1) * 0.05 + m_Time * 0.1 * m_WindDirection + sin(m_Time * 0.001 + position.z) * 0.005;
|
||||||
|
|
||||||
|
if(m_MaxAmplitude - m_FoamExistence.z> 0.0001){
|
||||||
|
foam += ((texture2D(m_FoamMap, texC) + texture2D(m_FoamMap, texCoord2)) * m_FoamIntensity * m_FoamIntensity * 0.3 *
|
||||||
|
saturate((level - (m_WaterHeight + m_FoamExistence.z)) / (m_MaxAmplitude - m_FoamExistence.z))).rgb;
|
||||||
|
}
|
||||||
|
foam *= m_LightColor.rgb;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vec3 specular = vec3(0.0);
|
||||||
|
vec3 color ;
|
||||||
|
float fogFactor;
|
||||||
|
|
||||||
|
if(position.y>level){
|
||||||
|
#ifdef ENABLE_SPECULAR
|
||||||
|
if(step(0.9999,sceneDepth)==1.0){
|
||||||
|
vec3 lightDir=normalize(m_LightDir);
|
||||||
|
vec3 mirrorEye = (2.0 * dot(eyeVecNorm, normal) * normal - eyeVecNorm);
|
||||||
|
float dotSpec = saturate(dot(mirrorEye.xyz, -lightDir) * 0.5 + 0.5);
|
||||||
|
specular = vec3((1.0 - fresnel) * saturate(-lightDir.y) * ((pow(dotSpec, 512.0)) * (m_Shininess * 1.8 + 0.2)));
|
||||||
|
specular += specular * 25.0 * saturate(m_Shininess - 0.05);
|
||||||
|
specular=specular * m_LightColor.rgb * 100.0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
float fogIntensity= 8.0 * m_WaterTransparency;
|
||||||
|
fogFactor = exp2( -fogIntensity * fogIntensity * cameraDepth * 0.03 * LOG2 );
|
||||||
|
fogFactor = clamp(fogFactor, 0.0, 1.0);
|
||||||
|
color =mix(m_DeepWaterColor.rgb,refraction,fogFactor);
|
||||||
|
specular=specular*fogFactor;
|
||||||
|
color = saturate(color + max(specular, foam ));
|
||||||
|
}else{
|
||||||
|
vec3 caustics = vec3(0.0);
|
||||||
|
#ifdef ENABLE_CAUSTICS
|
||||||
|
vec2 windDirection=m_WindDirection;
|
||||||
|
texC = (position.xz + eyeVecNorm.xz * 0.1) * 0.05 + m_Time * 0.05 * windDirection + sin(m_Time + position.x) * 0.01;
|
||||||
|
vec2 texCoord2 = (position.xz + eyeVecNorm.xz * 0.1) * 0.05 + m_Time * 0.05 * windDirection + sin(m_Time + position.z) * 0.01;
|
||||||
|
caustics += (texture2D(m_CausticsMap, texC)+ texture2D(m_CausticsMap, texCoord2)).rgb;
|
||||||
|
caustics=saturate(mix(m_WaterColor.rgb,caustics,m_CausticsIntensity));
|
||||||
|
color=mix(color2,caustics,m_CausticsIntensity);
|
||||||
|
#else
|
||||||
|
color=color2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float fogDepth= (2.0 * m_FrustumNearFar.x) / (m_FrustumNearFar.y + m_FrustumNearFar.x - sceneDepth* (m_FrustumNearFar.y-m_FrustumNearFar.x));
|
||||||
|
float fogIntensity= 18 * m_WaterTransparency;
|
||||||
|
fogFactor = exp2( -fogIntensity * fogIntensity * fogDepth * fogDepth * LOG2 );
|
||||||
|
fogFactor = clamp(fogFactor, 0.0, 1.0);
|
||||||
|
color =mix(m_DeepWaterColor.rgb,color,fogFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
return vec4(color, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
float sceneDepth = texture2D(m_DepthTexture, texCoord).r;
|
||||||
|
float isAtFarPlane = step(0.99998, sceneDepth);
|
||||||
|
|
||||||
|
vec3 color2 = texture2D(m_Texture, texCoord).rgb;
|
||||||
|
vec3 color = color2;
|
||||||
|
|
||||||
|
vec3 position = getPosition(sceneDepth,texCoord);
|
||||||
|
|
||||||
|
float level = m_WaterHeight;
|
||||||
|
|
||||||
|
// If we are underwater let's go to under water function
|
||||||
|
if(level >= m_CameraPosition.y){
|
||||||
|
gl_FragColor = underWater();
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#ifndef ENABLE_RIPPLES
|
||||||
|
// This optimization won't work on NVIDIA cards if ripples are enabled
|
||||||
|
if(position.y > level + m_MaxAmplitude + isAtFarPlane * 100.0){
|
||||||
|
gl_FragColor = vec4(color2, 1.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
vec3 eyeVec = position - m_CameraPosition;
|
||||||
|
float diff = level - position.y;
|
||||||
|
float cameraDepth = m_CameraPosition.y - position.y;
|
||||||
|
|
||||||
|
// Find intersection with water surface
|
||||||
|
vec3 eyeVecNorm = normalize(eyeVec);
|
||||||
|
float t = (level - m_CameraPosition.y) / eyeVecNorm.y;
|
||||||
|
vec3 surfacePoint = m_CameraPosition + eyeVecNorm * t;
|
||||||
|
|
||||||
|
vec2 texC;
|
||||||
|
int samples = 1;
|
||||||
|
#ifdef ENABLE_HQ_SHORELINE
|
||||||
|
samples = 10;
|
||||||
|
#endif
|
||||||
|
float biasFactor = 1.0/samples;
|
||||||
|
for (int i = 0; i < samples; i++){
|
||||||
|
texC = (surfacePoint.xz + eyeVecNorm.xz * biasFactor) * scale + m_Time * 0.03 * m_WindDirection;
|
||||||
|
|
||||||
|
float bias = texture2D(m_HeightMap, texC).r;
|
||||||
|
|
||||||
|
bias *= biasFactor;
|
||||||
|
level += bias * m_MaxAmplitude;
|
||||||
|
t = (level - m_CameraPosition.y) / eyeVecNorm.y;
|
||||||
|
surfacePoint = m_CameraPosition + eyeVecNorm * t;
|
||||||
|
}
|
||||||
|
|
||||||
|
float depth = length(position - surfacePoint);
|
||||||
|
float depth2 = surfacePoint.y - position.y;
|
||||||
|
|
||||||
|
// XXX: HACK ALERT: Increase water depth to infinity if at far plane
|
||||||
|
// Prevents "foam on horizon" issue
|
||||||
|
// For best results, replace the "100.0" below with the
|
||||||
|
// highest value in the m_ColorExtinction vec3
|
||||||
|
depth += isAtFarPlane * 100.0;
|
||||||
|
depth2 += isAtFarPlane * 100.0;
|
||||||
|
|
||||||
|
eyeVecNorm = normalize(m_CameraPosition - surfacePoint);
|
||||||
|
|
||||||
|
// Find normal of water surface
|
||||||
|
float normal1 = texture2D(m_HeightMap, (texC + vec2(-1.0, 0.0) / 256.0)).r;
|
||||||
|
float normal2 = texture2D(m_HeightMap, (texC + vec2(1.0, 0.0) / 256.0)).r;
|
||||||
|
float normal3 = texture2D(m_HeightMap, (texC + vec2(0.0, -1.0) / 256.0)).r;
|
||||||
|
float normal4 = texture2D(m_HeightMap, (texC + vec2(0.0, 1.0) / 256.0)).r;
|
||||||
|
|
||||||
|
vec3 myNormal = normalize(vec3((normal1 - normal2) * m_MaxAmplitude,m_NormalScale,(normal3 - normal4) * m_MaxAmplitude));
|
||||||
|
vec3 normal = vec3(0.0);
|
||||||
|
|
||||||
|
#ifdef ENABLE_RIPPLES
|
||||||
|
texC = surfacePoint.xz * 0.8 + m_WindDirection * m_Time* 1.6;
|
||||||
|
mat3 tangentFrame = computeTangentFrame(myNormal, eyeVecNorm, texC);
|
||||||
|
vec3 normal0a = normalize(tangentFrame*(2.0 * texture2D(m_NormalMap, texC).xyz - 1.0));
|
||||||
|
|
||||||
|
texC = surfacePoint.xz * 0.4 + m_WindDirection * m_Time* 0.8;
|
||||||
|
tangentFrame = computeTangentFrame(myNormal, eyeVecNorm, texC);
|
||||||
|
vec3 normal1a = normalize(tangentFrame*(2.0 * texture2D(m_NormalMap, texC).xyz - 1.0));
|
||||||
|
|
||||||
|
texC = surfacePoint.xz * 0.2 + m_WindDirection * m_Time * 0.4;
|
||||||
|
tangentFrame = computeTangentFrame(myNormal, eyeVecNorm, texC);
|
||||||
|
vec3 normal2a = normalize(tangentFrame*(2.0 * texture2D(m_NormalMap, texC).xyz - 1.0));
|
||||||
|
|
||||||
|
texC = surfacePoint.xz * 0.1 + m_WindDirection * m_Time * 0.2;
|
||||||
|
tangentFrame = computeTangentFrame(myNormal, eyeVecNorm, texC);
|
||||||
|
vec3 normal3a = normalize(tangentFrame*(2.0 * texture2D(m_NormalMap, texC).xyz - 1.0));
|
||||||
|
|
||||||
|
normal = normalize(normal0a * normalModifier.x + normal1a * normalModifier.y +normal2a * normalModifier.z + normal3a * normalModifier.w);
|
||||||
|
// XXX: Here's another way to fix the terrain edge issue,
|
||||||
|
// But it requires GLSL 1.3 and still looks kinda incorrect
|
||||||
|
// around edges
|
||||||
|
// To make the shader 1.2 compatible we use a trick :
|
||||||
|
// we clamp the x value of the normal and compare it to it's former value instead of using isnan.
|
||||||
|
normal = clamp(normal.x,0.0,1.0)!=normal.x ? myNormal : normal;
|
||||||
|
//if (position.y > level){
|
||||||
|
// gl_FragColor = vec4(color2 + normal*0.0001, 1.0);
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
#else
|
||||||
|
normal = myNormal;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec3 refraction = color2;
|
||||||
|
#ifdef ENABLE_REFRACTION
|
||||||
|
texC = texCoord.xy;
|
||||||
|
texC += sin(m_Time*1.8 + 3.0 * abs(position.y)) * (refractionScale * min(depth2, 1.0));
|
||||||
|
refraction = texture2D(m_Texture, texC).rgb;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec3 waterPosition = surfacePoint.xyz;
|
||||||
|
waterPosition.y -= (level - m_WaterHeight);
|
||||||
|
vec4 texCoordProj = m_TextureProjMatrix * vec4(waterPosition, 1.0);
|
||||||
|
|
||||||
|
texCoordProj.x = texCoordProj.x + m_ReflectionDisplace * normal.x;
|
||||||
|
texCoordProj.z = texCoordProj.z + m_ReflectionDisplace * normal.z;
|
||||||
|
texCoordProj /= texCoordProj.w;
|
||||||
|
texCoordProj.y = 1.0 - texCoordProj.y;
|
||||||
|
|
||||||
|
vec3 reflection = texture2D(m_ReflectionMap, texCoordProj.xy).rgb;
|
||||||
|
|
||||||
|
float fresnel = fresnelTerm(normal, eyeVecNorm);
|
||||||
|
|
||||||
|
float depthN = depth * m_WaterTransparency;
|
||||||
|
float waterCol = saturate(length(m_LightColor.rgb) / m_SunScale);
|
||||||
|
refraction = mix(mix(refraction, m_WaterColor.rgb * waterCol, saturate(depthN / visibility)),
|
||||||
|
m_DeepWaterColor.rgb * waterCol, saturate(depth2 / m_ColorExtinction));
|
||||||
|
|
||||||
|
vec3 foam = vec3(0.0);
|
||||||
|
#ifdef ENABLE_FOAM
|
||||||
|
texC = (surfacePoint.xz + eyeVecNorm.xz * 0.1) * 0.05 + m_Time * 0.05 * m_WindDirection + sin(m_Time * 0.001 + position.x) * 0.005;
|
||||||
|
vec2 texCoord2 = (surfacePoint.xz + eyeVecNorm.xz * 0.1) * 0.05 + m_Time * 0.1 * m_WindDirection + sin(m_Time * 0.001 + position.z) * 0.005;
|
||||||
|
|
||||||
|
if(depth2 < m_FoamExistence.x){
|
||||||
|
foam = (texture2D(m_FoamMap, texC).r + texture2D(m_FoamMap, texCoord2)).rgb * m_FoamIntensity;
|
||||||
|
}else if(depth2 < m_FoamExistence.y){
|
||||||
|
foam = mix((texture2D(m_FoamMap, texC) + texture2D(m_FoamMap, texCoord2)) * m_FoamIntensity, vec4(0.0),
|
||||||
|
(depth2 - m_FoamExistence.x) / (m_FoamExistence.y - m_FoamExistence.x)).rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_MaxAmplitude - m_FoamExistence.z > 0.0001){
|
||||||
|
foam += ((texture2D(m_FoamMap, texC) + texture2D(m_FoamMap, texCoord2)) * m_FoamIntensity * m_FoamIntensity * 0.3 *
|
||||||
|
saturate((level - (m_WaterHeight + m_FoamExistence.z)) / (m_MaxAmplitude - m_FoamExistence.z))).rgb;
|
||||||
|
}
|
||||||
|
foam *= m_LightColor.rgb;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec3 specular =vec3(0.0);
|
||||||
|
#ifdef ENABLE_SPECULAR
|
||||||
|
vec3 lightDir=normalize(m_LightDir);
|
||||||
|
vec3 mirrorEye = (2.0 * dot(eyeVecNorm, normal) * normal - eyeVecNorm);
|
||||||
|
float dotSpec = saturate(dot(mirrorEye.xyz, -lightDir) * 0.5 + 0.5);
|
||||||
|
specular = vec3((1.0 - fresnel) * saturate(-lightDir.y) * ((pow(dotSpec, 512.0)) * (m_Shininess * 1.8 + 0.2)));
|
||||||
|
specular += specular * 25.0 * saturate(m_Shininess - 0.05);
|
||||||
|
//foam does not shine
|
||||||
|
specular=specular * m_LightColor.rgb - (5.0 * foam);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
color = mix(refraction, reflection, fresnel);
|
||||||
|
color = mix(refraction, color, saturate(depth * m_ShoreHardness));
|
||||||
|
color = saturate(color + max(specular, foam ));
|
||||||
|
color = mix(refraction, color, saturate(depth* m_FoamHardness));
|
||||||
|
|
||||||
|
|
||||||
|
// XXX: HACK ALERT:
|
||||||
|
// We trick the GeForces to think they have
|
||||||
|
// to calculate the derivatives for all these pixels by using step()!
|
||||||
|
// That way we won't get pixels around the edges of the terrain,
|
||||||
|
// Where the derivatives are undefined
|
||||||
|
if(position.y > level){
|
||||||
|
color = color2;
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_FragColor = vec4(color,1.0);
|
||||||
|
|
||||||
|
}
|
90
engine/src/core-effects/Common/MatDefs/Water/Water.j3md
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
MaterialDef Advanced Water {
|
||||||
|
|
||||||
|
MaterialParameters {
|
||||||
|
Int NumSamples
|
||||||
|
Int NumSamplesDepth
|
||||||
|
Texture2D FoamMap
|
||||||
|
Texture2D CausticsMap
|
||||||
|
Texture2D NormalMap
|
||||||
|
Texture2D ReflectionMap
|
||||||
|
Texture2D HeightMap
|
||||||
|
Texture2D Texture
|
||||||
|
Texture2D DepthTexture
|
||||||
|
Vector3 CameraPosition
|
||||||
|
Float Time
|
||||||
|
Vector3 frustumCorner
|
||||||
|
Matrix4 TextureProjMatrix
|
||||||
|
Matrix4 ViewProjectionMatrixInverse
|
||||||
|
Float WaterHeight
|
||||||
|
Vector3 LightDir
|
||||||
|
Float WaterTransparency
|
||||||
|
Float NormalScale
|
||||||
|
Float R0
|
||||||
|
Float MaxAmplitude
|
||||||
|
Color LightColor
|
||||||
|
Float ShoreHardness
|
||||||
|
Float FoamHardness
|
||||||
|
Float RefractionStrength
|
||||||
|
Float WaveScale
|
||||||
|
Vector3 FoamExistence
|
||||||
|
Float SunScale
|
||||||
|
Vector3 ColorExtinction
|
||||||
|
Float Shininess
|
||||||
|
Color WaterColor
|
||||||
|
Color DeepWaterColor
|
||||||
|
Vector2 WindDirection
|
||||||
|
Float ReflectionDisplace
|
||||||
|
Float FoamIntensity
|
||||||
|
Float CausticsIntensity
|
||||||
|
Float UnderWaterFogDistance
|
||||||
|
|
||||||
|
Boolean UseRipples
|
||||||
|
Boolean UseHQShoreline
|
||||||
|
Boolean UseSpecular
|
||||||
|
Boolean UseFoam
|
||||||
|
Boolean UseCaustics
|
||||||
|
Boolean UseRefraction
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL150 : Common/MatDefs/Post/Post15.vert
|
||||||
|
FragmentShader GLSL150 : Common/MatDefs/Water/Water15.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
RESOLVE_MS : NumSamples
|
||||||
|
RESOLVE_DEPTH_MS : NumSamplesDepth
|
||||||
|
ENABLE_RIPPLES : UseRipples
|
||||||
|
ENABLE_HQ_SHORELINE : UseHQShoreline
|
||||||
|
ENABLE_SPECULAR : UseSpecular
|
||||||
|
ENABLE_FOAM : UseFoam
|
||||||
|
ENABLE_CAUSTICS : UseCaustics
|
||||||
|
ENABLE_REFRACTION : UseRefraction
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
VertexShader GLSL100 : Common/MatDefs/Post/Post.vert
|
||||||
|
FragmentShader GLSL120 : Common/MatDefs/Water/Water.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
}
|
||||||
|
Defines {
|
||||||
|
ENABLE_RIPPLES : UseRipples
|
||||||
|
ENABLE_HQ_SHORELINE : UseHQShoreline
|
||||||
|
ENABLE_SPECULAR : UseSpecular
|
||||||
|
ENABLE_FOAM : UseFoam
|
||||||
|
ENABLE_CAUSTICS : UseCaustics
|
||||||
|
ENABLE_REFRACTION : UseRefraction
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique FixedFunc {
|
||||||
|
}
|
||||||
|
}
|
419
engine/src/core-effects/Common/MatDefs/Water/Water15.frag
Normal file
@ -0,0 +1,419 @@
|
|||||||
|
#import "Common/ShaderLib/MultiSample.glsllib"
|
||||||
|
|
||||||
|
// Water pixel shader
|
||||||
|
// Copyright (C) JMonkeyEngine 3.0
|
||||||
|
// by Remy Bouquet (nehon) for JMonkeyEngine 3.0
|
||||||
|
// original HLSL version by Wojciech Toman 2009
|
||||||
|
|
||||||
|
uniform COLORTEXTURE m_Texture;
|
||||||
|
uniform DEPTHTEXTURE m_DepthTexture;
|
||||||
|
|
||||||
|
|
||||||
|
uniform sampler2D m_HeightMap;
|
||||||
|
uniform sampler2D m_NormalMap;
|
||||||
|
uniform sampler2D m_FoamMap;
|
||||||
|
uniform sampler2D m_CausticsMap;
|
||||||
|
uniform sampler2D m_ReflectionMap;
|
||||||
|
|
||||||
|
uniform mat4 m_ViewProjectionMatrixInverse;
|
||||||
|
uniform mat4 m_TextureProjMatrix;
|
||||||
|
uniform vec3 m_CameraPosition;
|
||||||
|
|
||||||
|
uniform float m_WaterHeight;
|
||||||
|
uniform float m_Time;
|
||||||
|
uniform float m_WaterTransparency;
|
||||||
|
uniform float m_NormalScale;
|
||||||
|
uniform float m_R0;
|
||||||
|
uniform float m_MaxAmplitude;
|
||||||
|
uniform vec3 m_LightDir;
|
||||||
|
uniform vec4 m_LightColor;
|
||||||
|
uniform float m_ShoreHardness;
|
||||||
|
uniform float m_FoamHardness;
|
||||||
|
uniform float m_RefractionStrength;
|
||||||
|
uniform vec3 m_FoamExistence;
|
||||||
|
uniform vec3 m_ColorExtinction;
|
||||||
|
uniform float m_Shininess;
|
||||||
|
uniform vec4 m_WaterColor;
|
||||||
|
uniform vec4 m_DeepWaterColor;
|
||||||
|
uniform vec2 m_WindDirection;
|
||||||
|
uniform float m_SunScale;
|
||||||
|
uniform float m_WaveScale;
|
||||||
|
uniform float m_UnderWaterFogDistance;
|
||||||
|
uniform float m_CausticsIntensity;
|
||||||
|
|
||||||
|
|
||||||
|
vec2 scale = vec2(m_WaveScale, m_WaveScale);
|
||||||
|
float refractionScale = m_WaveScale;
|
||||||
|
|
||||||
|
// Modifies 4 sampled normals. Increase first values to have more
|
||||||
|
// smaller "waves" or last to have more bigger "waves"
|
||||||
|
const vec4 normalModifier = vec4(3.0, 2.0, 4.0, 10.0);
|
||||||
|
// Strength of displacement along normal.
|
||||||
|
uniform float m_ReflectionDisplace;
|
||||||
|
// Water transparency along eye vector.
|
||||||
|
const float visibility = 3.0;
|
||||||
|
// foam intensity
|
||||||
|
uniform float m_FoamIntensity ;
|
||||||
|
|
||||||
|
in vec2 texCoord;
|
||||||
|
out vec4 outFragColor;
|
||||||
|
|
||||||
|
mat3 MatrixInverse(in mat3 inMatrix){
|
||||||
|
float det = dot(cross(inMatrix[0], inMatrix[1]), inMatrix[2]);
|
||||||
|
mat3 T = transpose(inMatrix);
|
||||||
|
return mat3(cross(T[1], T[2]),
|
||||||
|
cross(T[2], T[0]),
|
||||||
|
cross(T[0], T[1])) / det;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mat3 computeTangentFrame(in vec3 N, in vec3 P, in vec2 UV) {
|
||||||
|
vec3 dp1 = dFdx(P);
|
||||||
|
vec3 dp2 = dFdy(P);
|
||||||
|
vec2 duv1 = dFdx(UV);
|
||||||
|
vec2 duv2 = dFdy(UV);
|
||||||
|
|
||||||
|
// solve the linear system
|
||||||
|
vec3 dp1xdp2 = cross(dp1, dp2);
|
||||||
|
mat2x3 inverseM = mat2x3(cross(dp2, dp1xdp2), cross(dp1xdp2, dp1));
|
||||||
|
|
||||||
|
vec3 T = inverseM * vec2(duv1.x, duv2.x);
|
||||||
|
vec3 B = inverseM * vec2(duv1.y, duv2.y);
|
||||||
|
|
||||||
|
// construct tangent frame
|
||||||
|
float maxLength = max(length(T), length(B));
|
||||||
|
T = T / maxLength;
|
||||||
|
B = B / maxLength;
|
||||||
|
|
||||||
|
return mat3(T, B, N);
|
||||||
|
}
|
||||||
|
|
||||||
|
float saturate(in float val){
|
||||||
|
return clamp(val,0.0,1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 saturate(in vec3 val){
|
||||||
|
return clamp(val,vec3(0.0),vec3(1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 getPosition(in float depth, in vec2 uv){
|
||||||
|
vec4 pos = vec4(uv, depth, 1.0) * 2.0 - 1.0;
|
||||||
|
pos = m_ViewProjectionMatrixInverse * pos;
|
||||||
|
return pos.xyz / pos.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function calculating fresnel term.
|
||||||
|
// - normal - normalized normal vector
|
||||||
|
// - eyeVec - normalized eye vector
|
||||||
|
float fresnelTerm(in vec3 normal,in vec3 eyeVec){
|
||||||
|
float angle = 1.0 - max(0.0, dot(normal, eyeVec));
|
||||||
|
float fresnel = angle * angle;
|
||||||
|
fresnel = fresnel * fresnel;
|
||||||
|
fresnel = fresnel * angle;
|
||||||
|
return saturate(fresnel * (1.0 - saturate(m_R0)) + m_R0 - m_RefractionStrength);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 m_FrustumNearFar=vec2(1.0,m_UnderWaterFogDistance);
|
||||||
|
const float LOG2 = 1.442695;
|
||||||
|
|
||||||
|
vec4 underWater(int sampleNum){
|
||||||
|
|
||||||
|
|
||||||
|
float sceneDepth = fetchTextureSample(m_DepthTexture, texCoord, sampleNum).r;
|
||||||
|
vec3 color2 = fetchTextureSample(m_Texture, texCoord, sampleNum).rgb;
|
||||||
|
|
||||||
|
vec3 position = getPosition(sceneDepth, texCoord);
|
||||||
|
float level = m_WaterHeight;
|
||||||
|
|
||||||
|
vec3 eyeVec = position - m_CameraPosition;
|
||||||
|
|
||||||
|
// Find intersection with water surface
|
||||||
|
vec3 eyeVecNorm = normalize(eyeVec);
|
||||||
|
float t = (level - m_CameraPosition.y) / eyeVecNorm.y;
|
||||||
|
vec3 surfacePoint = m_CameraPosition + eyeVecNorm * t;
|
||||||
|
|
||||||
|
vec2 texC = vec2(0.0);
|
||||||
|
|
||||||
|
float cameraDepth = length(m_CameraPosition - surfacePoint);
|
||||||
|
texC = (surfacePoint.xz + eyeVecNorm.xz) * scale + m_Time * 0.03 * m_WindDirection;
|
||||||
|
float bias = texture(m_HeightMap, texC).r;
|
||||||
|
level += bias * m_MaxAmplitude;
|
||||||
|
t = (level - m_CameraPosition.y) / eyeVecNorm.y;
|
||||||
|
surfacePoint = m_CameraPosition + eyeVecNorm * t;
|
||||||
|
eyeVecNorm = normalize(m_CameraPosition - surfacePoint);
|
||||||
|
|
||||||
|
// Find normal of water surface
|
||||||
|
float normal1 = textureOffset(m_HeightMap, texC, ivec2(-1.0, 0.0)).r;
|
||||||
|
float normal2 = textureOffset(m_HeightMap, texC, ivec2( 1.0, 0.0)).r;
|
||||||
|
float normal3 = textureOffset(m_HeightMap, texC, ivec2( 0.0, -1.0)).r;
|
||||||
|
float normal4 = textureOffset(m_HeightMap, texC, ivec2( 0.0, 1.0)).r;
|
||||||
|
|
||||||
|
vec3 myNormal = normalize(vec3((normal1 - normal2) * m_MaxAmplitude,m_NormalScale,(normal3 - normal4) * m_MaxAmplitude));
|
||||||
|
vec3 normal = myNormal*-1.0;
|
||||||
|
float fresnel = fresnelTerm(normal, eyeVecNorm);
|
||||||
|
|
||||||
|
vec3 refraction = color2;
|
||||||
|
#ifdef ENABLE_REFRACTION
|
||||||
|
texC = texCoord.xy *sin (fresnel+1.0);
|
||||||
|
#ifdef RESOLVE_MS
|
||||||
|
ivec2 iTexC = ivec2(texC * textureSize(m_Texture));
|
||||||
|
refraction = texelFetch(m_Texture, iTexC, sampleNum).rgb;
|
||||||
|
#else
|
||||||
|
ivec2 iTexC = ivec2(texC * textureSize(m_Texture, 0));
|
||||||
|
refraction = texelFetch(m_Texture, iTexC, 0).rgb;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float waterCol = saturate(length(m_LightColor.rgb) / m_SunScale);
|
||||||
|
refraction = mix(mix(refraction, m_DeepWaterColor.rgb * waterCol, m_WaterTransparency), m_WaterColor.rgb* waterCol,m_WaterTransparency);
|
||||||
|
|
||||||
|
vec3 foam = vec3(0.0);
|
||||||
|
#ifdef ENABLE_FOAM
|
||||||
|
texC = (surfacePoint.xz + eyeVecNorm.xz * 0.1) * 0.05 + m_Time * 0.05 * m_WindDirection + sin(m_Time * 0.001 + position.x) * 0.005;
|
||||||
|
vec2 texCoord2 = (surfacePoint.xz + eyeVecNorm.xz * 0.1) * 0.05 + m_Time * 0.1 * m_WindDirection + sin(m_Time * 0.001 + position.z) * 0.005;
|
||||||
|
|
||||||
|
if(m_MaxAmplitude - m_FoamExistence.z> 0.0001){
|
||||||
|
foam += ((texture2D(m_FoamMap, texC) + texture2D(m_FoamMap, texCoord2)) * m_FoamIntensity * m_FoamIntensity * 0.3 *
|
||||||
|
saturate((level - (m_WaterHeight + m_FoamExistence.z)) / (m_MaxAmplitude - m_FoamExistence.z))).rgb;
|
||||||
|
}
|
||||||
|
foam *= m_LightColor.rgb;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vec3 specular = vec3(0.0);
|
||||||
|
vec3 color ;
|
||||||
|
float fogFactor;
|
||||||
|
|
||||||
|
if(position.y>level){
|
||||||
|
#ifdef ENABLE_SPECULAR
|
||||||
|
if(step(0.9999,sceneDepth)==1.0){
|
||||||
|
vec3 lightDir=normalize(m_LightDir);
|
||||||
|
vec3 mirrorEye = (2.0 * dot(eyeVecNorm, normal) * normal - eyeVecNorm);
|
||||||
|
float dotSpec = saturate(dot(mirrorEye.xyz, -lightDir) * 0.5 + 0.5);
|
||||||
|
specular = vec3((1.0 - fresnel) * saturate(-lightDir.y) * ((pow(dotSpec, 512.0)) * (m_Shininess * 1.8 + 0.2)));
|
||||||
|
specular += specular * 25.0 * saturate(m_Shininess - 0.05);
|
||||||
|
specular=specular * m_LightColor.rgb * 100.0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
float fogIntensity= 8.0 * m_WaterTransparency;
|
||||||
|
fogFactor = exp2( -fogIntensity * fogIntensity * cameraDepth * 0.03 * LOG2 );
|
||||||
|
fogFactor = clamp(fogFactor, 0.0, 1.0);
|
||||||
|
color =mix(m_DeepWaterColor.rgb,refraction,fogFactor);
|
||||||
|
specular=specular*fogFactor;
|
||||||
|
color = saturate(color + max(specular, foam ));
|
||||||
|
}else{
|
||||||
|
vec3 caustics = vec3(0.0);
|
||||||
|
#ifdef ENABLE_CAUSTICS
|
||||||
|
vec2 windDirection=m_WindDirection;
|
||||||
|
texC = (position.xz + eyeVecNorm.xz * 0.1) * 0.05 + m_Time * 0.05 * windDirection + sin(m_Time + position.x) * 0.01;
|
||||||
|
vec2 texCoord2 = (position.xz + eyeVecNorm.xz * 0.1) * 0.05 + m_Time * 0.05 * windDirection + sin(m_Time + position.z) * 0.01;
|
||||||
|
caustics += (texture2D(m_CausticsMap, texC)+ texture2D(m_CausticsMap, texCoord2)).rgb;
|
||||||
|
caustics=saturate(mix(m_WaterColor.rgb,caustics,m_CausticsIntensity));
|
||||||
|
color=mix(color2,caustics,m_CausticsIntensity);
|
||||||
|
#else
|
||||||
|
color=color2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float fogDepth= (2.0 * m_FrustumNearFar.x) / (m_FrustumNearFar.y + m_FrustumNearFar.x - sceneDepth* (m_FrustumNearFar.y-m_FrustumNearFar.x));
|
||||||
|
float fogIntensity= 18 * m_WaterTransparency;
|
||||||
|
fogFactor = exp2( -fogIntensity * fogIntensity * fogDepth * fogDepth * LOG2 );
|
||||||
|
fogFactor = clamp(fogFactor, 0.0, 1.0);
|
||||||
|
color =mix(m_DeepWaterColor.rgb,color,fogFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
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){
|
||||||
|
|
||||||
|
return underWater(sampleNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
float sceneDepth = fetchTextureSample(m_DepthTexture, texCoord, sampleNum).r;
|
||||||
|
vec3 color2 = fetchTextureSample(m_Texture, texCoord, sampleNum).rgb;
|
||||||
|
|
||||||
|
vec3 color = color2;
|
||||||
|
vec3 position = getPosition(sceneDepth, texCoord);
|
||||||
|
|
||||||
|
float level = m_WaterHeight;
|
||||||
|
|
||||||
|
float isAtFarPlane = step(0.99998, sceneDepth);
|
||||||
|
//#ifndef ENABLE_RIPPLES
|
||||||
|
// This optimization won't work on NVIDIA cards if ripples are enabled
|
||||||
|
if(position.y > level + m_MaxAmplitude + isAtFarPlane * 100.0){
|
||||||
|
|
||||||
|
return vec4(color2, 1.0);
|
||||||
|
}
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
vec3 eyeVec = position - m_CameraPosition;
|
||||||
|
float cameraDepth = m_CameraPosition.y - position.y;
|
||||||
|
|
||||||
|
// Find intersection with water surface
|
||||||
|
vec3 eyeVecNorm = normalize(eyeVec);
|
||||||
|
float t = (level - m_CameraPosition.y) / eyeVecNorm.y;
|
||||||
|
vec3 surfacePoint = m_CameraPosition + eyeVecNorm * t;
|
||||||
|
|
||||||
|
vec2 texC = vec2(0.0);
|
||||||
|
int samples = 1;
|
||||||
|
#ifdef ENABLE_HQ_SHORELINE
|
||||||
|
samples = 10;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float biasFactor = 1.0 / samples;
|
||||||
|
for (int i = 0; i < samples; i++){
|
||||||
|
texC = (surfacePoint.xz + eyeVecNorm.xz * biasFactor) * scale + m_Time * 0.03 * m_WindDirection;
|
||||||
|
|
||||||
|
float bias = texture(m_HeightMap, texC).r;
|
||||||
|
|
||||||
|
bias *= biasFactor;
|
||||||
|
level += bias * m_MaxAmplitude;
|
||||||
|
t = (level - m_CameraPosition.y) / eyeVecNorm.y;
|
||||||
|
surfacePoint = m_CameraPosition + eyeVecNorm * t;
|
||||||
|
}
|
||||||
|
|
||||||
|
float depth = length(position - surfacePoint);
|
||||||
|
float depth2 = surfacePoint.y - position.y;
|
||||||
|
|
||||||
|
// XXX: HACK ALERT: Increase water depth to infinity if at far plane
|
||||||
|
// Prevents "foam on horizon" issue
|
||||||
|
// For best results, replace the "100.0" below with the
|
||||||
|
// highest value in the m_ColorExtinction vec3
|
||||||
|
depth += isAtFarPlane * 100.0;
|
||||||
|
depth2 += isAtFarPlane * 100.0;
|
||||||
|
|
||||||
|
eyeVecNorm = normalize(m_CameraPosition - surfacePoint);
|
||||||
|
|
||||||
|
// Find normal of water surface
|
||||||
|
float normal1 = textureOffset(m_HeightMap, texC, ivec2(-1.0, 0.0)).r;
|
||||||
|
float normal2 = textureOffset(m_HeightMap, texC, ivec2( 1.0, 0.0)).r;
|
||||||
|
float normal3 = textureOffset(m_HeightMap, texC, ivec2( 0.0, -1.0)).r;
|
||||||
|
float normal4 = textureOffset(m_HeightMap, texC, ivec2( 0.0, 1.0)).r;
|
||||||
|
|
||||||
|
vec3 myNormal = normalize(vec3((normal1 - normal2) * m_MaxAmplitude,m_NormalScale,(normal3 - normal4) * m_MaxAmplitude));
|
||||||
|
vec3 normal = vec3(0.0);
|
||||||
|
|
||||||
|
#ifdef ENABLE_RIPPLES
|
||||||
|
texC = surfacePoint.xz * 0.8 + m_WindDirection * m_Time* 1.6;
|
||||||
|
mat3 tangentFrame = computeTangentFrame(myNormal, eyeVecNorm, texC);
|
||||||
|
vec3 normal0a = normalize(tangentFrame*(2.0 * texture(m_NormalMap, texC).xyz - 1.0));
|
||||||
|
|
||||||
|
texC = surfacePoint.xz * 0.4 + m_WindDirection * m_Time* 0.8;
|
||||||
|
tangentFrame = computeTangentFrame(myNormal, eyeVecNorm, texC);
|
||||||
|
vec3 normal1a = normalize(tangentFrame*(2.0 * texture(m_NormalMap, texC).xyz - 1.0));
|
||||||
|
|
||||||
|
texC = surfacePoint.xz * 0.2 + m_WindDirection * m_Time * 0.4;
|
||||||
|
tangentFrame = computeTangentFrame(myNormal, eyeVecNorm, texC);
|
||||||
|
vec3 normal2a = normalize(tangentFrame*(2.0 * texture(m_NormalMap, texC).xyz - 1.0));
|
||||||
|
|
||||||
|
texC = surfacePoint.xz * 0.1 + m_WindDirection * m_Time * 0.2;
|
||||||
|
tangentFrame = computeTangentFrame(myNormal, eyeVecNorm, texC);
|
||||||
|
vec3 normal3a = normalize(tangentFrame*(2.0 * texture(m_NormalMap, texC).xyz - 1.0));
|
||||||
|
|
||||||
|
normal = normalize(normal0a * normalModifier.x + normal1a * normalModifier.y +normal2a * normalModifier.z + normal3a * normalModifier.w);
|
||||||
|
// XXX: Here's another way to fix the terrain edge issue,
|
||||||
|
// But it requires GLSL 1.3 and still looks kinda incorrect
|
||||||
|
// around edges
|
||||||
|
normal = isnan(normal.x) ? myNormal : normal;
|
||||||
|
//if (position.y > level){
|
||||||
|
// gl_FragColor = vec4(color2 + normal*0.0001, 1.0);
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
#else
|
||||||
|
normal = myNormal;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec3 refraction = color2;
|
||||||
|
#ifdef ENABLE_REFRACTION
|
||||||
|
// texC = texCoord.xy+ m_ReflectionDisplace * normal.x;
|
||||||
|
texC = texCoord.xy;
|
||||||
|
texC += sin(m_Time*1.8 + 3.0 * abs(position.y)) * (refractionScale * min(depth2, 1.0));
|
||||||
|
#ifdef RESOLVE_MS
|
||||||
|
ivec2 iTexC = ivec2(texC * textureSize(m_Texture));
|
||||||
|
refraction = texelFetch(m_Texture, iTexC, sampleNum).rgb;
|
||||||
|
#else
|
||||||
|
ivec2 iTexC = ivec2(texC * textureSize(m_Texture, 0));
|
||||||
|
refraction = texelFetch(m_Texture, iTexC, 0).rgb;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec3 waterPosition = surfacePoint.xyz;
|
||||||
|
waterPosition.y -= (level - m_WaterHeight);
|
||||||
|
vec4 texCoordProj = m_TextureProjMatrix * vec4(waterPosition, 1.0);
|
||||||
|
|
||||||
|
texCoordProj.x = texCoordProj.x + m_ReflectionDisplace * normal.x;
|
||||||
|
texCoordProj.z = texCoordProj.z + m_ReflectionDisplace * normal.z;
|
||||||
|
texCoordProj /= texCoordProj.w;
|
||||||
|
texCoordProj.y = 1.0 - texCoordProj.y;
|
||||||
|
|
||||||
|
vec3 reflection = texture(m_ReflectionMap, texCoordProj.xy).rgb;
|
||||||
|
|
||||||
|
float fresnel = fresnelTerm(normal, eyeVecNorm);
|
||||||
|
|
||||||
|
float depthN = depth * m_WaterTransparency;
|
||||||
|
float waterCol = saturate(length(m_LightColor.rgb) / m_SunScale);
|
||||||
|
refraction = mix(mix(refraction, m_WaterColor.rgb * waterCol, saturate(depthN / visibility)),
|
||||||
|
m_DeepWaterColor.rgb * waterCol, saturate(depth2 / m_ColorExtinction));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vec3 foam = vec3(0.0);
|
||||||
|
#ifdef ENABLE_FOAM
|
||||||
|
texC = (surfacePoint.xz + eyeVecNorm.xz * 0.1) * 0.05 + m_Time * 0.05 * m_WindDirection + sin(m_Time * 0.001 + position.x) * 0.005;
|
||||||
|
vec2 texCoord2 = (surfacePoint.xz + eyeVecNorm.xz * 0.1) * 0.05 + m_Time * 0.1 * m_WindDirection + sin(m_Time * 0.001 + position.z) * 0.005;
|
||||||
|
|
||||||
|
if(depth2 < m_FoamExistence.x){
|
||||||
|
foam = (texture2D(m_FoamMap, texC).r + texture2D(m_FoamMap, texCoord2)).rgb * vec3(m_FoamIntensity);
|
||||||
|
}else if(depth2 < m_FoamExistence.y){
|
||||||
|
foam = mix((texture2D(m_FoamMap, texC) + texture2D(m_FoamMap, texCoord2)) * m_FoamIntensity , vec4(0.0),
|
||||||
|
(depth2 - m_FoamExistence.x) / (m_FoamExistence.y - m_FoamExistence.x)).rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(m_MaxAmplitude - m_FoamExistence.z> 0.0001){
|
||||||
|
foam += ((texture2D(m_FoamMap, texC) + texture2D(m_FoamMap, texCoord2)) * m_FoamIntensity * m_FoamIntensity * 0.3 *
|
||||||
|
saturate((level - (m_WaterHeight + m_FoamExistence.z)) / (m_MaxAmplitude - m_FoamExistence.z))).rgb;
|
||||||
|
}
|
||||||
|
foam *= m_LightColor.rgb;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec3 specular = vec3(0.0);
|
||||||
|
#ifdef ENABLE_SPECULAR
|
||||||
|
vec3 lightDir=normalize(m_LightDir);
|
||||||
|
vec3 mirrorEye = (2.0 * dot(eyeVecNorm, normal) * normal - eyeVecNorm);
|
||||||
|
float dotSpec = saturate(dot(mirrorEye.xyz, -lightDir) * 0.5 + 0.5);
|
||||||
|
specular = vec3((1.0 - fresnel) * saturate(-lightDir.y) * ((pow(dotSpec, 512.0)) * (m_Shininess * 1.8 + 0.2)));
|
||||||
|
specular += specular * 25.0 * saturate(m_Shininess - 0.05);
|
||||||
|
//foam does not shine
|
||||||
|
specular=specular * m_LightColor.rgb - (5.0 * foam);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
color = mix(refraction, reflection, fresnel);
|
||||||
|
color = mix(refraction, color, saturate(depth * m_ShoreHardness));
|
||||||
|
color = saturate(color + max(specular, foam ));
|
||||||
|
color = mix(refraction, color, saturate(depth* m_FoamHardness));
|
||||||
|
|
||||||
|
|
||||||
|
// XXX: HACK ALERT:
|
||||||
|
// We trick the GeForces to think they have
|
||||||
|
// to calculate the derivatives for all these pixels by using step()!
|
||||||
|
// That way we won't get pixels around the edges of the terrain,
|
||||||
|
// Where the derivatives are undefined
|
||||||
|
return vec4(mix(color, color2, step(level, position.y)), 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
#ifdef RESOLVE_MS
|
||||||
|
vec4 color = vec4(0.0);
|
||||||
|
for (int i = 0; i < m_NumSamples; i++){
|
||||||
|
color += main_multiSample(i);
|
||||||
|
}
|
||||||
|
outFragColor = color / m_NumSamples;
|
||||||
|
#else
|
||||||
|
outFragColor = main_multiSample(0);
|
||||||
|
#endif
|
||||||
|
}
|
126
engine/src/core-effects/Common/MatDefs/Water/simple_water.frag
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
GLSL conversion of Michael Horsch water demo
|
||||||
|
http://www.bonzaisoftware.com/wfs.html
|
||||||
|
Converted by Mars_999
|
||||||
|
8/20/2005
|
||||||
|
*/
|
||||||
|
|
||||||
|
uniform sampler2D m_water_normalmap;
|
||||||
|
uniform sampler2D m_water_reflection;
|
||||||
|
uniform sampler2D m_water_refraction;
|
||||||
|
uniform sampler2D m_water_dudvmap;
|
||||||
|
uniform sampler2D m_water_depthmap;
|
||||||
|
uniform vec4 m_waterColor;
|
||||||
|
uniform float m_waterDepth;
|
||||||
|
uniform vec4 m_distortionScale;
|
||||||
|
uniform vec4 m_distortionMix;
|
||||||
|
uniform vec4 m_texScale;
|
||||||
|
uniform vec2 m_FrustumNearFar;
|
||||||
|
uniform float m_waterTransparency;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
varying vec4 lightDir; //lightpos
|
||||||
|
varying vec4 waterTex1; //moving texcoords
|
||||||
|
varying vec4 waterTex2; //moving texcoords
|
||||||
|
varying vec4 position; //for projection
|
||||||
|
varying vec4 viewDir; //viewts
|
||||||
|
varying vec4 viewLightDir;
|
||||||
|
varying vec4 viewCamDir;
|
||||||
|
|
||||||
|
//unit 0 = m_water_reflection
|
||||||
|
//unit 1 = m_water_refraction
|
||||||
|
//unit 2 = m_water_normalmap
|
||||||
|
//unit 3 = m_water_dudvmap
|
||||||
|
//unit 4 = m_water_depthmap
|
||||||
|
|
||||||
|
const vec4 two = vec4(2.0, 2.0, 2.0, 1.0);
|
||||||
|
const vec4 mone = vec4(-1.0, -1.0, -1.0, 1.0);
|
||||||
|
|
||||||
|
const vec4 ofive = vec4(0.5,0.5,0.5,1.0);
|
||||||
|
|
||||||
|
const float exponent = 64.0;
|
||||||
|
|
||||||
|
float tangDot(in vec3 v1, in vec3 v2){
|
||||||
|
float d = dot(v1,v2);
|
||||||
|
#ifdef V_TANGENT
|
||||||
|
d = 1.0 - d*d;
|
||||||
|
return step(0.0, d) * sqrt(d);
|
||||||
|
#else
|
||||||
|
return d;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 readDepth(vec2 uv){
|
||||||
|
float depth= (2.0 * m_FrustumNearFar.x) / (m_FrustumNearFar.y + m_FrustumNearFar.x - texture2D(m_water_depthmap, uv).r* (m_FrustumNearFar.y-m_FrustumNearFar.x));
|
||||||
|
return vec4( depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
vec4 lightTS = normalize(lightDir);
|
||||||
|
vec4 viewt = normalize(viewDir);
|
||||||
|
vec4 disdis = texture2D(m_water_dudvmap, vec2(waterTex2 * m_texScale));
|
||||||
|
vec4 fdist = texture2D(m_water_dudvmap, vec2(waterTex1 + disdis*m_distortionMix));
|
||||||
|
fdist =normalize( fdist * 2.0 - 1.0)* m_distortionScale;
|
||||||
|
|
||||||
|
|
||||||
|
//load normalmap
|
||||||
|
vec4 nmap = texture2D(m_water_normalmap, vec2(waterTex1 + disdis*m_distortionMix));
|
||||||
|
nmap = (nmap-ofive) * two;
|
||||||
|
// nmap = nmap*2.0-1.0;
|
||||||
|
vec4 vNorm = normalize(nmap);
|
||||||
|
|
||||||
|
|
||||||
|
vec4 projCoord = position / position.w;
|
||||||
|
projCoord =(projCoord+1.0)*0.5 + fdist;
|
||||||
|
projCoord = clamp(projCoord, 0.001, 0.999);
|
||||||
|
|
||||||
|
//load reflection,refraction and depth texture
|
||||||
|
vec4 refl = texture2D(m_water_reflection, vec2(projCoord.x,1.0-projCoord.y));
|
||||||
|
vec4 refr = texture2D(m_water_refraction, vec2(projCoord));
|
||||||
|
vec4 wdepth =readDepth(vec2(projCoord));
|
||||||
|
|
||||||
|
wdepth = vec4(pow(wdepth.x, m_waterDepth));
|
||||||
|
vec4 invdepth = 1.0 - wdepth;
|
||||||
|
|
||||||
|
|
||||||
|
// Blinn - Phong
|
||||||
|
// vec4 H = (viewt - lightTS);
|
||||||
|
// vec4 specular =vec4(pow(max(dot(H, vNorm), 0.0), exponent));
|
||||||
|
|
||||||
|
// Standard Phong
|
||||||
|
|
||||||
|
// vec4 R =reflect(-L, vNorm);
|
||||||
|
// vec4 specular =vec4( pow(max(dot(R, E), 0.0),exponent));
|
||||||
|
|
||||||
|
|
||||||
|
//calculate specular highlight
|
||||||
|
vec4 L=normalize(viewLightDir);
|
||||||
|
vec4 E=normalize(viewCamDir);
|
||||||
|
vec4 vRef = normalize(reflect(-L,vNorm));
|
||||||
|
float stemp =max(0.0, dot( vRef,E) );
|
||||||
|
//initializing to 0 to avoid artifacts on old intel cards
|
||||||
|
vec4 specular = vec4(0.0,0.0,0.0,0.0);
|
||||||
|
if(stemp>0.0){
|
||||||
|
stemp = pow(stemp, exponent);
|
||||||
|
specular = vec4(stemp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vec4 fresnelTerm = vec4(0.02+0.97*pow((1.0-dot(normalize(viewt), vNorm)),5.0));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fresnelTerm=fresnelTerm*invdepth*m_waterTransparency;
|
||||||
|
fresnelTerm=clamp(fresnelTerm,0.0,1.0);
|
||||||
|
|
||||||
|
refr*=(fresnelTerm);
|
||||||
|
refr *= invdepth;
|
||||||
|
refr= refr+ m_waterColor*wdepth*fresnelTerm;
|
||||||
|
|
||||||
|
gl_FragColor =(refr+ refl*(1.0-fresnelTerm))+specular;
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
GLSL conversion of Michael Horsch water demo
|
||||||
|
http://www.bonzaisoftware.com/wfs.html
|
||||||
|
Converted by Mars_999
|
||||||
|
8/20/2005
|
||||||
|
*/
|
||||||
|
uniform vec3 m_lightPos;
|
||||||
|
uniform float m_time;
|
||||||
|
|
||||||
|
uniform mat4 g_WorldViewProjectionMatrix;
|
||||||
|
uniform mat4 g_WorldViewMatrix;
|
||||||
|
uniform mat4 g_ViewMatrix;
|
||||||
|
uniform vec3 g_CameraPosition;
|
||||||
|
uniform mat3 g_NormalMatrix;
|
||||||
|
|
||||||
|
attribute vec4 inPosition;
|
||||||
|
attribute vec2 inTexCoord;
|
||||||
|
attribute vec3 inTangent;
|
||||||
|
attribute vec3 inNormal;
|
||||||
|
|
||||||
|
varying vec4 lightDir;
|
||||||
|
varying vec4 waterTex1;
|
||||||
|
varying vec4 waterTex2;
|
||||||
|
varying vec4 position;
|
||||||
|
varying vec4 viewDir;
|
||||||
|
varying vec4 viewpos;
|
||||||
|
varying vec4 viewLightDir;
|
||||||
|
varying vec4 viewCamDir;
|
||||||
|
|
||||||
|
|
||||||
|
//unit 0 = water_reflection
|
||||||
|
//unit 1 = water_refraction
|
||||||
|
//unit 2 = water_normalmap
|
||||||
|
//unit 3 = water_dudvmap
|
||||||
|
//unit 4 = water_depthmap
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
viewpos.x = g_CameraPosition.x;
|
||||||
|
viewpos.y = g_CameraPosition.y;
|
||||||
|
viewpos.z = g_CameraPosition.z;
|
||||||
|
viewpos.w = 1.0;
|
||||||
|
|
||||||
|
vec4 temp;
|
||||||
|
vec4 tangent = vec4(1.0, 0.0, 0.0, 0.0);
|
||||||
|
vec4 norm = vec4(0.0, 1.0, 0.0, 0.0);
|
||||||
|
vec4 binormal = vec4(0.0, 0.0, 1.0, 0.0);
|
||||||
|
|
||||||
|
|
||||||
|
temp = viewpos - inPosition;
|
||||||
|
|
||||||
|
viewDir.x = dot(temp, tangent);
|
||||||
|
viewDir.y = dot(temp, binormal);
|
||||||
|
viewDir.z = dot(temp, norm);
|
||||||
|
viewDir.w = 0.0;
|
||||||
|
|
||||||
|
temp = vec4(m_lightPos,1.0)- inPosition;
|
||||||
|
lightDir.x = dot(temp, tangent);
|
||||||
|
lightDir.y = dot(temp, binormal);
|
||||||
|
lightDir.z = dot(temp, norm);
|
||||||
|
lightDir.w = 0.0;
|
||||||
|
|
||||||
|
vec4 viewSpaceLightPos=g_ViewMatrix*vec4(m_lightPos,1.0);
|
||||||
|
vec4 viewSpacePos=g_WorldViewMatrix*inPosition;
|
||||||
|
vec3 wvNormal = normalize(g_NormalMatrix * inNormal);
|
||||||
|
vec3 wvTangent = normalize(g_NormalMatrix * inTangent);
|
||||||
|
vec3 wvBinormal = cross(wvNormal, wvTangent);
|
||||||
|
mat3 tbnMat = mat3(wvTangent, wvBinormal, wvNormal);
|
||||||
|
|
||||||
|
temp = viewSpaceLightPos - viewSpacePos;
|
||||||
|
viewLightDir.xyz=temp.xyz*tbnMat;
|
||||||
|
viewLightDir.w = 0.0;
|
||||||
|
|
||||||
|
temp = -viewSpacePos;
|
||||||
|
viewCamDir.xyz =temp.xyz*tbnMat;
|
||||||
|
viewCamDir.w = 0.0;
|
||||||
|
|
||||||
|
|
||||||
|
vec4 t1 = vec4(0.0, -m_time, 0.0,0.0);
|
||||||
|
vec4 t2 = vec4(0.0, m_time, 0.0,0.0);
|
||||||
|
|
||||||
|
waterTex1 =vec4(inTexCoord,0.0,0.0) + t1;
|
||||||
|
waterTex2 =vec4(inTexCoord ,0.0,0.0)+ t2;
|
||||||
|
|
||||||
|
position = g_WorldViewProjectionMatrix * inPosition;
|
||||||
|
gl_Position = position;
|
||||||
|
}
|
309
engine/src/core-effects/com/jme3/post/filters/BloomFilter.java
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2010 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.post.filters;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.export.InputCapsule;
|
||||||
|
import com.jme3.export.JmeExporter;
|
||||||
|
import com.jme3.export.JmeImporter;
|
||||||
|
import com.jme3.export.OutputCapsule;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
|
import com.jme3.post.Filter;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.texture.Image.Format;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BloomFilter is used to make objects in the scene have a glow effect.<br>
|
||||||
|
* There are 2 mode : Scene and Objects.<br>
|
||||||
|
* Scene mode extracts the bright parts of the scene to make them glow<br>
|
||||||
|
* Object mode make objects glow according to their material's glowMap or their GlowColor<br>
|
||||||
|
* @see <a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:bloom_and_glow">advanced:bloom_and_glow</a> for more details
|
||||||
|
*
|
||||||
|
* @author Rémy Bouquet aka Nehon
|
||||||
|
*/
|
||||||
|
public class BloomFilter extends Filter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GlowMode specifies if the glow will be applied to the whole scene,or to objects that have aglow color or a glow map
|
||||||
|
*/
|
||||||
|
public enum GlowMode {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply bloom filter to bright areas in the scene.
|
||||||
|
*/
|
||||||
|
Scene,
|
||||||
|
/**
|
||||||
|
* Apply bloom only to objects that have a glow map or a glow color.
|
||||||
|
*/
|
||||||
|
Objects,
|
||||||
|
/**
|
||||||
|
* Apply bloom to both bright parts of the scene and objects with glow map.
|
||||||
|
*/
|
||||||
|
SceneAndObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GlowMode glowMode = GlowMode.Scene;
|
||||||
|
//Bloom parameters
|
||||||
|
private float blurScale = 1.5f;
|
||||||
|
private float exposurePower = 5.0f;
|
||||||
|
private float exposureCutOff = 0.0f;
|
||||||
|
private float bloomIntensity = 2.0f;
|
||||||
|
private float downSamplingFactor = 1;
|
||||||
|
private Pass preGlowPass;
|
||||||
|
private Pass extractPass;
|
||||||
|
private Pass horizontalBlur = new Pass();
|
||||||
|
private Pass verticalalBlur = new Pass();
|
||||||
|
private Material extractMat;
|
||||||
|
private Material vBlurMat;
|
||||||
|
private Material hBlurMat;
|
||||||
|
private int screenWidth;
|
||||||
|
private int screenHeight;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Bloom filter
|
||||||
|
*/
|
||||||
|
public BloomFilter() {
|
||||||
|
super("BloomFilter");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the bloom filter with the specific glow mode
|
||||||
|
* @param glowMode
|
||||||
|
*/
|
||||||
|
public BloomFilter(GlowMode glowMode) {
|
||||||
|
this();
|
||||||
|
this.glowMode = glowMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
|
||||||
|
screenWidth = (int) Math.max(1, (w / downSamplingFactor));
|
||||||
|
screenHeight = (int) Math.max(1, (h / downSamplingFactor));
|
||||||
|
// System.out.println(screenWidth + " " + screenHeight);
|
||||||
|
if (glowMode != GlowMode.Scene) {
|
||||||
|
preGlowPass = new Pass();
|
||||||
|
preGlowPass.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
postRenderPasses = new ArrayList<Pass>();
|
||||||
|
//configuring extractPass
|
||||||
|
extractMat = new Material(manager, "Common/MatDefs/Post/BloomExtract.j3md");
|
||||||
|
extractPass = new Pass() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresSceneAsTexture() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeRender() {
|
||||||
|
extractMat.setFloat("ExposurePow", exposurePower);
|
||||||
|
extractMat.setFloat("ExposureCutoff", exposureCutOff);
|
||||||
|
if (glowMode != GlowMode.Scene) {
|
||||||
|
extractMat.setTexture("GlowMap", preGlowPass.getRenderedTexture());
|
||||||
|
}
|
||||||
|
extractMat.setBoolean("Extract", glowMode != GlowMode.Objects);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
extractPass.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth, 1, extractMat);
|
||||||
|
postRenderPasses.add(extractPass);
|
||||||
|
|
||||||
|
//configuring horizontal blur pass
|
||||||
|
hBlurMat = new Material(manager, "Common/MatDefs/Blur/HGaussianBlur.j3md");
|
||||||
|
horizontalBlur = new Pass() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeRender() {
|
||||||
|
hBlurMat.setTexture("Texture", extractPass.getRenderedTexture());
|
||||||
|
hBlurMat.setFloat("Size", screenWidth);
|
||||||
|
hBlurMat.setFloat("Scale", blurScale);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
horizontalBlur.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth, 1, hBlurMat);
|
||||||
|
postRenderPasses.add(horizontalBlur);
|
||||||
|
|
||||||
|
//configuring vertical blur pass
|
||||||
|
vBlurMat = new Material(manager, "Common/MatDefs/Blur/VGaussianBlur.j3md");
|
||||||
|
verticalalBlur = new Pass() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeRender() {
|
||||||
|
vBlurMat.setTexture("Texture", horizontalBlur.getRenderedTexture());
|
||||||
|
vBlurMat.setFloat("Size", screenHeight);
|
||||||
|
vBlurMat.setFloat("Scale", blurScale);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
verticalalBlur.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth, 1, vBlurMat);
|
||||||
|
postRenderPasses.add(verticalalBlur);
|
||||||
|
|
||||||
|
|
||||||
|
//final material
|
||||||
|
material = new Material(manager, "Common/MatDefs/Post/BloomFinal.j3md");
|
||||||
|
material.setTexture("BloomTex", verticalalBlur.getRenderedTexture());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Material getMaterial() {
|
||||||
|
material.setFloat("BloomIntensity", bloomIntensity);
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void postQueue(RenderManager renderManager, ViewPort viewPort) {
|
||||||
|
if (glowMode != GlowMode.Scene) {
|
||||||
|
renderManager.getRenderer().setBackgroundColor(ColorRGBA.BlackNoAlpha);
|
||||||
|
renderManager.getRenderer().setFrameBuffer(preGlowPass.getRenderFrameBuffer());
|
||||||
|
renderManager.getRenderer().clearBuffers(true, true, true);
|
||||||
|
renderManager.setForcedTechnique("Glow");
|
||||||
|
renderManager.renderViewPortQueues(viewPort, false);
|
||||||
|
renderManager.setForcedTechnique(null);
|
||||||
|
renderManager.getRenderer().setFrameBuffer(viewPort.getOutputFrameBuffer());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the bloom intensity
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getBloomIntensity() {
|
||||||
|
return bloomIntensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* intensity of the bloom effect default is 2.0
|
||||||
|
* @param bloomIntensity
|
||||||
|
*/
|
||||||
|
public void setBloomIntensity(float bloomIntensity) {
|
||||||
|
this.bloomIntensity = bloomIntensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the blur scale
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getBlurScale() {
|
||||||
|
return blurScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets The spread of the bloom default is 1.5f
|
||||||
|
* @param blurScale
|
||||||
|
*/
|
||||||
|
public void setBlurScale(float blurScale) {
|
||||||
|
this.blurScale = blurScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the exposure cutoff<br>
|
||||||
|
* for more details see {@link setExposureCutOff(float exposureCutOff)}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getExposureCutOff() {
|
||||||
|
return exposureCutOff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define the color threshold on which the bloom will be applied (0.0 to 1.0)
|
||||||
|
* @param exposureCutOff
|
||||||
|
*/
|
||||||
|
public void setExposureCutOff(float exposureCutOff) {
|
||||||
|
this.exposureCutOff = exposureCutOff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the exposure power<br>
|
||||||
|
* form more details see {@link setExposurePower(float exposurePower)}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getExposurePower() {
|
||||||
|
return exposurePower;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* defines how many time the bloom extracted color will be multiplied by itself. default id 5.0<br>
|
||||||
|
* a high value will reduce rough edges in the bloom and somhow the range of the bloom area *
|
||||||
|
* @param exposurePower
|
||||||
|
*/
|
||||||
|
public void setExposurePower(float exposurePower) {
|
||||||
|
this.exposurePower = exposurePower;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the downSampling factor<br>
|
||||||
|
* form more details see {@link setDownSamplingFactor(float downSamplingFactor)}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getDownSamplingFactor() {
|
||||||
|
return downSamplingFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the downSampling factor : the size of the computed texture will be divided by this factor. default is 1 for no downsampling
|
||||||
|
* A 2 value is a good way of widening the blur
|
||||||
|
* @param downSamplingFactor
|
||||||
|
*/
|
||||||
|
public void setDownSamplingFactor(float downSamplingFactor) {
|
||||||
|
this.downSamplingFactor = downSamplingFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JmeExporter ex) throws IOException {
|
||||||
|
super.write(ex);
|
||||||
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
|
oc.write(glowMode, "glowMode", GlowMode.Scene);
|
||||||
|
oc.write(blurScale, "blurScale", 1.5f);
|
||||||
|
oc.write(exposurePower, "exposurePower", 5.0f);
|
||||||
|
oc.write(exposureCutOff, "exposureCutOff", 0.0f);
|
||||||
|
oc.write(bloomIntensity, "bloomIntensity", 2.0f);
|
||||||
|
oc.write(downSamplingFactor, "downSamplingFactor", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(JmeImporter im) throws IOException {
|
||||||
|
super.read(im);
|
||||||
|
InputCapsule ic = im.getCapsule(this);
|
||||||
|
glowMode = ic.readEnum("glowMode", GlowMode.class, GlowMode.Scene);
|
||||||
|
blurScale = ic.readFloat("blurScale", 1.5f);
|
||||||
|
exposurePower = ic.readFloat("exposurePower", 5.0f);
|
||||||
|
exposureCutOff = ic.readFloat("exposureCutOff", 0.0f);
|
||||||
|
bloomIntensity = ic.readFloat("bloomIntensity", 2.0f);
|
||||||
|
downSamplingFactor = ic.readFloat("downSamplingFactor", 1);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,245 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2010 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.post.filters;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
|
import com.jme3.post.Filter;
|
||||||
|
import com.jme3.post.Filter.Pass;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.Renderer;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.texture.Image.Format;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies a cartoon-style edge detection filter to all objects in the scene.
|
||||||
|
*
|
||||||
|
* @author Kirill Vainer
|
||||||
|
*/
|
||||||
|
public class CartoonEdgeFilter extends Filter {
|
||||||
|
|
||||||
|
private Pass normalPass;
|
||||||
|
private float edgeWidth = 1.0f;
|
||||||
|
private float edgeIntensity = 1.0f;
|
||||||
|
private float normalThreshold = 0.5f;
|
||||||
|
private float depthThreshold = 0.1f;
|
||||||
|
private float normalSensitivity = 1.0f;
|
||||||
|
private float depthSensitivity = 10.0f;
|
||||||
|
private ColorRGBA edgeColor = new ColorRGBA(0, 0, 0, 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a CartoonEdgeFilter
|
||||||
|
*/
|
||||||
|
public CartoonEdgeFilter() {
|
||||||
|
super("CartoonEdgeFilter");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isRequiresDepthTexture() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void postQueue(RenderManager renderManager, ViewPort viewPort) {
|
||||||
|
Renderer r = renderManager.getRenderer();
|
||||||
|
r.setFrameBuffer(normalPass.getRenderFrameBuffer());
|
||||||
|
renderManager.getRenderer().clearBuffers(true, true, true);
|
||||||
|
renderManager.setForcedTechnique("PreNormalPass");
|
||||||
|
renderManager.renderViewPortQueues(viewPort, false);
|
||||||
|
renderManager.setForcedTechnique(null);
|
||||||
|
renderManager.getRenderer().setFrameBuffer(viewPort.getOutputFrameBuffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Material getMaterial() {
|
||||||
|
material.setTexture("NormalsTexture", normalPass.getRenderedTexture());
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
|
||||||
|
normalPass = new Pass();
|
||||||
|
normalPass.init(renderManager.getRenderer(), w, h, Format.RGBA8, Format.Depth);
|
||||||
|
material = new Material(manager, "Common/MatDefs/Post/CartoonEdge.j3md");
|
||||||
|
material.setFloat("EdgeWidth", edgeWidth);
|
||||||
|
material.setFloat("EdgeIntensity", edgeIntensity);
|
||||||
|
material.setFloat("NormalThreshold", normalThreshold);
|
||||||
|
material.setFloat("DepthThreshold", depthThreshold);
|
||||||
|
material.setFloat("NormalSensitivity", normalSensitivity);
|
||||||
|
material.setFloat("DepthSensitivity", depthSensitivity);
|
||||||
|
material.setColor("EdgeColor", edgeColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the depth sensitivity<br>
|
||||||
|
* for more details see {@link setDepthSensitivity(float depthSensitivity)}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getDepthSensitivity() {
|
||||||
|
return depthSensitivity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the depth sensitivity<br>
|
||||||
|
* defines how much depth will influence edges, default is 10
|
||||||
|
* @param depthSensitivity
|
||||||
|
*/
|
||||||
|
public void setDepthSensitivity(float depthSensitivity) {
|
||||||
|
this.depthSensitivity = depthSensitivity;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("DepthSensitivity", depthSensitivity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the depth threshold<br>
|
||||||
|
* for more details see {@link setDepthThreshold(float depthThreshold)}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getDepthThreshold() {
|
||||||
|
return depthThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the depth threshold<br>
|
||||||
|
* Defines at what threshold of difference of depth an edge is outlined default is 0.1f
|
||||||
|
* @param depthThreshold
|
||||||
|
*/
|
||||||
|
public void setDepthThreshold(float depthThreshold) {
|
||||||
|
this.depthThreshold = depthThreshold;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("DepthThreshold", depthThreshold);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the edge intensity<br>
|
||||||
|
* for more details see {@link setEdgeIntensity(float edgeIntensity) }
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getEdgeIntensity() {
|
||||||
|
return edgeIntensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the edge intensity<br>
|
||||||
|
* Defineshow visilble will be the outlined edges
|
||||||
|
* @param edgeIntensity
|
||||||
|
*/
|
||||||
|
public void setEdgeIntensity(float edgeIntensity) {
|
||||||
|
this.edgeIntensity = edgeIntensity;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("EdgeIntensity", edgeIntensity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the width of the edges
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getEdgeWidth() {
|
||||||
|
return edgeWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the witdh of the edge in pixels default is 1
|
||||||
|
* @param edgeWidth
|
||||||
|
*/
|
||||||
|
public void setEdgeWidth(float edgeWidth) {
|
||||||
|
this.edgeWidth = edgeWidth;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("EdgeWidth", edgeWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the normals sensitivity<br>
|
||||||
|
* form more details see {@link setNormalSensitivity(float normalSensitivity)}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getNormalSensitivity() {
|
||||||
|
return normalSensitivity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the normals sensitivity default is 1
|
||||||
|
* @param normalSensitivity
|
||||||
|
*/
|
||||||
|
public void setNormalSensitivity(float normalSensitivity) {
|
||||||
|
this.normalSensitivity = normalSensitivity;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("NormalSensitivity", normalSensitivity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the normal threshold<br>
|
||||||
|
* for more details see {@link setNormalThreshold(float normalThreshold)}
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getNormalThreshold() {
|
||||||
|
return normalThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the normal threshold default is 0.5
|
||||||
|
* @param normalThreshold
|
||||||
|
*/
|
||||||
|
public void setNormalThreshold(float normalThreshold) {
|
||||||
|
this.normalThreshold = normalThreshold;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("NormalThreshold", normalThreshold);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the edge color
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ColorRGBA getEdgeColor() {
|
||||||
|
return edgeColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the edge color, default is black
|
||||||
|
* @param edgeColor
|
||||||
|
*/
|
||||||
|
public void setEdgeColor(ColorRGBA edgeColor) {
|
||||||
|
this.edgeColor = edgeColor;
|
||||||
|
if (material != null) {
|
||||||
|
material.setColor("EdgeColor", edgeColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2010 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.post.filters;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.export.InputCapsule;
|
||||||
|
import com.jme3.export.JmeExporter;
|
||||||
|
import com.jme3.export.JmeImporter;
|
||||||
|
import com.jme3.export.OutputCapsule;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
|
import com.jme3.post.Filter;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This filter simply multiply the whole scene by a color
|
||||||
|
* @author Rémy Bouquet aka Nehon
|
||||||
|
*/
|
||||||
|
public class ColorOverlayFilter extends Filter {
|
||||||
|
|
||||||
|
private ColorRGBA color = ColorRGBA.White;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a colorOverlayFilter with a white coor (transparent)
|
||||||
|
*/
|
||||||
|
public ColorOverlayFilter() {
|
||||||
|
super("Color Overlay");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a colorOverlayFilter with the given color
|
||||||
|
* @param color
|
||||||
|
*/
|
||||||
|
public ColorOverlayFilter(ColorRGBA color) {
|
||||||
|
this();
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Material getMaterial() {
|
||||||
|
|
||||||
|
material.setColor("Color", color);
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the color
|
||||||
|
* @return color
|
||||||
|
*/
|
||||||
|
public ColorRGBA getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the color
|
||||||
|
* @param color
|
||||||
|
*/
|
||||||
|
public void setColor(ColorRGBA color) {
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
|
||||||
|
material = new Material(manager, "Common/MatDefs/Post/Overlay.j3md");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JmeExporter ex) throws IOException {
|
||||||
|
super.write(ex);
|
||||||
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
|
oc.write(color, "color", ColorRGBA.White);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(JmeImporter im) throws IOException {
|
||||||
|
super.read(im);
|
||||||
|
InputCapsule ic = im.getCapsule(this);
|
||||||
|
color = (ColorRGBA) ic.readSavable("color", ColorRGBA.White);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,305 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.post.filters;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
|
import com.jme3.post.Filter;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Post Processing filter that makes the screen look like it was drawn as
|
||||||
|
* diagonal lines with a pen.
|
||||||
|
* Try combining this with a cartoon edge filter to obtain manga style visuals.
|
||||||
|
*
|
||||||
|
* Based on an article from Geeks3D:
|
||||||
|
* <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>
|
||||||
|
*
|
||||||
|
* @author Roy Straver a.k.a. Baal Garnaal
|
||||||
|
*/
|
||||||
|
public class CrossHatchFilter extends Filter {
|
||||||
|
|
||||||
|
private ColorRGBA lineColor = ColorRGBA.Black.clone();
|
||||||
|
private ColorRGBA paperColor = ColorRGBA.White.clone();
|
||||||
|
private float colorInfluenceLine = 0.8f;
|
||||||
|
private float colorInfluencePaper = 0.1f;
|
||||||
|
private float fillValue = 0.9f;
|
||||||
|
private float luminance1 = 0.9f;
|
||||||
|
private float luminance2 = 0.7f;
|
||||||
|
private float luminance3 = 0.5f;
|
||||||
|
private float luminance4 = 0.3f;
|
||||||
|
private float luminance5 = 0.0f;
|
||||||
|
private float lineThickness = 1.0f;
|
||||||
|
private float lineDistance = 4.0f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a crossHatch filter
|
||||||
|
*/
|
||||||
|
public CrossHatchFilter() {
|
||||||
|
super("CrossHatchFilter");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a crossHatch filter
|
||||||
|
* @param lineColor the colors of the lines
|
||||||
|
* @param paperColor the paper color
|
||||||
|
*/
|
||||||
|
public CrossHatchFilter(ColorRGBA lineColor, ColorRGBA paperColor) {
|
||||||
|
this();
|
||||||
|
this.lineColor = lineColor;
|
||||||
|
this.paperColor = paperColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isRequiresDepthTexture() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
|
||||||
|
material = new Material(manager, "Common/MatDefs/Post/CrossHatch.j3md");
|
||||||
|
material.setColor("LineColor", lineColor);
|
||||||
|
material.setColor("PaperColor", paperColor);
|
||||||
|
|
||||||
|
material.setFloat("ColorInfluenceLine", colorInfluenceLine);
|
||||||
|
material.setFloat("ColorInfluencePaper", colorInfluencePaper);
|
||||||
|
|
||||||
|
material.setFloat("FillValue", fillValue);
|
||||||
|
|
||||||
|
material.setFloat("Luminance1", luminance1);
|
||||||
|
material.setFloat("Luminance2", luminance2);
|
||||||
|
material.setFloat("Luminance3", luminance3);
|
||||||
|
material.setFloat("Luminance4", luminance4);
|
||||||
|
material.setFloat("Luminance5", luminance5);
|
||||||
|
|
||||||
|
material.setFloat("LineThickness", lineThickness);
|
||||||
|
material.setFloat("LineDistance", lineDistance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Material getMaterial() {
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets color used to draw lines
|
||||||
|
* @param lineColor
|
||||||
|
*/
|
||||||
|
public void setLineColor(ColorRGBA lineColor) {
|
||||||
|
this.lineColor = lineColor;
|
||||||
|
if (material != null) {
|
||||||
|
material.setColor("LineColor", lineColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets color used as background
|
||||||
|
* @param paperColor
|
||||||
|
*/
|
||||||
|
public void setPaperColor(ColorRGBA paperColor) {
|
||||||
|
this.paperColor = paperColor;
|
||||||
|
if (material != null) {
|
||||||
|
material.setColor("PaperColor", paperColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets color influence of original image on lines drawn
|
||||||
|
* @param colorInfluenceLine
|
||||||
|
*/
|
||||||
|
public void setColorInfluenceLine(float colorInfluenceLine) {
|
||||||
|
this.colorInfluenceLine = colorInfluenceLine;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("ColorInfluenceLine", colorInfluenceLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets color influence of original image on non-line areas
|
||||||
|
* @param colorInfluencePaper
|
||||||
|
*/
|
||||||
|
public void setColorInfluencePaper(float colorInfluencePaper) {
|
||||||
|
this.colorInfluencePaper = colorInfluencePaper;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("ColorInfluencePaper", colorInfluencePaper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets line/paper color ratio for areas with values < luminance5,
|
||||||
|
* really dark areas get no lines but a filled blob instead
|
||||||
|
* @param fillValue
|
||||||
|
*/
|
||||||
|
public void setFillValue(float fillValue) {
|
||||||
|
this.fillValue = fillValue;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("FillValue", fillValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Sets minimum luminance levels for lines drawn
|
||||||
|
* @param luminance1 Top-left to down right 1
|
||||||
|
* @param luminance2 Top-right to bottom left 1
|
||||||
|
* @param luminance3 Top-left to down right 2
|
||||||
|
* @param luminance4 Top-right to bottom left 2
|
||||||
|
* @param luminance5 Blobs
|
||||||
|
*/
|
||||||
|
public void setLuminanceLevels(float luminance1, float luminance2, float luminance3, float luminance4, float luminance5) {
|
||||||
|
this.luminance1 = luminance1;
|
||||||
|
this.luminance2 = luminance2;
|
||||||
|
this.luminance3 = luminance3;
|
||||||
|
this.luminance4 = luminance4;
|
||||||
|
this.luminance5 = luminance5;
|
||||||
|
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("Luminance1", luminance1);
|
||||||
|
material.setFloat("Luminance2", luminance2);
|
||||||
|
material.setFloat("Luminance3", luminance3);
|
||||||
|
material.setFloat("Luminance4", luminance4);
|
||||||
|
material.setFloat("Luminance5", luminance5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the thickness of lines drawn
|
||||||
|
* @param lineThickness
|
||||||
|
*/
|
||||||
|
public void setLineThickness(float lineThickness) {
|
||||||
|
this.lineThickness = lineThickness;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("LineThickness", lineThickness);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets minimum distance between lines drawn
|
||||||
|
* Primary lines are drawn at 2*lineDistance
|
||||||
|
* Secondary lines are drawn at lineDistance
|
||||||
|
* @param lineDistance
|
||||||
|
*/
|
||||||
|
public void setLineDistance(float lineDistance) {
|
||||||
|
this.lineDistance = lineDistance;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("LineDistance", lineDistance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns line color
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ColorRGBA getLineColor() {
|
||||||
|
return lineColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns paper background color
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ColorRGBA getPaperColor() {
|
||||||
|
return paperColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns current influence of image colors on lines
|
||||||
|
*/
|
||||||
|
public float getColorInfluenceLine() {
|
||||||
|
return colorInfluenceLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns current influence of image colors on paper background
|
||||||
|
*/
|
||||||
|
public float getColorInfluencePaper() {
|
||||||
|
return colorInfluencePaper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns line/paper color ratio for blobs
|
||||||
|
*/
|
||||||
|
public float getFillValue() {
|
||||||
|
return fillValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the thickness of the lines drawn
|
||||||
|
*/
|
||||||
|
public float getLineThickness() {
|
||||||
|
return lineThickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns minimum distance between lines
|
||||||
|
*/
|
||||||
|
public float getLineDistance() {
|
||||||
|
return lineDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns treshold for lines 1
|
||||||
|
*/
|
||||||
|
public float getLuminance1() {
|
||||||
|
return luminance1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns treshold for lines 2
|
||||||
|
*/
|
||||||
|
public float getLuminance2() {
|
||||||
|
return luminance2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns treshold for lines 3
|
||||||
|
*/
|
||||||
|
public float getLuminance3() {
|
||||||
|
return luminance3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns treshold for lines 4
|
||||||
|
*/
|
||||||
|
public float getLuminance4() {
|
||||||
|
return luminance4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns treshold for blobs
|
||||||
|
*/
|
||||||
|
public float getLuminance5() {
|
||||||
|
return luminance5;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2010 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.post.filters;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.post.Filter;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A post-processing filter that performs a depth range
|
||||||
|
* blur using a scaled convolution filter.
|
||||||
|
*
|
||||||
|
* @version $Revision: 779 $
|
||||||
|
* @author Paul Speed
|
||||||
|
*/
|
||||||
|
public class DepthOfFieldFilter extends Filter {
|
||||||
|
|
||||||
|
private float focusDistance = 50f;
|
||||||
|
private float focusRange = 10f;
|
||||||
|
private float blurScale = 1f;
|
||||||
|
// These values are set internally based on the
|
||||||
|
// viewport size.
|
||||||
|
private float xScale;
|
||||||
|
private float yScale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a DepthOfField filter
|
||||||
|
*/
|
||||||
|
public DepthOfFieldFilter() {
|
||||||
|
super("Depth Of Field");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isRequiresDepthTexture() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Material getMaterial() {
|
||||||
|
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initFilter(AssetManager assets, RenderManager renderManager,
|
||||||
|
ViewPort vp, int w, int h) {
|
||||||
|
material = new Material(assets, "Common/MatDefs/Post/DepthOfField.j3md");
|
||||||
|
material.setFloat("FocusDistance", focusDistance);
|
||||||
|
material.setFloat("FocusRange", focusRange);
|
||||||
|
|
||||||
|
|
||||||
|
xScale = 1.0f / w;
|
||||||
|
yScale = 1.0f / h;
|
||||||
|
|
||||||
|
material.setFloat("XScale", blurScale * xScale);
|
||||||
|
material.setFloat("YScale", blurScale * yScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the distance at which objects are purely in focus.
|
||||||
|
*/
|
||||||
|
public void setFocusDistance(float f) {
|
||||||
|
|
||||||
|
this.focusDistance = f;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("FocusDistance", focusDistance);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the focus distance
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getFocusDistance() {
|
||||||
|
return focusDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the range to either side of focusDistance where the
|
||||||
|
* objects go gradually out of focus. Less than focusDistance - focusRange
|
||||||
|
* and greater than focusDistance + focusRange, objects are maximally "blurred".
|
||||||
|
*/
|
||||||
|
public void setFocusRange(float f) {
|
||||||
|
this.focusRange = f;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("FocusRange", focusRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the focus range
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getFocusRange() {
|
||||||
|
return focusRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the blur amount by scaling the convolution filter up or
|
||||||
|
* down. A value of 1 (the default) performs a sparse 5x5 evenly
|
||||||
|
* distribubted convolution at pixel level accuracy. Higher values skip
|
||||||
|
* more pixels, and so on until you are no longer blurring the image
|
||||||
|
* but simply hashing it.
|
||||||
|
*
|
||||||
|
* The sparse convolution is as follows:
|
||||||
|
*%MINIFYHTMLc3d0cd9fab65de6875a381fd3f83e1b338%*
|
||||||
|
* Where 'x' is the texel being modified. Setting blur scale higher
|
||||||
|
* than 1 spaces the samples out.
|
||||||
|
*/
|
||||||
|
public void setBlurScale(float f) {
|
||||||
|
this.blurScale = f;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("XScale", blurScale * xScale);
|
||||||
|
material.setFloat("YScale", blurScale * yScale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the blur scale
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getBlurScale() {
|
||||||
|
return blurScale;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,95 @@
|
|||||||
|
package com.jme3.post.filters;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.post.Filter;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <a href="http://www.geeks3d.com/20110405/fxaa-fast-approximate-anti-aliasing-demo-glsl-opengl-test-radeon-geforce/3/" rel="nofollow">http://www.geeks3d.com/20110405/fxaa-fast-approximate-anti-aliasing-demo-glsl-<span class="domtooltips" title="OpenGL (Open Graphics Library) is a standard specification defining a cross-language, cross-platform API for writing applications that produce 2D and 3D computer graphics." id="domtooltipsspan11">opengl</span>-test-radeon-geforce/3/</a>
|
||||||
|
* <a href="http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf" rel="nofollow">http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf</a>
|
||||||
|
*
|
||||||
|
* @author Phate666 (adapted to jme3)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class FXAAFilter extends Filter {
|
||||||
|
|
||||||
|
private float subPixelShift = 1.0f / 4.0f;
|
||||||
|
private float vxOffset = 0.0f;
|
||||||
|
private float spanMax = 8.0f;
|
||||||
|
private float reduceMul = 1.0f / 8.0f;
|
||||||
|
|
||||||
|
public FXAAFilter() {
|
||||||
|
super("FXAAFilter");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initFilter(AssetManager manager,
|
||||||
|
RenderManager renderManager, ViewPort vp, int w, int h) {
|
||||||
|
material = new Material(manager, "Common/MatDefs/Post/FXAA.j3md");
|
||||||
|
material.setFloat("SubPixelShift", subPixelShift);
|
||||||
|
material.setFloat("VxOffset", vxOffset);
|
||||||
|
material.setFloat("SpanMax", spanMax);
|
||||||
|
material.setFloat("ReduceMul", reduceMul);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Material getMaterial() {
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSpanMax(float spanMax) {
|
||||||
|
this.spanMax = spanMax;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("SpanMax", this.spanMax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set to 0.0f for higher quality
|
||||||
|
*
|
||||||
|
* @param subPixelShift
|
||||||
|
*/
|
||||||
|
public void setSubPixelShift(float subPixelShift) {
|
||||||
|
this.subPixelShift = subPixelShift;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("SubPixelShif", this.subPixelShift);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set to 0.0f for higher quality
|
||||||
|
*
|
||||||
|
* @param reduceMul
|
||||||
|
*/
|
||||||
|
public void setReduceMul(float reduceMul) {
|
||||||
|
this.reduceMul = reduceMul;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("ReduceMul", this.reduceMul);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVxOffset(float vxOffset) {
|
||||||
|
this.vxOffset = vxOffset;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("VxOffset", this.vxOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getReduceMul() {
|
||||||
|
return reduceMul;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getSpanMax() {
|
||||||
|
return spanMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getSubPixelShift() {
|
||||||
|
return subPixelShift;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getVxOffset() {
|
||||||
|
return vxOffset;
|
||||||
|
}
|
||||||
|
}
|
177
engine/src/core-effects/com/jme3/post/filters/FadeFilter.java
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2010 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.post.filters;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.export.InputCapsule;
|
||||||
|
import com.jme3.export.JmeExporter;
|
||||||
|
import com.jme3.export.JmeImporter;
|
||||||
|
import com.jme3.export.OutputCapsule;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.post.Filter;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Fade Filter allows you to make an animated fade effect on a scene.
|
||||||
|
* @author Rémy Bouquet aka Nehon
|
||||||
|
* implemented from boxjar implementation
|
||||||
|
* @see <a href="http://jmonkeyengine.org/groups/graphics/forum/topic/newbie-question-general-fade-inout-effect/#post-105559">http://jmonkeyengine.org/groups/graphics/forum/topic/newbie-question-general-fade-inout-effect/#post-105559</a>
|
||||||
|
*/
|
||||||
|
public class FadeFilter extends Filter {
|
||||||
|
|
||||||
|
private float value = 1;
|
||||||
|
private boolean playing = false;
|
||||||
|
private float direction = 1;
|
||||||
|
private float duration = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a FadeFilter
|
||||||
|
*/
|
||||||
|
public FadeFilter() {
|
||||||
|
super("Fade In/Out");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a FadeFilter with the given duration
|
||||||
|
* @param duration
|
||||||
|
*/
|
||||||
|
public FadeFilter(float duration) {
|
||||||
|
this();
|
||||||
|
this.duration = duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Material getMaterial() {
|
||||||
|
material.setFloat("Value", value);
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
|
||||||
|
material = new Material(manager, "Common/MatDefs/Post/Fade.j3md");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void preFrame(float tpf) {
|
||||||
|
if (playing) {
|
||||||
|
value += tpf * direction / duration;
|
||||||
|
|
||||||
|
if (direction > 0 && value > 1) {
|
||||||
|
value = 1;
|
||||||
|
playing = false;
|
||||||
|
setEnabled(false);
|
||||||
|
}
|
||||||
|
if (direction < 0 && value < 0) {
|
||||||
|
value = 0;
|
||||||
|
playing = false;
|
||||||
|
setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the duration of the effect
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getDuration() {
|
||||||
|
return duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the duration of the filter default is 1 second
|
||||||
|
* @param duration
|
||||||
|
*/
|
||||||
|
public void setDuration(float duration) {
|
||||||
|
this.duration = duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fades the scene in (black to scene)
|
||||||
|
*/
|
||||||
|
public void fadeIn() {
|
||||||
|
setEnabled(true);
|
||||||
|
direction = 1;
|
||||||
|
playing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fades the scene out (scene to black)
|
||||||
|
*/
|
||||||
|
public void fadeOut() {
|
||||||
|
setEnabled(true);
|
||||||
|
direction = -1;
|
||||||
|
playing = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pause() {
|
||||||
|
playing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JmeExporter ex) throws IOException {
|
||||||
|
super.write(ex);
|
||||||
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
|
oc.write(duration, "duration", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(JmeImporter im) throws IOException {
|
||||||
|
super.read(im);
|
||||||
|
InputCapsule ic = im.getCapsule(this);
|
||||||
|
duration = ic.readFloat("duration", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the current value of the fading
|
||||||
|
* can be used to chack if fade is complete (eg value=1)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the fade value
|
||||||
|
* can be used to force complete black or compete scene
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
public void setValue(float value) {
|
||||||
|
this.value = value;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("Value", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
172
engine/src/core-effects/com/jme3/post/filters/FogFilter.java
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.post.filters;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.export.InputCapsule;
|
||||||
|
import com.jme3.export.JmeExporter;
|
||||||
|
import com.jme3.export.JmeImporter;
|
||||||
|
import com.jme3.export.OutputCapsule;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
|
import com.jme3.post.Filter;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A filter to render a fog effect
|
||||||
|
* @author Rémy Bouquet aka Nehon
|
||||||
|
*/
|
||||||
|
public class FogFilter extends Filter {
|
||||||
|
|
||||||
|
private ColorRGBA fogColor = ColorRGBA.White.clone();
|
||||||
|
private float fogDensity = 0.7f;
|
||||||
|
private float fogDistance = 1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a FogFilter
|
||||||
|
*/
|
||||||
|
public FogFilter() {
|
||||||
|
super("FogFilter");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a fog filter
|
||||||
|
* @param fogColor the color of the fog (default is white)
|
||||||
|
* @param fogDensity the density of the fog (default is 0.7)
|
||||||
|
* @param fogDistance the distance of the fog (default is 1000)
|
||||||
|
*/
|
||||||
|
public FogFilter(ColorRGBA fogColor, float fogDensity, float fogDistance) {
|
||||||
|
this();
|
||||||
|
this.fogColor = fogColor;
|
||||||
|
this.fogDensity = fogDensity;
|
||||||
|
this.fogDistance = fogDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isRequiresDepthTexture() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
|
||||||
|
material = new Material(manager, "Common/MatDefs/Post/Fog.j3md");
|
||||||
|
material.setColor("FogColor", fogColor);
|
||||||
|
material.setFloat("FogDensity", fogDensity);
|
||||||
|
material.setFloat("FogDistance", fogDistance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Material getMaterial() {
|
||||||
|
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the fog color
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ColorRGBA getFogColor() {
|
||||||
|
return fogColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the color of the fog
|
||||||
|
* @param fogColor
|
||||||
|
*/
|
||||||
|
public void setFogColor(ColorRGBA fogColor) {
|
||||||
|
if (material != null) {
|
||||||
|
material.setColor("FogColor", fogColor);
|
||||||
|
}
|
||||||
|
this.fogColor = fogColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the fog density
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getFogDensity() {
|
||||||
|
return fogDensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the density of the fog, a high value gives a thick fog
|
||||||
|
* @param fogDensity
|
||||||
|
*/
|
||||||
|
public void setFogDensity(float fogDensity) {
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("FogDensity", fogDensity);
|
||||||
|
}
|
||||||
|
this.fogDensity = fogDensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the fog distance
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getFogDistance() {
|
||||||
|
return fogDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the distance of the fog. the higer the value the distant the fog looks
|
||||||
|
* @param fogDistance
|
||||||
|
*/
|
||||||
|
public void setFogDistance(float fogDistance) {
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("FogDistance", fogDistance);
|
||||||
|
}
|
||||||
|
this.fogDistance = fogDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JmeExporter ex) throws IOException {
|
||||||
|
super.write(ex);
|
||||||
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
|
oc.write(fogColor, "fogColor", ColorRGBA.White.clone());
|
||||||
|
oc.write(fogDensity, "fogDensity", 0.7f);
|
||||||
|
oc.write(fogDistance, "fogDistance", 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(JmeImporter im) throws IOException {
|
||||||
|
super.read(im);
|
||||||
|
InputCapsule ic = im.getCapsule(this);
|
||||||
|
fogColor = (ColorRGBA) ic.readSavable("fogColor", ColorRGBA.White.clone());
|
||||||
|
fogDensity = ic.readFloat("fogDensity", 0.7f);
|
||||||
|
fogDistance = ic.readFloat("fogDistance", 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
package com.jme3.post.filters;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.post.Filter;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Phate666
|
||||||
|
* @version 1.0 initial version
|
||||||
|
* @version 1.1 added luma
|
||||||
|
*/
|
||||||
|
public class GammaCorrectionFilter extends Filter
|
||||||
|
{
|
||||||
|
private float gamma = 2.0f;
|
||||||
|
private boolean computeLuma = false;
|
||||||
|
|
||||||
|
public GammaCorrectionFilter()
|
||||||
|
{
|
||||||
|
super("GammaCorrectionFilter");
|
||||||
|
}
|
||||||
|
|
||||||
|
public GammaCorrectionFilter(float gamma)
|
||||||
|
{
|
||||||
|
this();
|
||||||
|
this.setGamma(gamma);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Material getMaterial()
|
||||||
|
{
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initFilter(AssetManager manager,
|
||||||
|
RenderManager renderManager, ViewPort vp, int w, int h)
|
||||||
|
{
|
||||||
|
material = new Material(manager,
|
||||||
|
"Common/MatDefs/Post/GammaCorrection.j3md");
|
||||||
|
material.setFloat("gamma", gamma);
|
||||||
|
material.setBoolean("computeLuma", computeLuma);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getGamma()
|
||||||
|
{
|
||||||
|
return gamma;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set to 0.0 to disable gamma correction
|
||||||
|
* @param gamma
|
||||||
|
*/
|
||||||
|
public void setGamma(float gamma)
|
||||||
|
{
|
||||||
|
if (material != null)
|
||||||
|
{
|
||||||
|
material.setFloat("gamma", gamma);
|
||||||
|
}
|
||||||
|
this.gamma = gamma;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isComputeLuma()
|
||||||
|
{
|
||||||
|
return computeLuma;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setComputeLuma(boolean computeLuma)
|
||||||
|
{
|
||||||
|
if (material != null)
|
||||||
|
{
|
||||||
|
material.setBoolean("computeLuma", computeLuma);
|
||||||
|
}
|
||||||
|
this.computeLuma = computeLuma;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,243 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2010 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.post.filters;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.export.InputCapsule;
|
||||||
|
import com.jme3.export.JmeExporter;
|
||||||
|
import com.jme3.export.JmeImporter;
|
||||||
|
import com.jme3.export.OutputCapsule;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.post.Filter;
|
||||||
|
import com.jme3.renderer.Camera;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LightScattering filters creates rays comming from a light sources
|
||||||
|
* This is often reffered as god rays.
|
||||||
|
*
|
||||||
|
* @author Rémy Bouquet aka Nehon
|
||||||
|
*/
|
||||||
|
public class LightScatteringFilter extends Filter {
|
||||||
|
|
||||||
|
private Vector3f lightPosition;
|
||||||
|
private Vector3f screenLightPos = new Vector3f();
|
||||||
|
private int nbSamples = 50;
|
||||||
|
private float blurStart = 0.02f;
|
||||||
|
private float blurWidth = 0.9f;
|
||||||
|
private float lightDensity = 1.4f;
|
||||||
|
private boolean adaptative = true;
|
||||||
|
Vector3f viewLightPos = new Vector3f();
|
||||||
|
private boolean display = true;
|
||||||
|
private float innerLightDensity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a lightScaterring filter
|
||||||
|
*/
|
||||||
|
public LightScatteringFilter() {
|
||||||
|
super("Light Scattering");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a lightScatteringFilter
|
||||||
|
* @param lightPosition
|
||||||
|
*/
|
||||||
|
public LightScatteringFilter(Vector3f lightPosition) {
|
||||||
|
this();
|
||||||
|
this.lightPosition = lightPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isRequiresDepthTexture() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Material getMaterial() {
|
||||||
|
material.setVector3("LightPosition", screenLightPos);
|
||||||
|
material.setInt("NbSamples", nbSamples);
|
||||||
|
material.setFloat("BlurStart", blurStart);
|
||||||
|
material.setFloat("BlurWidth", blurWidth);
|
||||||
|
material.setFloat("LightDensity", innerLightDensity);
|
||||||
|
material.setBoolean("Display", display);
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void postQueue(RenderManager renderManager, ViewPort viewPort) {
|
||||||
|
getClipCoordinates(lightPosition, screenLightPos, viewPort.getCamera());
|
||||||
|
// screenLightPos.x = screenLightPos.x / viewPort.getCamera().getWidth();
|
||||||
|
// screenLightPos.y = screenLightPos.y / viewPort.getCamera().getHeight();
|
||||||
|
|
||||||
|
viewPort.getCamera().getViewMatrix().mult(lightPosition, viewLightPos);
|
||||||
|
//System.err.println("viewLightPos "+viewLightPos);
|
||||||
|
display = screenLightPos.x < 1.6f && screenLightPos.x > -0.6f && screenLightPos.y < 1.6f && screenLightPos.y > -0.6f && viewLightPos.z < 0;
|
||||||
|
//System.err.println("camdir "+viewPort.getCamera().getDirection());
|
||||||
|
//System.err.println("lightPos "+lightPosition);
|
||||||
|
//System.err.println("screenLightPos "+screenLightPos);
|
||||||
|
if (adaptative) {
|
||||||
|
innerLightDensity = Math.max(lightDensity - Math.max(screenLightPos.x, screenLightPos.y), 0.0f);
|
||||||
|
} else {
|
||||||
|
innerLightDensity = lightDensity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vector3f getClipCoordinates(Vector3f worldPosition, Vector3f store, Camera cam) {
|
||||||
|
|
||||||
|
float w = cam.getViewProjectionMatrix().multProj(worldPosition, store);
|
||||||
|
store.divideLocal(w);
|
||||||
|
|
||||||
|
store.x = ((store.x + 1f) * (cam.getViewPortRight() - cam.getViewPortLeft()) / 2f + cam.getViewPortLeft());
|
||||||
|
store.y = ((store.y + 1f) * (cam.getViewPortTop() - cam.getViewPortBottom()) / 2f + cam.getViewPortBottom());
|
||||||
|
store.z = (store.z + 1f) / 2f;
|
||||||
|
|
||||||
|
return store;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
|
||||||
|
material = new Material(manager, "Common/MatDefs/Post/LightScattering.j3md");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the blur start of the scattering
|
||||||
|
* see {@link setBlurStart(float blurStart)}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getBlurStart() {
|
||||||
|
return blurStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the blur start<br>
|
||||||
|
* at which distance from the light source the effect starts default is 0.02
|
||||||
|
* @param blurStart
|
||||||
|
*/
|
||||||
|
public void setBlurStart(float blurStart) {
|
||||||
|
this.blurStart = blurStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the blur width<br>
|
||||||
|
* see {@link setBlurWidth(float blurWidth)}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getBlurWidth() {
|
||||||
|
return blurWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the blur width default is 0.9
|
||||||
|
* @param blurWidth
|
||||||
|
*/
|
||||||
|
public void setBlurWidth(float blurWidth) {
|
||||||
|
this.blurWidth = blurWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retiurns the light density<br>
|
||||||
|
* see {@link setLightDensity(float lightDensity)}
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getLightDensity() {
|
||||||
|
return lightDensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets how much the effect is visible over the rendered scene default is 1.4
|
||||||
|
* @param lightDensity
|
||||||
|
*/
|
||||||
|
public void setLightDensity(float lightDensity) {
|
||||||
|
this.lightDensity = lightDensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the light position
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Vector3f getLightPosition() {
|
||||||
|
return lightPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the light position
|
||||||
|
* @param lightPosition
|
||||||
|
*/
|
||||||
|
public void setLightPosition(Vector3f lightPosition) {
|
||||||
|
this.lightPosition = lightPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the nmber of samples for the radial blur
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getNbSamples() {
|
||||||
|
return nbSamples;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the number of samples for the radial blur default is 50
|
||||||
|
* the higher the value the higher the quality, but the slower the performances.
|
||||||
|
* @param nbSamples
|
||||||
|
*/
|
||||||
|
public void setNbSamples(int nbSamples) {
|
||||||
|
this.nbSamples = nbSamples;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JmeExporter ex) throws IOException {
|
||||||
|
super.write(ex);
|
||||||
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
|
oc.write(lightPosition, "lightPosition", Vector3f.ZERO);
|
||||||
|
oc.write(nbSamples, "nbSamples", 50);
|
||||||
|
oc.write(blurStart, "blurStart", 0.02f);
|
||||||
|
oc.write(blurWidth, "blurWidth", 0.9f);
|
||||||
|
oc.write(lightDensity, "lightDensity", 1.4f);
|
||||||
|
oc.write(adaptative, "adaptative", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(JmeImporter im) throws IOException {
|
||||||
|
super.read(im);
|
||||||
|
InputCapsule ic = im.getCapsule(this);
|
||||||
|
lightPosition = (Vector3f) ic.readSavable("lightPosition", Vector3f.ZERO);
|
||||||
|
nbSamples = ic.readInt("nbSamples", 50);
|
||||||
|
blurStart = ic.readFloat("blurStart", 0.02f);
|
||||||
|
blurWidth = ic.readFloat("blurWidth", 0.9f);
|
||||||
|
lightDensity = ic.readFloat("lightDensity", 1.4f);
|
||||||
|
adaptative = ic.readBoolean("adaptative", true);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2010 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.post.filters;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.post.Filter;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Post Processing filter to change colors appear with sharp edges as if the
|
||||||
|
* available amount of colors available was not enough to draw the true image.
|
||||||
|
* Possibly useful in cartoon styled games. Use the strength variable to lessen
|
||||||
|
* influence of this filter on the total result. Values from 0.2 to 0.7 appear
|
||||||
|
* to give nice results.
|
||||||
|
*
|
||||||
|
* Based on an article from Geeks3D:
|
||||||
|
* <a href="http://www.geeks3d.com/20091027/shader-library-posterization-post-processing-effect-glsl/" rel="nofollow">http://www.geeks3d.com/20091027/shader-library-posterization-post-processing-effect-glsl/</a>
|
||||||
|
*
|
||||||
|
* @author: Roy Straver a.k.a. Baal Garnaal
|
||||||
|
*/
|
||||||
|
public class PosterizationFilter extends Filter {
|
||||||
|
|
||||||
|
private int numColors = 8;
|
||||||
|
private float gamma = 0.6f;
|
||||||
|
private float strength = 1.0f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a posterization Filter
|
||||||
|
*/
|
||||||
|
public PosterizationFilter() {
|
||||||
|
super("PosterizationFilter");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a posterization Filter with the given number of colors
|
||||||
|
* @param numColors
|
||||||
|
*/
|
||||||
|
public PosterizationFilter(int numColors) {
|
||||||
|
this();
|
||||||
|
this.numColors = numColors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a posterization Filter with the given number of colors and gamma
|
||||||
|
* @param numColors
|
||||||
|
* @param gamma
|
||||||
|
*/
|
||||||
|
public PosterizationFilter(int numColors, float gamma) {
|
||||||
|
this(numColors);
|
||||||
|
this.gamma = gamma;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
|
||||||
|
material = new Material(manager, "Common/MatDefs/Post/Posterization.j3md");
|
||||||
|
material.setInt("NumColors", numColors);
|
||||||
|
material.setFloat("Gamma", gamma);
|
||||||
|
material.setFloat("Strength", strength);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Material getMaterial() {
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets number of color levels used to draw the screen
|
||||||
|
*/
|
||||||
|
public void setNumColors(int numColors) {
|
||||||
|
this.numColors = numColors;
|
||||||
|
if (material != null) {
|
||||||
|
material.setInt("NumColors", numColors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets gamma level used to enhange visual quality
|
||||||
|
*/
|
||||||
|
public void setGamma(float gamma) {
|
||||||
|
this.gamma = gamma;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("Gamma", gamma);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets urrent strength value, i.e. influence on final image
|
||||||
|
*/
|
||||||
|
public void setStrength(float strength) {
|
||||||
|
this.strength = strength;
|
||||||
|
if (material != null) {
|
||||||
|
material.setFloat("Strength", strength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns number of color levels used
|
||||||
|
*/
|
||||||
|
public int getNumColors() {
|
||||||
|
return numColors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns current gamma value
|
||||||
|
*/
|
||||||
|
public float getGamma() {
|
||||||
|
return gamma;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns current strength value, i.e. influence on final image
|
||||||
|
*/
|
||||||
|
public float getStrength() {
|
||||||
|
return strength;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.post.filters;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.export.InputCapsule;
|
||||||
|
import com.jme3.export.JmeExporter;
|
||||||
|
import com.jme3.export.JmeImporter;
|
||||||
|
import com.jme3.export.OutputCapsule;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.post.Filter;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.shader.VarType;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Radially blurs the scene from the center of it
|
||||||
|
* @author Rémy Bouquet aka Nehon
|
||||||
|
*/
|
||||||
|
public class RadialBlurFilter extends Filter {
|
||||||
|
|
||||||
|
private float sampleDist = 1.0f;
|
||||||
|
private float sampleStrength = 2.2f;
|
||||||
|
private float[] samples = {-0.08f, -0.05f, -0.03f, -0.02f, -0.01f, 0.01f, 0.02f, 0.03f, 0.05f, 0.08f};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a RadialBlurFilter
|
||||||
|
*/
|
||||||
|
public RadialBlurFilter() {
|
||||||
|
super("Radial blur");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a RadialBlurFilter
|
||||||
|
* @param sampleDist the distance between samples
|
||||||
|
* @param sampleStrength the strenght of each sample
|
||||||
|
*/
|
||||||
|
public RadialBlurFilter(float sampleDist, float sampleStrength) {
|
||||||
|
this();
|
||||||
|
this.sampleDist = sampleDist;
|
||||||
|
this.sampleStrength = sampleStrength;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Material getMaterial() {
|
||||||
|
|
||||||
|
material.setFloat("SampleDist", sampleDist);
|
||||||
|
material.setFloat("SampleStrength", sampleStrength);
|
||||||
|
material.setParam("Samples", VarType.FloatArray, samples);
|
||||||
|
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the sample distance
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getSampleDistance() {
|
||||||
|
return sampleDist;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the samples distances default is 1
|
||||||
|
* @param sampleDist
|
||||||
|
*/
|
||||||
|
public void setSampleDistance(float sampleDist) {
|
||||||
|
this.sampleDist = sampleDist;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @deprecated use {@link #getSampleDistance()}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public float getSampleDist() {
|
||||||
|
return sampleDist;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param sampleDist
|
||||||
|
* @deprecated use {@link #setSampleDistance(float sampleDist)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void setSampleDist(float sampleDist) {
|
||||||
|
this.sampleDist = sampleDist;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the sample Strength
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getSampleStrength() {
|
||||||
|
return sampleStrength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the sample streanght default is 2.2
|
||||||
|
* @param sampleStrength
|
||||||
|
*/
|
||||||
|
public void setSampleStrength(float sampleStrength) {
|
||||||
|
this.sampleStrength = sampleStrength;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
|
||||||
|
material = new Material(manager, "Common/MatDefs/Blur/RadialBlur.j3md");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JmeExporter ex) throws IOException {
|
||||||
|
super.write(ex);
|
||||||
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
|
oc.write(sampleDist, "sampleDist", 1.0f);
|
||||||
|
oc.write(sampleStrength, "sampleStrength", 2.2f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(JmeImporter im) throws IOException {
|
||||||
|
super.read(im);
|
||||||
|
InputCapsule ic = im.getCapsule(this);
|
||||||
|
sampleDist = ic.readFloat("sampleDist", 1.0f);
|
||||||
|
sampleStrength = ic.readFloat("sampleStrength", 2.2f);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* To change this template, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package com.jme3.post.filters;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
|
import com.jme3.post.Filter;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.Renderer;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.renderer.queue.RenderQueue;
|
||||||
|
import com.jme3.texture.FrameBuffer;
|
||||||
|
import com.jme3.texture.Texture2D;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A filter to handle translucent objects when rendering a scene with filters that uses depth like WaterFilter and SSAOFilter
|
||||||
|
* just create a TranslucentBucketFilter and add it to the Filter list of a FilterPostPorcessor
|
||||||
|
* @author Nehon
|
||||||
|
*/
|
||||||
|
public final class TranslucentBucketFilter extends Filter {
|
||||||
|
|
||||||
|
private RenderManager renderManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initFilter(AssetManager manager, RenderManager rm, ViewPort vp, int w, int h) {
|
||||||
|
this.renderManager = rm;
|
||||||
|
material = new Material(manager, "Common/MatDefs/Post/Overlay.j3md");
|
||||||
|
material.setColor("Color", ColorRGBA.White);
|
||||||
|
Texture2D tex = processor.getFilterTexture();
|
||||||
|
material.setTexture("Texture", tex);
|
||||||
|
if (tex.getImage().getMultiSamples() > 1) {
|
||||||
|
material.setInt("NumSamples", tex.getImage().getMultiSamples());
|
||||||
|
} else {
|
||||||
|
material.clearParam("NumSamples");
|
||||||
|
}
|
||||||
|
renderManager.setHandleTranslucentBucket(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this method and return false if your Filter does not need the scene texture
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected boolean isRequiresSceneTexture() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void postFrame(RenderManager renderManager, ViewPort viewPort, FrameBuffer prevFilterBuffer, FrameBuffer sceneBuffer) {
|
||||||
|
renderManager.setCamera(viewPort.getCamera(), false);
|
||||||
|
if (prevFilterBuffer != sceneBuffer) {
|
||||||
|
renderManager.getRenderer().copyFrameBuffer(prevFilterBuffer, sceneBuffer, false);
|
||||||
|
}
|
||||||
|
renderManager.getRenderer().setFrameBuffer(sceneBuffer);
|
||||||
|
viewPort.getQueue().renderQueue(RenderQueue.Bucket.Translucent, renderManager, viewPort.getCamera());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void cleanUpFilter(Renderer r) {
|
||||||
|
if (renderManager != null) {
|
||||||
|
renderManager.setHandleTranslucentBucket(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Material getMaterial() {
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
super.setEnabled(enabled);
|
||||||
|
if (renderManager != null) {
|
||||||
|
renderManager.setHandleTranslucentBucket(!enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
324
engine/src/core-effects/com/jme3/post/ssao/SSAOFilter.java
Normal file
@ -0,0 +1,324 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.post.ssao;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.export.InputCapsule;
|
||||||
|
import com.jme3.export.JmeExporter;
|
||||||
|
import com.jme3.export.JmeImporter;
|
||||||
|
import com.jme3.export.OutputCapsule;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.math.Vector2f;
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.post.Filter;
|
||||||
|
import com.jme3.post.Filter.Pass;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.Renderer;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.shader.VarType;
|
||||||
|
import com.jme3.texture.Image.Format;
|
||||||
|
import com.jme3.texture.Texture;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SSAO stands for screen space ambient occlusion
|
||||||
|
* It's a technique that fake ambient lighting by computing shadows that near by objects would casts on each others
|
||||||
|
* under the effect of an ambient light
|
||||||
|
* more info on this in this blog post <a href="http://jmonkeyengine.org/2010/08/16/screen-space-ambient-occlusion-for-jmonkeyengine-3-0/">http://jmonkeyengine.org/2010/08/16/screen-space-ambient-occlusion-for-jmonkeyengine-3-0/</a>
|
||||||
|
*
|
||||||
|
* @author Rémy Bouquet aka Nehon
|
||||||
|
*/
|
||||||
|
public class SSAOFilter extends Filter {
|
||||||
|
|
||||||
|
private Pass normalPass;
|
||||||
|
private Vector3f frustumCorner;
|
||||||
|
private Vector2f frustumNearFar;
|
||||||
|
private Vector2f[] samples = {new Vector2f(1.0f, 0.0f), new Vector2f(-1.0f, 0.0f), new Vector2f(0.0f, 1.0f), new Vector2f(0.0f, -1.0f)};
|
||||||
|
private float sampleRadius = 5.1f;
|
||||||
|
private float intensity = 1.5f;
|
||||||
|
private float scale = 0.2f;
|
||||||
|
private float bias = 0.1f;
|
||||||
|
private boolean useOnlyAo = false;
|
||||||
|
private boolean useAo = true;
|
||||||
|
private Material ssaoMat;
|
||||||
|
private Pass ssaoPass;
|
||||||
|
// private Material downSampleMat;
|
||||||
|
// private Pass downSamplePass;
|
||||||
|
private float downSampleFactor = 1f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a Screen Space Ambient Occlusion Filter
|
||||||
|
*/
|
||||||
|
public SSAOFilter() {
|
||||||
|
super("SSAOFilter");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a Screen Space Ambient Occlusion Filter
|
||||||
|
* @param sampleRadius The radius of the area where random samples will be picked. default 5.1f
|
||||||
|
* @param intensity intensity of the resulting AO. default 1.2f
|
||||||
|
* @param scale distance between occluders and occludee. default 0.2f
|
||||||
|
* @param bias the width of the occlusion cone considered by the occludee. default 0.1f
|
||||||
|
*/
|
||||||
|
public SSAOFilter(float sampleRadius, float intensity, float scale, float bias) {
|
||||||
|
this();
|
||||||
|
this.sampleRadius = sampleRadius;
|
||||||
|
this.intensity = intensity;
|
||||||
|
this.scale = scale;
|
||||||
|
this.bias = bias;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isRequiresDepthTexture() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void postQueue(RenderManager renderManager, ViewPort viewPort) {
|
||||||
|
Renderer r = renderManager.getRenderer();
|
||||||
|
r.setFrameBuffer(normalPass.getRenderFrameBuffer());
|
||||||
|
renderManager.getRenderer().clearBuffers(true, true, true);
|
||||||
|
renderManager.setForcedTechnique("PreNormalPass");
|
||||||
|
renderManager.renderViewPortQueues(viewPort, false);
|
||||||
|
renderManager.setForcedTechnique(null);
|
||||||
|
renderManager.getRenderer().setFrameBuffer(viewPort.getOutputFrameBuffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Material getMaterial() {
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
|
||||||
|
int screenWidth = w;
|
||||||
|
int screenHeight = h;
|
||||||
|
postRenderPasses = new ArrayList<Pass>();
|
||||||
|
|
||||||
|
normalPass = new Pass();
|
||||||
|
normalPass.init(renderManager.getRenderer(), (int) (screenWidth / downSampleFactor), (int) (screenHeight / downSampleFactor), Format.RGBA8, Format.Depth);
|
||||||
|
|
||||||
|
|
||||||
|
frustumNearFar = new Vector2f();
|
||||||
|
|
||||||
|
float farY = (vp.getCamera().getFrustumTop() / vp.getCamera().getFrustumNear()) * vp.getCamera().getFrustumFar();
|
||||||
|
float farX = farY * ((float) screenWidth / (float) screenHeight);
|
||||||
|
frustumCorner = new Vector3f(farX, farY, vp.getCamera().getFrustumFar());
|
||||||
|
frustumNearFar.x = vp.getCamera().getFrustumNear();
|
||||||
|
frustumNearFar.y = vp.getCamera().getFrustumFar();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//ssao Pass
|
||||||
|
ssaoMat = new Material(manager, "Common/MatDefs/SSAO/ssao.j3md");
|
||||||
|
ssaoMat.setTexture("Normals", normalPass.getRenderedTexture());
|
||||||
|
Texture random = manager.loadTexture("Common/MatDefs/SSAO/Textures/random.png");
|
||||||
|
random.setWrap(Texture.WrapMode.Repeat);
|
||||||
|
ssaoMat.setTexture("RandomMap", random);
|
||||||
|
|
||||||
|
ssaoPass = new Pass() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresDepthAsTexture() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ssaoPass.init(renderManager.getRenderer(), (int) (screenWidth / downSampleFactor), (int) (screenHeight / downSampleFactor), Format.RGBA8, Format.Depth, 1, ssaoMat);
|
||||||
|
ssaoPass.getRenderedTexture().setMinFilter(Texture.MinFilter.Trilinear);
|
||||||
|
ssaoPass.getRenderedTexture().setMagFilter(Texture.MagFilter.Bilinear);
|
||||||
|
postRenderPasses.add(ssaoPass);
|
||||||
|
material = new Material(manager, "Common/MatDefs/SSAO/ssaoBlur.j3md");
|
||||||
|
material.setTexture("SSAOMap", ssaoPass.getRenderedTexture());
|
||||||
|
|
||||||
|
ssaoMat.setVector3("FrustumCorner", frustumCorner);
|
||||||
|
ssaoMat.setFloat("SampleRadius", sampleRadius);
|
||||||
|
ssaoMat.setFloat("Intensity", intensity);
|
||||||
|
ssaoMat.setFloat("Scale", scale);
|
||||||
|
ssaoMat.setFloat("Bias", bias);
|
||||||
|
material.setBoolean("UseAo", useAo);
|
||||||
|
material.setBoolean("UseOnlyAo", useOnlyAo);
|
||||||
|
ssaoMat.setVector2("FrustumNearFar", frustumNearFar);
|
||||||
|
material.setVector2("FrustumNearFar", frustumNearFar);
|
||||||
|
ssaoMat.setParam("Samples", VarType.Vector2Array, samples);
|
||||||
|
|
||||||
|
float xScale = 1.0f / w;
|
||||||
|
float yScale = 1.0f / h;
|
||||||
|
|
||||||
|
float blurScale = 2f;
|
||||||
|
material.setFloat("XScale", blurScale * xScale);
|
||||||
|
material.setFloat("YScale", blurScale * yScale);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the bias<br>
|
||||||
|
* see {@link #setBias(float bias)}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getBias() {
|
||||||
|
return bias;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the the width of the occlusion cone considered by the occludee default is 0.1f
|
||||||
|
* @param bias
|
||||||
|
*/
|
||||||
|
public void setBias(float bias) {
|
||||||
|
this.bias = bias;
|
||||||
|
if (ssaoMat != null) {
|
||||||
|
ssaoMat.setFloat("Bias", bias);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the ambient occlusion intensity
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getIntensity() {
|
||||||
|
return intensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the Ambient occlusion intensity default is 1.2f
|
||||||
|
* @param intensity
|
||||||
|
*/
|
||||||
|
public void setIntensity(float intensity) {
|
||||||
|
this.intensity = intensity;
|
||||||
|
if (ssaoMat != null) {
|
||||||
|
ssaoMat.setFloat("Intensity", intensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the sample radius<br>
|
||||||
|
* see {link setSampleRadius(float sampleRadius)}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getSampleRadius() {
|
||||||
|
return sampleRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the radius of the area where random samples will be picked dafault 5.1f
|
||||||
|
* @param sampleRadius
|
||||||
|
*/
|
||||||
|
public void setSampleRadius(float sampleRadius) {
|
||||||
|
this.sampleRadius = sampleRadius;
|
||||||
|
if (ssaoMat != null) {
|
||||||
|
ssaoMat.setFloat("SampleRadius", sampleRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the scale<br>
|
||||||
|
* see {@link #setScale(float scale)}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getScale() {
|
||||||
|
return scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Returns the distance between occluders and occludee. default 0.2f
|
||||||
|
* @param scale
|
||||||
|
*/
|
||||||
|
public void setScale(float scale) {
|
||||||
|
this.scale = scale;
|
||||||
|
if (ssaoMat != null) {
|
||||||
|
ssaoMat.setFloat("Scale", scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* debugging only , will be removed
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isUseAo() {
|
||||||
|
return useAo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* debugging only , will be removed
|
||||||
|
*/
|
||||||
|
public void setUseAo(boolean useAo) {
|
||||||
|
this.useAo = useAo;
|
||||||
|
if (material != null) {
|
||||||
|
material.setBoolean("UseAo", useAo);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* debugging only , will be removed
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isUseOnlyAo() {
|
||||||
|
return useOnlyAo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* debugging only , will be removed
|
||||||
|
*/
|
||||||
|
public void setUseOnlyAo(boolean useOnlyAo) {
|
||||||
|
this.useOnlyAo = useOnlyAo;
|
||||||
|
if (material != null) {
|
||||||
|
material.setBoolean("UseOnlyAo", useOnlyAo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JmeExporter ex) throws IOException {
|
||||||
|
super.write(ex);
|
||||||
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
|
oc.write(sampleRadius, "sampleRadius", 5.1f);
|
||||||
|
oc.write(intensity, "intensity", 1.5f);
|
||||||
|
oc.write(scale, "scale", 0.2f);
|
||||||
|
oc.write(bias, "bias", 0.1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(JmeImporter im) throws IOException {
|
||||||
|
super.read(im);
|
||||||
|
InputCapsule ic = im.getCapsule(this);
|
||||||
|
sampleRadius = ic.readFloat("sampleRadius", 5.1f);
|
||||||
|
intensity = ic.readFloat("intensity", 1.5f);
|
||||||
|
scale = ic.readFloat("scale", 0.2f);
|
||||||
|
bias = ic.readFloat("bias", 0.1f);
|
||||||
|
}
|
||||||
|
}
|
125
engine/src/core-effects/com/jme3/water/ReflectionProcessor.java
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* To change this template, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package com.jme3.water;
|
||||||
|
|
||||||
|
import com.jme3.math.Plane;
|
||||||
|
import com.jme3.post.SceneProcessor;
|
||||||
|
import com.jme3.renderer.Camera;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.renderer.queue.RenderQueue;
|
||||||
|
import com.jme3.texture.FrameBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reflection Processor
|
||||||
|
* Used to render the reflected scene in an off view port
|
||||||
|
*/
|
||||||
|
public class ReflectionProcessor implements SceneProcessor {
|
||||||
|
|
||||||
|
private RenderManager rm;
|
||||||
|
private ViewPort vp;
|
||||||
|
private Camera reflectionCam;
|
||||||
|
private FrameBuffer reflectionBuffer;
|
||||||
|
private Plane reflectionClipPlane;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a ReflectionProcessor
|
||||||
|
* @param reflectionCam the cam to use for reflection
|
||||||
|
* @param reflectionBuffer the FrameBuffer to render to
|
||||||
|
* @param reflectionClipPlane the clipping plane
|
||||||
|
*/
|
||||||
|
public ReflectionProcessor(Camera reflectionCam, FrameBuffer reflectionBuffer, Plane reflectionClipPlane) {
|
||||||
|
this.reflectionCam = reflectionCam;
|
||||||
|
this.reflectionBuffer = reflectionBuffer;
|
||||||
|
this.reflectionClipPlane = reflectionClipPlane;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initialize(RenderManager rm, ViewPort vp) {
|
||||||
|
this.rm = rm;
|
||||||
|
this.vp = vp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reshape(ViewPort vp, int w, int h) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInitialized() {
|
||||||
|
return rm != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void preFrame(float tpf) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postQueue(RenderQueue rq) {
|
||||||
|
//we need special treatement for the sky because it must not be clipped
|
||||||
|
rm.getRenderer().setFrameBuffer(reflectionBuffer);
|
||||||
|
reflectionCam.setProjectionMatrix(null);
|
||||||
|
rm.setCamera(reflectionCam, false);
|
||||||
|
rm.getRenderer().clearBuffers(true, true, true);
|
||||||
|
//Rendering the sky whithout clipping
|
||||||
|
rm.getRenderer().setDepthRange(1, 1);
|
||||||
|
vp.getQueue().renderQueue(RenderQueue.Bucket.Sky, rm, reflectionCam, true);
|
||||||
|
rm.getRenderer().setDepthRange(0, 1);
|
||||||
|
//setting the clip plane to the cam
|
||||||
|
reflectionCam.setClipPlane(reflectionClipPlane, Plane.Side.Positive);//,1
|
||||||
|
rm.setCamera(reflectionCam, false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postFrame(FrameBuffer out) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cleanup() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal use only<br>
|
||||||
|
* returns the frame buffer
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public FrameBuffer getReflectionBuffer() {
|
||||||
|
return reflectionBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal use only<br>
|
||||||
|
* sets the frame buffer
|
||||||
|
* @param reflectionBuffer
|
||||||
|
*/
|
||||||
|
public void setReflectionBuffer(FrameBuffer reflectionBuffer) {
|
||||||
|
this.reflectionBuffer = reflectionBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the reflection cam
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Camera getReflectionCam() {
|
||||||
|
return reflectionCam;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the reflection cam
|
||||||
|
* @param reflectionCam
|
||||||
|
*/
|
||||||
|
public void setReflectionCam(Camera reflectionCam) {
|
||||||
|
this.reflectionCam = reflectionCam;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the reflection clip plane
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Plane getReflectionClipPlane() {
|
||||||
|
return reflectionClipPlane;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the reflection clip plane
|
||||||
|
* @param reflectionClipPlane
|
||||||
|
*/
|
||||||
|
public void setReflectionClipPlane(Plane reflectionClipPlane) {
|
||||||
|
this.reflectionClipPlane = reflectionClipPlane;
|
||||||
|
}
|
||||||
|
}
|
589
engine/src/core-effects/com/jme3/water/SimpleWaterProcessor.java
Normal file
@ -0,0 +1,589 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2010 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.water;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.math.*;
|
||||||
|
import com.jme3.post.SceneProcessor;
|
||||||
|
import com.jme3.renderer.Camera;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.Renderer;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.renderer.queue.RenderQueue;
|
||||||
|
import com.jme3.scene.Geometry;
|
||||||
|
import com.jme3.scene.Spatial;
|
||||||
|
import com.jme3.scene.shape.Quad;
|
||||||
|
import com.jme3.texture.FrameBuffer;
|
||||||
|
import com.jme3.texture.Image.Format;
|
||||||
|
import com.jme3.texture.Texture.WrapMode;
|
||||||
|
import com.jme3.texture.Texture2D;
|
||||||
|
import com.jme3.ui.Picture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Simple Water renders a simple plane that use reflection and refraction to look like water.
|
||||||
|
* It's pretty basic, but much faster than the WaterFilter
|
||||||
|
* It's useful if you aim low specs hardware and still want a good looking water.
|
||||||
|
* Usage is :
|
||||||
|
* <code>
|
||||||
|
* SimpleWaterProcessor waterProcessor = new SimpleWaterProcessor(assetManager);
|
||||||
|
* //setting the scene to use for reflection
|
||||||
|
* waterProcessor.setReflectionScene(mainScene);
|
||||||
|
* //setting the light position
|
||||||
|
* waterProcessor.setLightPosition(lightPos);
|
||||||
|
*
|
||||||
|
* //setting the water plane
|
||||||
|
* Vector3f waterLocation=new Vector3f(0,-20,0);
|
||||||
|
* waterProcessor.setPlane(new Plane(Vector3f.UNIT_Y, waterLocation.dot(Vector3f.UNIT_Y)));
|
||||||
|
* //setting the water color
|
||||||
|
* waterProcessor.setWaterColor(ColorRGBA.Brown);
|
||||||
|
*
|
||||||
|
* //creating a quad to render water to
|
||||||
|
* Quad quad = new Quad(400,400);
|
||||||
|
*
|
||||||
|
* //the texture coordinates define the general size of the waves
|
||||||
|
* quad.scaleTextureCoordinates(new Vector2f(6f,6f));
|
||||||
|
*
|
||||||
|
* //creating a geom to attach the water material
|
||||||
|
* Geometry water=new Geometry("water", quad);
|
||||||
|
* water.setLocalTranslation(-200, -20, 250);
|
||||||
|
* water.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X));
|
||||||
|
* //finally setting the material
|
||||||
|
* water.setMaterial(waterProcessor.getMaterial());
|
||||||
|
*
|
||||||
|
* //attaching the water to the root node
|
||||||
|
* rootNode.attachChild(water);
|
||||||
|
* </code>
|
||||||
|
* @author Normen Hansen & Rémy Bouquet
|
||||||
|
*/
|
||||||
|
public class SimpleWaterProcessor implements SceneProcessor {
|
||||||
|
|
||||||
|
protected RenderManager rm;
|
||||||
|
protected ViewPort vp;
|
||||||
|
protected Spatial reflectionScene;
|
||||||
|
protected ViewPort reflectionView;
|
||||||
|
protected ViewPort refractionView;
|
||||||
|
protected FrameBuffer reflectionBuffer;
|
||||||
|
protected FrameBuffer refractionBuffer;
|
||||||
|
protected Camera reflectionCam;
|
||||||
|
protected Camera refractionCam;
|
||||||
|
protected Texture2D reflectionTexture;
|
||||||
|
protected Texture2D refractionTexture;
|
||||||
|
protected Texture2D depthTexture;
|
||||||
|
protected Texture2D normalTexture;
|
||||||
|
protected Texture2D dudvTexture;
|
||||||
|
protected int renderWidth = 512;
|
||||||
|
protected int renderHeight = 512;
|
||||||
|
protected Plane plane = new Plane(Vector3f.UNIT_Y, Vector3f.ZERO.dot(Vector3f.UNIT_Y));
|
||||||
|
protected float speed = 0.05f;
|
||||||
|
protected Ray ray = new Ray();
|
||||||
|
protected Vector3f targetLocation = new Vector3f();
|
||||||
|
protected AssetManager manager;
|
||||||
|
protected Material material;
|
||||||
|
protected float waterDepth = 1;
|
||||||
|
protected float waterTransparency = 0.4f;
|
||||||
|
protected boolean debug = false;
|
||||||
|
private Picture dispRefraction;
|
||||||
|
private Picture dispReflection;
|
||||||
|
private Picture dispDepth;
|
||||||
|
private Plane reflectionClipPlane;
|
||||||
|
private Plane refractionClipPlane;
|
||||||
|
private float refractionClippingOffset = 0.3f;
|
||||||
|
private float reflectionClippingOffset = -5f;
|
||||||
|
private Vector3f vect1 = new Vector3f();
|
||||||
|
private Vector3f vect2 = new Vector3f();
|
||||||
|
private Vector3f vect3 = new Vector3f();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a SimpleWaterProcessor
|
||||||
|
* @param manager the asset manager
|
||||||
|
*/
|
||||||
|
public SimpleWaterProcessor(AssetManager manager) {
|
||||||
|
this.manager = manager;
|
||||||
|
material = new Material(manager, "Common/MatDefs/Water/SimpleWater.j3md");
|
||||||
|
material.setFloat("waterDepth", waterDepth);
|
||||||
|
material.setFloat("waterTransparency", waterTransparency / 10);
|
||||||
|
material.setColor("waterColor", ColorRGBA.White);
|
||||||
|
material.setVector3("lightPos", new Vector3f(1, -1, 1));
|
||||||
|
|
||||||
|
material.setColor("distortionScale", new ColorRGBA(0.2f, 0.2f, 0.2f, 0.2f));
|
||||||
|
material.setColor("distortionMix", new ColorRGBA(0.5f, 0.5f, 0.5f, 0.5f));
|
||||||
|
material.setColor("texScale", new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
|
updateClipPlanes();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initialize(RenderManager rm, ViewPort vp) {
|
||||||
|
this.rm = rm;
|
||||||
|
this.vp = vp;
|
||||||
|
|
||||||
|
loadTextures(manager);
|
||||||
|
createTextures();
|
||||||
|
applyTextures(material);
|
||||||
|
|
||||||
|
createPreViews();
|
||||||
|
|
||||||
|
material.setVector2("FrustumNearFar", new Vector2f(vp.getCamera().getFrustumNear(), vp.getCamera().getFrustumFar()));
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
dispRefraction = new Picture("dispRefraction");
|
||||||
|
dispRefraction.setTexture(manager, refractionTexture, false);
|
||||||
|
dispReflection = new Picture("dispRefraction");
|
||||||
|
dispReflection.setTexture(manager, reflectionTexture, false);
|
||||||
|
dispDepth = new Picture("depthTexture");
|
||||||
|
dispDepth.setTexture(manager, depthTexture, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reshape(ViewPort vp, int w, int h) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInitialized() {
|
||||||
|
return rm != null;
|
||||||
|
}
|
||||||
|
float time = 0;
|
||||||
|
float savedTpf = 0;
|
||||||
|
|
||||||
|
public void preFrame(float tpf) {
|
||||||
|
time = time + (tpf * speed);
|
||||||
|
if (time > 1f) {
|
||||||
|
time = 0;
|
||||||
|
}
|
||||||
|
material.setFloat("time", time);
|
||||||
|
savedTpf = tpf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postQueue(RenderQueue rq) {
|
||||||
|
Camera sceneCam = rm.getCurrentCamera();
|
||||||
|
|
||||||
|
//update ray
|
||||||
|
ray.setOrigin(sceneCam.getLocation());
|
||||||
|
ray.setDirection(sceneCam.getDirection());
|
||||||
|
|
||||||
|
//update refraction cam
|
||||||
|
refractionCam.setLocation(sceneCam.getLocation());
|
||||||
|
refractionCam.setRotation(sceneCam.getRotation());
|
||||||
|
refractionCam.setFrustum(sceneCam.getFrustumNear(),
|
||||||
|
sceneCam.getFrustumFar(),
|
||||||
|
sceneCam.getFrustumLeft(),
|
||||||
|
sceneCam.getFrustumRight(),
|
||||||
|
sceneCam.getFrustumTop(),
|
||||||
|
sceneCam.getFrustumBottom());
|
||||||
|
|
||||||
|
//update reflection cam
|
||||||
|
boolean inv = false;
|
||||||
|
if (!ray.intersectsWherePlane(plane, targetLocation)) {
|
||||||
|
ray.setDirection(ray.getDirection().negateLocal());
|
||||||
|
ray.intersectsWherePlane(plane, targetLocation);
|
||||||
|
inv = true;
|
||||||
|
}
|
||||||
|
Vector3f loc = plane.reflect(sceneCam.getLocation(), new Vector3f());
|
||||||
|
reflectionCam.setLocation(loc);
|
||||||
|
reflectionCam.setFrustum(sceneCam.getFrustumNear(),
|
||||||
|
sceneCam.getFrustumFar(),
|
||||||
|
sceneCam.getFrustumLeft(),
|
||||||
|
sceneCam.getFrustumRight(),
|
||||||
|
sceneCam.getFrustumTop(),
|
||||||
|
sceneCam.getFrustumBottom());
|
||||||
|
// tempVec and calcVect are just temporary vector3f objects
|
||||||
|
vect1.set(sceneCam.getLocation()).addLocal(sceneCam.getUp());
|
||||||
|
float planeDistance = plane.pseudoDistance(vect1);
|
||||||
|
vect2.set(plane.getNormal()).multLocal(planeDistance * 2.0f);
|
||||||
|
vect3.set(vect1.subtractLocal(vect2)).subtractLocal(loc).normalizeLocal().negateLocal();
|
||||||
|
// now set the up vector
|
||||||
|
reflectionCam.lookAt(targetLocation, vect3);
|
||||||
|
if (inv) {
|
||||||
|
reflectionCam.setAxes(reflectionCam.getLeft().negateLocal(), reflectionCam.getUp(), reflectionCam.getDirection().negateLocal());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Rendering reflection and refraction
|
||||||
|
rm.renderViewPort(reflectionView, savedTpf);
|
||||||
|
rm.renderViewPort(refractionView, savedTpf);
|
||||||
|
rm.getRenderer().setFrameBuffer(vp.getOutputFrameBuffer());
|
||||||
|
rm.setCamera(sceneCam, false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postFrame(FrameBuffer out) {
|
||||||
|
if (debug) {
|
||||||
|
displayMap(rm.getRenderer(), dispRefraction, 64);
|
||||||
|
displayMap(rm.getRenderer(), dispReflection, 256);
|
||||||
|
displayMap(rm.getRenderer(), dispDepth, 448);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cleanup() {
|
||||||
|
}
|
||||||
|
|
||||||
|
//debug only : displays maps
|
||||||
|
protected void displayMap(Renderer r, Picture pic, int left) {
|
||||||
|
Camera cam = vp.getCamera();
|
||||||
|
rm.setCamera(cam, true);
|
||||||
|
int h = cam.getHeight();
|
||||||
|
|
||||||
|
pic.setPosition(left, h / 20f);
|
||||||
|
|
||||||
|
pic.setWidth(128);
|
||||||
|
pic.setHeight(128);
|
||||||
|
pic.updateGeometricState();
|
||||||
|
rm.renderGeometry(pic);
|
||||||
|
rm.setCamera(cam, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void loadTextures(AssetManager manager) {
|
||||||
|
normalTexture = (Texture2D) manager.loadTexture("Common/MatDefs/Water/Textures/water_normalmap.dds");
|
||||||
|
dudvTexture = (Texture2D) manager.loadTexture("Common/MatDefs/Water/Textures/dudv_map.jpg");
|
||||||
|
normalTexture.setWrap(WrapMode.Repeat);
|
||||||
|
dudvTexture.setWrap(WrapMode.Repeat);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void createTextures() {
|
||||||
|
reflectionTexture = new Texture2D(renderWidth, renderHeight, Format.RGBA8);
|
||||||
|
refractionTexture = new Texture2D(renderWidth, renderHeight, Format.RGBA8);
|
||||||
|
depthTexture = new Texture2D(renderWidth, renderHeight, Format.Depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void applyTextures(Material mat) {
|
||||||
|
mat.setTexture("water_reflection", reflectionTexture);
|
||||||
|
mat.setTexture("water_refraction", refractionTexture);
|
||||||
|
mat.setTexture("water_depthmap", depthTexture);
|
||||||
|
mat.setTexture("water_normalmap", normalTexture);
|
||||||
|
mat.setTexture("water_dudvmap", dudvTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void createPreViews() {
|
||||||
|
reflectionCam = new Camera(renderWidth, renderHeight);
|
||||||
|
refractionCam = new Camera(renderWidth, renderHeight);
|
||||||
|
|
||||||
|
// create a pre-view. a view that is rendered before the main view
|
||||||
|
reflectionView = new ViewPort("Reflection View", reflectionCam);
|
||||||
|
reflectionView.setClearFlags(true, true, true);
|
||||||
|
reflectionView.setBackgroundColor(ColorRGBA.Black);
|
||||||
|
// create offscreen framebuffer
|
||||||
|
reflectionBuffer = new FrameBuffer(renderWidth, renderHeight, 1);
|
||||||
|
//setup framebuffer to use texture
|
||||||
|
reflectionBuffer.setDepthBuffer(Format.Depth);
|
||||||
|
reflectionBuffer.setColorTexture(reflectionTexture);
|
||||||
|
|
||||||
|
//set viewport to render to offscreen framebuffer
|
||||||
|
reflectionView.setOutputFrameBuffer(reflectionBuffer);
|
||||||
|
reflectionView.addProcessor(new ReflectionProcessor(reflectionCam, reflectionBuffer, reflectionClipPlane));
|
||||||
|
// attach the scene to the viewport to be rendered
|
||||||
|
reflectionView.attachScene(reflectionScene);
|
||||||
|
|
||||||
|
// create a pre-view. a view that is rendered before the main view
|
||||||
|
refractionView = new ViewPort("Refraction View", refractionCam);
|
||||||
|
refractionView.setClearFlags(true, true, true);
|
||||||
|
refractionView.setBackgroundColor(ColorRGBA.Black);
|
||||||
|
// create offscreen framebuffer
|
||||||
|
refractionBuffer = new FrameBuffer(renderWidth, renderHeight, 1);
|
||||||
|
//setup framebuffer to use texture
|
||||||
|
refractionBuffer.setDepthBuffer(Format.Depth);
|
||||||
|
refractionBuffer.setColorTexture(refractionTexture);
|
||||||
|
refractionBuffer.setDepthTexture(depthTexture);
|
||||||
|
//set viewport to render to offscreen framebuffer
|
||||||
|
refractionView.setOutputFrameBuffer(refractionBuffer);
|
||||||
|
refractionView.addProcessor(new RefractionProcessor());
|
||||||
|
// attach the scene to the viewport to be rendered
|
||||||
|
refractionView.attachScene(reflectionScene);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void destroyViews() {
|
||||||
|
// rm.removePreView(reflectionView);
|
||||||
|
rm.removePreView(refractionView);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the water material from this processor, apply this to your water quad.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Material getMaterial() {
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the reflected scene, should not include the water quad!
|
||||||
|
* Set before adding processor.
|
||||||
|
* @param spat
|
||||||
|
*/
|
||||||
|
public void setReflectionScene(Spatial spat) {
|
||||||
|
reflectionScene = spat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the width of the reflection and refraction textures
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getRenderWidth() {
|
||||||
|
return renderWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the height of the reflection and refraction textures
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getRenderHeight() {
|
||||||
|
return renderHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the reflection Texture render size,
|
||||||
|
* set before adding the processor!
|
||||||
|
* @param with
|
||||||
|
* @param height
|
||||||
|
*/
|
||||||
|
public void setRenderSize(int width, int height) {
|
||||||
|
renderWidth = width;
|
||||||
|
renderHeight = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the water plane
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Plane getPlane() {
|
||||||
|
return plane;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the water plane for this processor.
|
||||||
|
* @param plane
|
||||||
|
*/
|
||||||
|
public void setPlane(Plane plane) {
|
||||||
|
this.plane.setConstant(plane.getConstant());
|
||||||
|
this.plane.setNormal(plane.getNormal());
|
||||||
|
updateClipPlanes();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the water plane using an origin (location) and a normal (reflection direction).
|
||||||
|
* @param origin Set to 0,-6,0 if your water quad is at that location for correct reflection
|
||||||
|
* @param normal Set to 0,1,0 (Vector3f.UNIT_Y) for normal planar water
|
||||||
|
*/
|
||||||
|
public void setPlane(Vector3f origin, Vector3f normal) {
|
||||||
|
this.plane.setOriginNormal(origin, normal);
|
||||||
|
updateClipPlanes();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateClipPlanes() {
|
||||||
|
reflectionClipPlane = plane.clone();
|
||||||
|
reflectionClipPlane.setConstant(reflectionClipPlane.getConstant() + reflectionClippingOffset);
|
||||||
|
refractionClipPlane = plane.clone();
|
||||||
|
refractionClipPlane.setConstant(refractionClipPlane.getConstant() + refractionClippingOffset);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the light Position for the processor
|
||||||
|
* @param position
|
||||||
|
*/
|
||||||
|
//TODO maybe we should provide a convenient method to compute position from direction
|
||||||
|
public void setLightPosition(Vector3f position) {
|
||||||
|
material.setVector3("lightPos", position);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the color that will be added to the refraction texture.
|
||||||
|
* @param color
|
||||||
|
*/
|
||||||
|
public void setWaterColor(ColorRGBA color) {
|
||||||
|
material.setColor("waterColor", color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Higher values make the refraction texture shine through earlier.
|
||||||
|
* Default is 4
|
||||||
|
* @param depth
|
||||||
|
*/
|
||||||
|
public void setWaterDepth(float depth) {
|
||||||
|
waterDepth = depth;
|
||||||
|
material.setFloat("waterDepth", depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the water depth
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getWaterDepth() {
|
||||||
|
return waterDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns water transparency
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getWaterTransparency() {
|
||||||
|
return waterTransparency;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the water transparency default os 0.1f
|
||||||
|
* @param waterTransparency
|
||||||
|
*/
|
||||||
|
public void setWaterTransparency(float waterTransparency) {
|
||||||
|
this.waterTransparency = Math.max(0, waterTransparency);
|
||||||
|
material.setFloat("waterTransparency", waterTransparency / 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the speed of the wave animation, default = 0.05f.
|
||||||
|
* @param speed
|
||||||
|
*/
|
||||||
|
public void setWaveSpeed(float speed) {
|
||||||
|
this.speed = speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the scale of distortion by the normal map, default = 0.2
|
||||||
|
*/
|
||||||
|
public void setDistortionScale(float value) {
|
||||||
|
material.setColor("distortionScale", new ColorRGBA(value, value, value, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets how the normal and dudv map are mixed to create the wave effect, default = 0.5
|
||||||
|
*/
|
||||||
|
public void setDistortionMix(float value) {
|
||||||
|
material.setColor("distortionMix", new ColorRGBA(value, value, value, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the scale of the normal/dudv texture, default = 1.
|
||||||
|
* Note that the waves should be scaled by the texture coordinates of the quad to avoid animation artifacts,
|
||||||
|
* use mesh.scaleTextureCoordinates(Vector2f) for that.
|
||||||
|
*/
|
||||||
|
public void setTexScale(float value) {
|
||||||
|
material.setColor("texScale", new ColorRGBA(value, value, value, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retruns true if the waterprocessor is in debug mode
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isDebug() {
|
||||||
|
return debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set to true to display reflection and refraction textures in the GUI for debug purpose
|
||||||
|
* @param debug
|
||||||
|
*/
|
||||||
|
public void setDebug(boolean debug) {
|
||||||
|
this.debug = debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a quad with the water material applied to it.
|
||||||
|
* @param width
|
||||||
|
* @param height
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Geometry createWaterGeometry(float width, float height) {
|
||||||
|
Quad quad = new Quad(width, height);
|
||||||
|
Geometry geom = new Geometry("WaterGeometry", quad);
|
||||||
|
geom.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X));
|
||||||
|
geom.setMaterial(material);
|
||||||
|
return geom;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the reflection clipping plane offset
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getReflectionClippingOffset() {
|
||||||
|
return reflectionClippingOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the reflection clipping plane offset
|
||||||
|
* set a nagetive value to lower the clipping plane for relection texture rendering.
|
||||||
|
* @param reflectionClippingOffset
|
||||||
|
*/
|
||||||
|
public void setReflectionClippingOffset(float reflectionClippingOffset) {
|
||||||
|
this.reflectionClippingOffset = reflectionClippingOffset;
|
||||||
|
updateClipPlanes();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the refraction clipping plane offset
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public float getRefractionClippingOffset() {
|
||||||
|
return refractionClippingOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the refraction clipping plane offset
|
||||||
|
* set a positive value to raise the clipping plane for refraction texture rendering
|
||||||
|
* @param refractionClippingOffset
|
||||||
|
*/
|
||||||
|
public void setRefractionClippingOffset(float refractionClippingOffset) {
|
||||||
|
this.refractionClippingOffset = refractionClippingOffset;
|
||||||
|
updateClipPlanes();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refraction Processor
|
||||||
|
*/
|
||||||
|
public class RefractionProcessor implements SceneProcessor {
|
||||||
|
|
||||||
|
RenderManager rm;
|
||||||
|
ViewPort vp;
|
||||||
|
|
||||||
|
public void initialize(RenderManager rm, ViewPort vp) {
|
||||||
|
this.rm = rm;
|
||||||
|
this.vp = vp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reshape(ViewPort vp, int w, int h) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInitialized() {
|
||||||
|
return rm != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void preFrame(float tpf) {
|
||||||
|
refractionCam.setClipPlane(refractionClipPlane, Plane.Side.Negative);//,-1
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postQueue(RenderQueue rq) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postFrame(FrameBuffer out) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cleanup() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|