Water Filter : underwater shader
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7599 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
fae5029629
commit
95e709f820
BIN
engine/src/core-data/Common/MatDefs/Water/Textures/caustics.jpg
Normal file
BIN
engine/src/core-data/Common/MatDefs/Water/Textures/caustics.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 56 KiB |
@ -8,6 +8,7 @@ uniform sampler2D m_Texture;
|
|||||||
uniform sampler2D m_DepthTexture;
|
uniform sampler2D m_DepthTexture;
|
||||||
uniform sampler2D m_NormalMap;
|
uniform sampler2D m_NormalMap;
|
||||||
uniform sampler2D m_FoamMap;
|
uniform sampler2D m_FoamMap;
|
||||||
|
uniform sampler2D m_CausticsMap;
|
||||||
uniform sampler2D m_ReflectionMap;
|
uniform sampler2D m_ReflectionMap;
|
||||||
|
|
||||||
uniform mat4 m_ViewProjectionMatrixInverse;
|
uniform mat4 m_ViewProjectionMatrixInverse;
|
||||||
@ -114,6 +115,112 @@ float fresnelTerm(in vec3 normal,in vec3 eyeVec){
|
|||||||
return saturate(fresnel * (1.0 - saturate(m_R0)) + m_R0 - m_RefractionStrength);
|
return saturate(fresnel * (1.0 - saturate(m_R0)) + m_R0 - m_RefractionStrength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec2 m_FrustumNearFar=vec2(1.0,50);
|
||||||
|
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 = 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)).r;
|
||||||
|
float normal2 = textureOffset(m_HeightMap, texC, ivec2( 1, 0)).r;
|
||||||
|
float normal3 = textureOffset(m_HeightMap, texC, ivec2( 0, -1)).r;
|
||||||
|
float normal4 = textureOffset(m_HeightMap, texC, ivec2( 0, 1)).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 * 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 *= m_WaterColor.rgb;
|
||||||
|
color=mix(color2, caustics,0.6);
|
||||||
|
#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(){
|
void main(){
|
||||||
float sceneDepth = texture2D(m_DepthTexture, texCoord).r;
|
float sceneDepth = texture2D(m_DepthTexture, texCoord).r;
|
||||||
float isAtFarPlane = step(0.99998, sceneDepth);
|
float isAtFarPlane = step(0.99998, sceneDepth);
|
||||||
@ -125,10 +232,10 @@ void main(){
|
|||||||
|
|
||||||
float level = m_WaterHeight;
|
float level = m_WaterHeight;
|
||||||
|
|
||||||
// If we are underwater let's leave out complex computations
|
// If we are underwater let's go to under water function
|
||||||
if(level >= m_CameraPosition.y){
|
if(level >= m_CameraPosition.y){
|
||||||
gl_FragColor = vec4(color2, 1.0);
|
gl_FragColor = underWater();
|
||||||
return;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#ifndef ENABLE_RIPPLES
|
//#ifndef ENABLE_RIPPLES
|
||||||
@ -284,10 +391,6 @@ void main(){
|
|||||||
// to calculate the derivatives for all these pixels by using step()!
|
// to calculate the derivatives for all these pixels by using step()!
|
||||||
// That way we won't get pixels around the edges of the terrain,
|
// That way we won't get pixels around the edges of the terrain,
|
||||||
// Where the derivatives are undefined
|
// Where the derivatives are undefined
|
||||||
/* float coef=1.0;
|
|
||||||
if(position.y<level)coef=0.0;
|
|
||||||
gl_FragColor = vec4(mix(color, color2, coef), 1.0);
|
|
||||||
*/
|
|
||||||
if(position.y > level){
|
if(position.y > level){
|
||||||
color = color2;
|
color = color2;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ MaterialDef Advanced Water {
|
|||||||
Int NumSamples
|
Int NumSamples
|
||||||
Int NumSamplesDepth
|
Int NumSamplesDepth
|
||||||
Texture2D FoamMap
|
Texture2D FoamMap
|
||||||
|
Texture2D CausticsMap
|
||||||
Texture2D NormalMap
|
Texture2D NormalMap
|
||||||
Texture2D ReflectionMap
|
Texture2D ReflectionMap
|
||||||
Texture2D HeightMap
|
Texture2D HeightMap
|
||||||
@ -39,7 +40,9 @@ MaterialDef Advanced Water {
|
|||||||
Boolean UseHQShoreline
|
Boolean UseHQShoreline
|
||||||
Boolean UseSpecular
|
Boolean UseSpecular
|
||||||
Boolean UseFoam
|
Boolean UseFoam
|
||||||
|
Boolean UseCaustics
|
||||||
Boolean UseRefraction
|
Boolean UseRefraction
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Technique {
|
Technique {
|
||||||
@ -53,6 +56,12 @@ MaterialDef Advanced Water {
|
|||||||
Defines {
|
Defines {
|
||||||
RESOLVE_MS : NumSamples
|
RESOLVE_MS : NumSamples
|
||||||
RESOLVE_DEPTH_MS : NumSamplesDepth
|
RESOLVE_DEPTH_MS : NumSamplesDepth
|
||||||
|
ENABLE_RIPPLES : UseRipples
|
||||||
|
ENABLE_HQ_SHORELINE : UseHQShoreline
|
||||||
|
ENABLE_SPECULAR : UseSpecular
|
||||||
|
ENABLE_FOAM : UseFoam
|
||||||
|
ENABLE_CAUSTICS : UseCaustics
|
||||||
|
ENABLE_REFRACTION : UseRefraction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +77,9 @@ MaterialDef Advanced Water {
|
|||||||
ENABLE_HQ_SHORELINE : UseHQShoreline
|
ENABLE_HQ_SHORELINE : UseHQShoreline
|
||||||
ENABLE_SPECULAR : UseSpecular
|
ENABLE_SPECULAR : UseSpecular
|
||||||
ENABLE_FOAM : UseFoam
|
ENABLE_FOAM : UseFoam
|
||||||
|
ENABLE_CAUSTICS : UseCaustics
|
||||||
ENABLE_REFRACTION : UseRefraction
|
ENABLE_REFRACTION : UseRefraction
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ uniform DEPTHTEXTURE m_DepthTexture;
|
|||||||
uniform sampler2D m_HeightMap;
|
uniform sampler2D m_HeightMap;
|
||||||
uniform sampler2D m_NormalMap;
|
uniform sampler2D m_NormalMap;
|
||||||
uniform sampler2D m_FoamMap;
|
uniform sampler2D m_FoamMap;
|
||||||
|
uniform sampler2D m_CausticsMap;
|
||||||
uniform sampler2D m_ReflectionMap;
|
uniform sampler2D m_ReflectionMap;
|
||||||
|
|
||||||
uniform mat4 m_ViewProjectionMatrixInverse;
|
uniform mat4 m_ViewProjectionMatrixInverse;
|
||||||
@ -38,11 +39,6 @@ uniform vec2 m_WindDirection;
|
|||||||
uniform float m_SunScale;
|
uniform float m_SunScale;
|
||||||
uniform float m_WaveScale;
|
uniform float m_WaveScale;
|
||||||
|
|
||||||
uniform bool m_UseRipples,
|
|
||||||
m_UseHQShoreline,
|
|
||||||
m_UseSpecular,
|
|
||||||
m_UseFoam,
|
|
||||||
m_UseRefraction;
|
|
||||||
|
|
||||||
vec2 scale = vec2(m_WaveScale, m_WaveScale);
|
vec2 scale = vec2(m_WaveScale, m_WaveScale);
|
||||||
float refractionScale = m_WaveScale;
|
float refractionScale = m_WaveScale;
|
||||||
@ -115,8 +111,124 @@ float fresnelTerm(in vec3 normal,in vec3 eyeVec){
|
|||||||
return saturate(fresnel * (1.0 - saturate(m_R0)) + m_R0 - m_RefractionStrength);
|
return saturate(fresnel * (1.0 - saturate(m_R0)) + m_R0 - m_RefractionStrength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec2 m_FrustumNearFar=vec2(1.0,50);
|
||||||
|
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)).r;
|
||||||
|
float normal2 = textureOffset(m_HeightMap, texC, ivec2( 1, 0)).r;
|
||||||
|
float normal3 = textureOffset(m_HeightMap, texC, ivec2( 0, -1)).r;
|
||||||
|
float normal4 = textureOffset(m_HeightMap, texC, ivec2( 0, 1)).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 * 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 *= m_WaterColor.rgb;
|
||||||
|
color=mix(color2, caustics,0.6);
|
||||||
|
#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
|
// NOTE: This will be called even for single-sampling
|
||||||
vec4 main_multiSample(int sampleNum){
|
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;
|
float sceneDepth = fetchTextureSample(m_DepthTexture, texCoord, sampleNum).r;
|
||||||
vec3 color2 = fetchTextureSample(m_Texture, texCoord, sampleNum).rgb;
|
vec3 color2 = fetchTextureSample(m_Texture, texCoord, sampleNum).rgb;
|
||||||
@ -126,21 +238,16 @@ vec4 main_multiSample(int sampleNum){
|
|||||||
|
|
||||||
float level = m_WaterHeight;
|
float level = m_WaterHeight;
|
||||||
|
|
||||||
// If we are underwater let's leave out complex computations
|
|
||||||
if(level >= m_CameraPosition.y){
|
|
||||||
return vec4(color2, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float isAtFarPlane = step(0.99998, sceneDepth);
|
float isAtFarPlane = step(0.99998, sceneDepth);
|
||||||
//#ifndef ENABLE_RIPPLES
|
//#ifndef ENABLE_RIPPLES
|
||||||
// This optimization won't work on NVIDIA cards if ripples are enabled
|
// This optimization won't work on NVIDIA cards if ripples are enabled
|
||||||
if(position.y > level + m_MaxAmplitude + isAtFarPlane * 100.0){
|
if(position.y > level + m_MaxAmplitude + isAtFarPlane * 100.0){
|
||||||
|
|
||||||
return vec4(color2, 1.0);
|
return vec4(color2, 1.0);
|
||||||
}
|
}
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
vec3 eyeVec = position - m_CameraPosition;
|
vec3 eyeVec = position - m_CameraPosition;
|
||||||
float diff = level - position.y;
|
|
||||||
float cameraDepth = m_CameraPosition.y - position.y;
|
float cameraDepth = m_CameraPosition.y - position.y;
|
||||||
|
|
||||||
// Find intersection with water surface
|
// Find intersection with water surface
|
||||||
@ -150,9 +257,9 @@ vec4 main_multiSample(int sampleNum){
|
|||||||
|
|
||||||
vec2 texC = vec2(0.0);
|
vec2 texC = vec2(0.0);
|
||||||
int samples = 1;
|
int samples = 1;
|
||||||
if (m_UseHQShoreline){
|
#ifdef ENABLE_HQ_SHORELINE
|
||||||
samples = 10;
|
samples = 10;
|
||||||
}
|
#endif
|
||||||
|
|
||||||
float biasFactor = 1.0 / samples;
|
float biasFactor = 1.0 / samples;
|
||||||
for (int i = 0; i < samples; i++){
|
for (int i = 0; i < samples; i++){
|
||||||
@ -187,7 +294,7 @@ vec4 main_multiSample(int sampleNum){
|
|||||||
vec3 myNormal = normalize(vec3((normal1 - normal2) * m_MaxAmplitude,m_NormalScale,(normal3 - normal4) * m_MaxAmplitude));
|
vec3 myNormal = normalize(vec3((normal1 - normal2) * m_MaxAmplitude,m_NormalScale,(normal3 - normal4) * m_MaxAmplitude));
|
||||||
vec3 normal = vec3(0.0);
|
vec3 normal = vec3(0.0);
|
||||||
|
|
||||||
if (m_UseRipples){
|
#ifdef ENABLE_RIPPLES
|
||||||
texC = surfacePoint.xz * 0.8 + m_WindDirection * m_Time* 1.6;
|
texC = surfacePoint.xz * 0.8 + m_WindDirection * m_Time* 1.6;
|
||||||
mat3 tangentFrame = computeTangentFrame(myNormal, eyeVecNorm, texC);
|
mat3 tangentFrame = computeTangentFrame(myNormal, eyeVecNorm, texC);
|
||||||
vec3 normal0a = normalize(tangentFrame*(2.0 * texture(m_NormalMap, texC).xyz - 1.0));
|
vec3 normal0a = normalize(tangentFrame*(2.0 * texture(m_NormalMap, texC).xyz - 1.0));
|
||||||
@ -213,12 +320,12 @@ vec4 main_multiSample(int sampleNum){
|
|||||||
// gl_FragColor = vec4(color2 + normal*0.0001, 1.0);
|
// gl_FragColor = vec4(color2 + normal*0.0001, 1.0);
|
||||||
// return;
|
// return;
|
||||||
//}
|
//}
|
||||||
}else{
|
#else
|
||||||
normal = myNormal;
|
normal = myNormal;
|
||||||
}
|
#endif
|
||||||
|
|
||||||
vec3 refraction = color2;
|
vec3 refraction = color2;
|
||||||
if (m_UseRefraction){
|
#ifdef ENABLE_REFRACTION
|
||||||
// texC = texCoord.xy+ m_ReflectionDisplace * normal.x;
|
// texC = texCoord.xy+ m_ReflectionDisplace * normal.x;
|
||||||
texC = texCoord.xy;
|
texC = texCoord.xy;
|
||||||
texC += sin(m_Time*1.8 + 3.0 * abs(position.y)) * (refractionScale * min(depth2, 1.0));
|
texC += sin(m_Time*1.8 + 3.0 * abs(position.y)) * (refractionScale * min(depth2, 1.0));
|
||||||
@ -229,7 +336,7 @@ vec4 main_multiSample(int sampleNum){
|
|||||||
ivec2 iTexC = ivec2(texC * textureSize(m_Texture, 0));
|
ivec2 iTexC = ivec2(texC * textureSize(m_Texture, 0));
|
||||||
refraction = texelFetch(m_Texture, iTexC, 0).rgb;
|
refraction = texelFetch(m_Texture, iTexC, 0).rgb;
|
||||||
#endif
|
#endif
|
||||||
}
|
#endif
|
||||||
|
|
||||||
vec3 waterPosition = surfacePoint.xyz;
|
vec3 waterPosition = surfacePoint.xyz;
|
||||||
waterPosition.y -= (level - m_WaterHeight);
|
waterPosition.y -= (level - m_WaterHeight);
|
||||||
@ -249,8 +356,11 @@ vec4 main_multiSample(int sampleNum){
|
|||||||
refraction = mix(mix(refraction, m_WaterColor.rgb * waterCol, saturate(depthN / visibility)),
|
refraction = mix(mix(refraction, m_WaterColor.rgb * waterCol, saturate(depthN / visibility)),
|
||||||
m_DeepWaterColor.rgb * waterCol, saturate(depth2 / m_ColorExtinction));
|
m_DeepWaterColor.rgb * waterCol, saturate(depth2 / m_ColorExtinction));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
vec3 foam = vec3(0.0);
|
vec3 foam = vec3(0.0);
|
||||||
if (m_UseFoam){
|
#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;
|
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;
|
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;
|
||||||
|
|
||||||
@ -267,10 +377,10 @@ vec4 main_multiSample(int sampleNum){
|
|||||||
saturate((level - (m_WaterHeight + m_FoamExistence.z)) / (m_MaxAmplitude - m_FoamExistence.z))).rgb;
|
saturate((level - (m_WaterHeight + m_FoamExistence.z)) / (m_MaxAmplitude - m_FoamExistence.z))).rgb;
|
||||||
}
|
}
|
||||||
foam *= m_LightColor.rgb;
|
foam *= m_LightColor.rgb;
|
||||||
}
|
#endif
|
||||||
|
|
||||||
vec3 specular = vec3(0.0);
|
vec3 specular = vec3(0.0);
|
||||||
if (m_UseSpecular){
|
#ifdef ENABLE_SPECULAR
|
||||||
vec3 lightDir=normalize(m_LightDir);
|
vec3 lightDir=normalize(m_LightDir);
|
||||||
vec3 mirrorEye = (2.0 * dot(eyeVecNorm, normal) * normal - eyeVecNorm);
|
vec3 mirrorEye = (2.0 * dot(eyeVecNorm, normal) * normal - eyeVecNorm);
|
||||||
float dotSpec = saturate(dot(mirrorEye.xyz, -lightDir) * 0.5 + 0.5);
|
float dotSpec = saturate(dot(mirrorEye.xyz, -lightDir) * 0.5 + 0.5);
|
||||||
@ -278,7 +388,7 @@ vec4 main_multiSample(int sampleNum){
|
|||||||
specular += specular * 25.0 * saturate(m_Shininess - 0.05);
|
specular += specular * 25.0 * saturate(m_Shininess - 0.05);
|
||||||
//foam does not shine
|
//foam does not shine
|
||||||
specular=specular * m_LightColor.rgb - (5.0 * foam);
|
specular=specular * m_LightColor.rgb - (5.0 * foam);
|
||||||
}
|
#endif
|
||||||
|
|
||||||
color = mix(refraction, reflection, fresnel);
|
color = mix(refraction, reflection, fresnel);
|
||||||
color = mix(refraction, color, saturate(depth * m_ShoreHardness));
|
color = mix(refraction, color, saturate(depth * m_ShoreHardness));
|
||||||
|
@ -58,6 +58,12 @@ public class FogFilter extends Filter {
|
|||||||
super("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) {
|
public FogFilter(ColorRGBA fogColor, float fogDensity, float fogDistance) {
|
||||||
this();
|
this();
|
||||||
this.fogColor = fogColor;
|
this.fogColor = fogColor;
|
||||||
|
@ -59,7 +59,7 @@ public class LightScatteringFilter extends Filter {
|
|||||||
private float lightDensity = 1.4f;
|
private float lightDensity = 1.4f;
|
||||||
private boolean adaptative = true;
|
private boolean adaptative = true;
|
||||||
Vector3f viewLightPos = new Vector3f();
|
Vector3f viewLightPos = new Vector3f();
|
||||||
private boolean display;
|
private boolean display=true;
|
||||||
private float innerLightDensity;
|
private float innerLightDensity;
|
||||||
|
|
||||||
public LightScatteringFilter() {
|
public LightScatteringFilter() {
|
||||||
@ -101,6 +101,8 @@ public class LightScatteringFilter extends Filter {
|
|||||||
//System.err.println("screenLightPos "+screenLightPos);
|
//System.err.println("screenLightPos "+screenLightPos);
|
||||||
if (adaptative) {
|
if (adaptative) {
|
||||||
innerLightDensity = Math.max(lightDensity - Math.max(screenLightPos.x, screenLightPos.y), 0.0f);
|
innerLightDensity = Math.max(lightDensity - Math.max(screenLightPos.x, screenLightPos.y), 0.0f);
|
||||||
|
}else{
|
||||||
|
innerLightDensity=lightDensity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ public class WaterFilter extends Filter {
|
|||||||
protected ViewPort reflectionView;
|
protected ViewPort reflectionView;
|
||||||
private Texture2D normalTexture;
|
private Texture2D normalTexture;
|
||||||
private Texture2D foamTexture;
|
private Texture2D foamTexture;
|
||||||
|
private Texture2D causticsTexture;
|
||||||
private Texture2D heightTexture;
|
private Texture2D heightTexture;
|
||||||
private Plane plane;
|
private Plane plane;
|
||||||
private Camera reflectionCam;
|
private Camera reflectionCam;
|
||||||
@ -102,11 +103,13 @@ public class WaterFilter extends Filter {
|
|||||||
private boolean useHQShoreline = true;
|
private boolean useHQShoreline = true;
|
||||||
private boolean useSpecular = true;
|
private boolean useSpecular = true;
|
||||||
private boolean useFoam = true;
|
private boolean useFoam = true;
|
||||||
|
private boolean useCaustics = true;
|
||||||
private boolean useRefraction = true;
|
private boolean useRefraction = true;
|
||||||
private float time = 0;
|
private float time = 0;
|
||||||
private float savedTpf = 0;
|
private float savedTpf = 0;
|
||||||
private float reflectionDisplace = 30;
|
private float reflectionDisplace = 30;
|
||||||
private float foamIntensity = 0.5f;
|
private float foamIntensity = 0.5f;
|
||||||
|
private boolean underWater;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Water Filter
|
* Create a Water Filter
|
||||||
@ -126,11 +129,6 @@ public class WaterFilter extends Filter {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Format getDefaultPassDepthFormat() {
|
|
||||||
return Format.Depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void preFrame(float tpf) {
|
public void preFrame(float tpf) {
|
||||||
time = time + (tpf * speed);
|
time = time + (tpf * speed);
|
||||||
@ -181,6 +179,8 @@ public class WaterFilter extends Filter {
|
|||||||
reflectionCam.setAxes(reflectionCam.getLeft().negateLocal(), reflectionCam.getUp(), reflectionCam.getDirection().negateLocal());
|
reflectionCam.setAxes(reflectionCam.getLeft().negateLocal(), reflectionCam.getUp(), reflectionCam.getDirection().negateLocal());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if we're under water no need to compute reflection
|
||||||
|
if (sceneCam.getLocation().y >= waterHeight) {
|
||||||
boolean rtb = true;
|
boolean rtb = true;
|
||||||
if (!renderManager.isHandleTranslucentBucket()) {
|
if (!renderManager.isHandleTranslucentBucket()) {
|
||||||
renderManager.setHandleTranslucentBucket(true);
|
renderManager.setHandleTranslucentBucket(true);
|
||||||
@ -192,6 +192,10 @@ public class WaterFilter extends Filter {
|
|||||||
}
|
}
|
||||||
renderManager.getRenderer().setFrameBuffer(viewPort.getOutputFrameBuffer());
|
renderManager.getRenderer().setFrameBuffer(viewPort.getOutputFrameBuffer());
|
||||||
renderManager.setCamera(sceneCam, false);
|
renderManager.setCamera(sceneCam, false);
|
||||||
|
underWater=false;
|
||||||
|
}else{
|
||||||
|
underWater=true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -217,14 +221,19 @@ public class WaterFilter extends Filter {
|
|||||||
if (foamTexture == null) {
|
if (foamTexture == null) {
|
||||||
foamTexture = (Texture2D) manager.loadTexture("Common/MatDefs/Water/Textures/foam.jpg");
|
foamTexture = (Texture2D) manager.loadTexture("Common/MatDefs/Water/Textures/foam.jpg");
|
||||||
}
|
}
|
||||||
|
if (causticsTexture == null) {
|
||||||
|
causticsTexture = (Texture2D) manager.loadTexture("Common/MatDefs/Water/Textures/caustics.jpg");
|
||||||
|
}
|
||||||
heightTexture = (Texture2D) manager.loadTexture("Common/MatDefs/Water/Textures/heightmap.jpg");
|
heightTexture = (Texture2D) manager.loadTexture("Common/MatDefs/Water/Textures/heightmap.jpg");
|
||||||
|
|
||||||
normalTexture.setWrap(WrapMode.Repeat);
|
normalTexture.setWrap(WrapMode.Repeat);
|
||||||
foamTexture.setWrap(WrapMode.Repeat);
|
foamTexture.setWrap(WrapMode.Repeat);
|
||||||
|
causticsTexture.setWrap(WrapMode.Repeat);
|
||||||
heightTexture.setWrap(WrapMode.Repeat);
|
heightTexture.setWrap(WrapMode.Repeat);
|
||||||
|
|
||||||
material = new Material(manager, "Common/MatDefs/Water/Water.j3md");
|
material = new Material(manager, "Common/MatDefs/Water/Water.j3md");
|
||||||
material.setTexture("HeightMap", heightTexture);
|
material.setTexture("HeightMap", heightTexture);
|
||||||
|
material.setTexture("CausticsMap", causticsTexture);
|
||||||
material.setTexture("FoamMap", foamTexture);
|
material.setTexture("FoamMap", foamTexture);
|
||||||
material.setTexture("NormalMap", normalTexture);
|
material.setTexture("NormalMap", normalTexture);
|
||||||
material.setTexture("ReflectionMap", reflectionPass.getRenderedTexture());
|
material.setTexture("ReflectionMap", reflectionPass.getRenderedTexture());
|
||||||
@ -250,6 +259,7 @@ public class WaterFilter extends Filter {
|
|||||||
material.setBoolean("UseHQShoreline", useHQShoreline);
|
material.setBoolean("UseHQShoreline", useHQShoreline);
|
||||||
material.setBoolean("UseSpecular", useSpecular);
|
material.setBoolean("UseSpecular", useSpecular);
|
||||||
material.setBoolean("UseFoam", useFoam);
|
material.setBoolean("UseFoam", useFoam);
|
||||||
|
material.setBoolean("UseCaustics", useCaustics);
|
||||||
material.setBoolean("UseRefraction", useRefraction);
|
material.setBoolean("UseRefraction", useRefraction);
|
||||||
material.setFloat("ReflectionDisplace", reflectionDisplace);
|
material.setFloat("ReflectionDisplace", reflectionDisplace);
|
||||||
material.setFloat("FoamIntensity", foamIntensity);
|
material.setFloat("FoamIntensity", foamIntensity);
|
||||||
@ -293,6 +303,10 @@ public class WaterFilter extends Filter {
|
|||||||
this.waterHeight = waterHeight;
|
this.waterHeight = waterHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the scene to render in the reflection map
|
||||||
|
* @param reflectionScene
|
||||||
|
*/
|
||||||
public void setReflectionScene(Spatial reflectionScene) {
|
public void setReflectionScene(Spatial reflectionScene) {
|
||||||
this.reflectionScene = reflectionScene;
|
this.reflectionScene = reflectionScene;
|
||||||
}
|
}
|
||||||
@ -340,6 +354,10 @@ public class WaterFilter extends Filter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the refractoin constant
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public float getRefractionConstant() {
|
public float getRefractionConstant() {
|
||||||
return refractionConstant;
|
return refractionConstant;
|
||||||
}
|
}
|
||||||
@ -360,6 +378,10 @@ public class WaterFilter extends Filter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the maximum wave amplitude
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public float getMaxAmplitude() {
|
public float getMaxAmplitude() {
|
||||||
return maxAmplitude;
|
return maxAmplitude;
|
||||||
}
|
}
|
||||||
@ -437,7 +459,7 @@ public class WaterFilter extends Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* retunrs the foam hardness
|
* returns the foam hardness
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public float getFoamHardness() {
|
public float getFoamHardness() {
|
||||||
@ -739,7 +761,37 @@ public class WaterFilter extends Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* sets the texture to use to render caustics on the ground underwater
|
||||||
|
* @param causticsTexture
|
||||||
|
*/
|
||||||
|
public void setCausticsTexture(Texture2D causticsTexture) {
|
||||||
|
this.causticsTexture = causticsTexture;
|
||||||
|
if (material != null) {
|
||||||
|
material.setTexture("causticsMap", causticsTexture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns true if caustics are rendered
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isUseCaustics() {
|
||||||
|
return useCaustics;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set to true if you want caustics to be rendered on the ground underwater, false otherwise
|
||||||
|
* @param useCaustics
|
||||||
|
*/
|
||||||
|
public void setUseCaustics(boolean useCaustics) {
|
||||||
|
this.useCaustics = useCaustics;
|
||||||
|
if (material != null) {
|
||||||
|
material.setBoolean("UseCaustics", useCaustics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return true
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public boolean isUseHQShoreline() {
|
public boolean isUseHQShoreline() {
|
||||||
@ -810,7 +862,15 @@ public class WaterFilter extends Filter {
|
|||||||
if (material != null) {
|
if (material != null) {
|
||||||
material.setFloat("m_ReflectionDisplace", reflectionDisplace);
|
material.setFloat("m_ReflectionDisplace", reflectionDisplace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns true if the camera is under the water level
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isUnderWater() {
|
||||||
|
return underWater;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@ package jme3test.water;
|
|||||||
|
|
||||||
import com.jme3.app.SimpleApplication;
|
import com.jme3.app.SimpleApplication;
|
||||||
import com.jme3.audio.AudioNode;
|
import com.jme3.audio.AudioNode;
|
||||||
|
import com.jme3.audio.Filter;
|
||||||
|
import com.jme3.audio.LowPassFilter;
|
||||||
import com.jme3.bounding.BoundingBox;
|
import com.jme3.bounding.BoundingBox;
|
||||||
import com.jme3.effect.ParticleEmitter;
|
import com.jme3.effect.ParticleEmitter;
|
||||||
import com.jme3.effect.ParticleMesh;
|
import com.jme3.effect.ParticleMesh;
|
||||||
@ -16,7 +18,9 @@ import com.jme3.math.Quaternion;
|
|||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
|
|
||||||
import com.jme3.post.FilterPostProcessor;
|
import com.jme3.post.FilterPostProcessor;
|
||||||
|
import com.jme3.post.filters.BloomFilter;
|
||||||
import com.jme3.post.filters.DepthOfFieldFilter;
|
import com.jme3.post.filters.DepthOfFieldFilter;
|
||||||
|
import com.jme3.post.filters.FogFilter;
|
||||||
import com.jme3.post.filters.LightScatteringFilter;
|
import com.jme3.post.filters.LightScatteringFilter;
|
||||||
import com.jme3.post.filters.TranslucentBucketFilter;
|
import com.jme3.post.filters.TranslucentBucketFilter;
|
||||||
import com.jme3.renderer.Camera;
|
import com.jme3.renderer.Camera;
|
||||||
@ -34,6 +38,7 @@ import com.jme3.texture.Texture.WrapMode;
|
|||||||
import com.jme3.texture.Texture2D;
|
import com.jme3.texture.Texture2D;
|
||||||
import com.jme3.util.SkyFactory;
|
import com.jme3.util.SkyFactory;
|
||||||
import com.jme3.water.WaterFilter;
|
import com.jme3.water.WaterFilter;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import jme3tools.converters.ImageToAwt;
|
import jme3tools.converters.ImageToAwt;
|
||||||
@ -48,6 +53,10 @@ public class TestPostWater extends SimpleApplication {
|
|||||||
private WaterFilter water;
|
private WaterFilter water;
|
||||||
TerrainQuad terrain;
|
TerrainQuad terrain;
|
||||||
Material matRock;
|
Material matRock;
|
||||||
|
AudioNode waves;
|
||||||
|
LowPassFilter underWaterAudioFilter = new LowPassFilter(0.5f, 0.1f);
|
||||||
|
LowPassFilter underWaterReverbFilter = new LowPassFilter(0.5f, 0.1f);
|
||||||
|
LowPassFilter aboveWaterAudioFilter = new LowPassFilter(1, 1);
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
TestPostWater app = new TestPostWater();
|
TestPostWater app = new TestPostWater();
|
||||||
@ -57,6 +66,8 @@ public class TestPostWater extends SimpleApplication {
|
|||||||
@Override
|
@Override
|
||||||
public void simpleInitApp() {
|
public void simpleInitApp() {
|
||||||
|
|
||||||
|
setDisplayFps(false);
|
||||||
|
setDisplayStatView(false);
|
||||||
|
|
||||||
Node mainScene = new Node("Main Scene");
|
Node mainScene = new Node("Main Scene");
|
||||||
rootNode.attachChild(mainScene);
|
rootNode.attachChild(mainScene);
|
||||||
@ -72,9 +83,14 @@ public class TestPostWater extends SimpleApplication {
|
|||||||
l.setColor(ColorRGBA.White.clone().multLocal(0.3f));
|
l.setColor(ColorRGBA.White.clone().multLocal(0.3f));
|
||||||
mainScene.addLight(l);
|
mainScene.addLight(l);
|
||||||
|
|
||||||
flyCam.setMoveSpeed(100);
|
flyCam.setMoveSpeed(50);
|
||||||
|
|
||||||
|
//cam.setLocation(new Vector3f(-700, 100, 300));
|
||||||
|
//cam.setRotation(new Quaternion().fromAngleAxis(0.5f, Vector3f.UNIT_Z));
|
||||||
|
cam.setLocation(new Vector3f(-327.21957f, 61.6459f, 126.884346f));
|
||||||
|
cam.setRotation(new Quaternion(0.052168474f, 0.9443102f, -0.18395276f, 0.2678024f));
|
||||||
|
|
||||||
|
|
||||||
cam.setLocation(new Vector3f(-700, 100, 300));
|
|
||||||
cam.setRotation(new Quaternion().fromAngles(new float[]{FastMath.PI * 0.06f, FastMath.PI * 0.65f, 0}));
|
cam.setRotation(new Quaternion().fromAngles(new float[]{FastMath.PI * 0.06f, FastMath.PI * 0.65f, 0}));
|
||||||
|
|
||||||
|
|
||||||
@ -83,9 +99,8 @@ public class TestPostWater extends SimpleApplication {
|
|||||||
mainScene.attachChild(sky);
|
mainScene.attachChild(sky);
|
||||||
cam.setFrustumFar(4000);
|
cam.setFrustumFar(4000);
|
||||||
//cam.setFrustumNear(100);
|
//cam.setFrustumNear(100);
|
||||||
AudioNode waves = new AudioNode(audioRenderer, assetManager, "Sound/Environment/Ocean Waves.ogg", false);
|
|
||||||
waves.setLooping(true);
|
|
||||||
audioRenderer.playSource(waves);
|
|
||||||
|
|
||||||
//private FilterPostProcessor fpp;
|
//private FilterPostProcessor fpp;
|
||||||
|
|
||||||
@ -94,13 +109,20 @@ public class TestPostWater extends SimpleApplication {
|
|||||||
|
|
||||||
FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
|
FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
|
||||||
fpp.addFilter(water);
|
fpp.addFilter(water);
|
||||||
|
BloomFilter bloom=new BloomFilter();
|
||||||
|
bloom.setExposurePower(55);
|
||||||
|
fpp.addFilter(bloom);
|
||||||
|
LightScatteringFilter lsf = new LightScatteringFilter(lightDir.mult(-300));
|
||||||
|
lsf.setLightDensity(1.0f);
|
||||||
|
fpp.addFilter(lsf);
|
||||||
DepthOfFieldFilter dof=new DepthOfFieldFilter();
|
DepthOfFieldFilter dof=new DepthOfFieldFilter();
|
||||||
dof.setFocusDistance(0);
|
dof.setFocusDistance(0);
|
||||||
dof.setFocusRange(100);
|
dof.setFocusRange(100);
|
||||||
fpp.addFilter(new TranslucentBucketFilter());
|
|
||||||
fpp.addFilter(dof);
|
fpp.addFilter(dof);
|
||||||
|
//
|
||||||
|
|
||||||
|
// fpp.addFilter(new TranslucentBucketFilter());
|
||||||
|
//
|
||||||
|
|
||||||
// fpp.setNumSamples(4);
|
// fpp.setNumSamples(4);
|
||||||
|
|
||||||
@ -116,8 +138,17 @@ public class TestPostWater extends SimpleApplication {
|
|||||||
//water.setFoamHardness(0.6f);
|
//water.setFoamHardness(0.6f);
|
||||||
|
|
||||||
water.setWaterHeight(initialWaterHeight);
|
water.setWaterHeight(initialWaterHeight);
|
||||||
|
uw=cam.getLocation().y<waterHeight;
|
||||||
|
|
||||||
|
waves = new AudioNode(audioRenderer, assetManager, "Sound/Environment/Ocean Waves.ogg", false);
|
||||||
|
waves.setLooping(true);
|
||||||
|
waves.setReverbEnabled(true);
|
||||||
|
if(uw){
|
||||||
|
waves.setDryFilter(new LowPassFilter(0.5f, 0.1f));
|
||||||
|
}else{
|
||||||
|
waves.setDryFilter(aboveWaterAudioFilter);
|
||||||
|
}
|
||||||
|
audioRenderer.playSource(waves);
|
||||||
//
|
//
|
||||||
viewPort.addProcessor(fpp);
|
viewPort.addProcessor(fpp);
|
||||||
|
|
||||||
@ -140,8 +171,8 @@ public class TestPostWater extends SimpleApplication {
|
|||||||
inputManager.addMapping("foam1", new KeyTrigger(keyInput.KEY_1));
|
inputManager.addMapping("foam1", new KeyTrigger(keyInput.KEY_1));
|
||||||
inputManager.addMapping("foam2", new KeyTrigger(keyInput.KEY_2));
|
inputManager.addMapping("foam2", new KeyTrigger(keyInput.KEY_2));
|
||||||
inputManager.addMapping("foam3", new KeyTrigger(keyInput.KEY_3));
|
inputManager.addMapping("foam3", new KeyTrigger(keyInput.KEY_3));
|
||||||
createBox();
|
// createBox();
|
||||||
createFire();
|
// createFire();
|
||||||
}
|
}
|
||||||
Geometry box;
|
Geometry box;
|
||||||
|
|
||||||
@ -248,7 +279,7 @@ public class TestPostWater extends SimpleApplication {
|
|||||||
private float time = 0.0f;
|
private float time = 0.0f;
|
||||||
private float waterHeight = 0.0f;
|
private float waterHeight = 0.0f;
|
||||||
private float initialWaterHeight = 0.8f;
|
private float initialWaterHeight = 0.8f;
|
||||||
|
private boolean uw=false;
|
||||||
@Override
|
@Override
|
||||||
public void simpleUpdate(float tpf) {
|
public void simpleUpdate(float tpf) {
|
||||||
super.simpleUpdate(tpf);
|
super.simpleUpdate(tpf);
|
||||||
@ -256,5 +287,17 @@ public class TestPostWater extends SimpleApplication {
|
|||||||
time += tpf;
|
time += tpf;
|
||||||
waterHeight = (float) Math.cos(((time * 0.6f) % FastMath.TWO_PI)) * 1.5f;
|
waterHeight = (float) Math.cos(((time * 0.6f) % FastMath.TWO_PI)) * 1.5f;
|
||||||
water.setWaterHeight(initialWaterHeight + waterHeight);
|
water.setWaterHeight(initialWaterHeight + waterHeight);
|
||||||
|
if(water.isUnderWater() && !uw){
|
||||||
|
|
||||||
|
waves.setDryFilter(new LowPassFilter(0.5f, 0.1f));
|
||||||
|
uw=true;
|
||||||
|
}
|
||||||
|
if(!water.isUnderWater() && uw){
|
||||||
|
uw=false;
|
||||||
|
//waves.setReverbEnabled(false);
|
||||||
|
waves.setDryFilter(new LowPassFilter(1, 1f));
|
||||||
|
//waves.setDryFilter(new LowPassFilter(1,1f));
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user