Weiter an den Dialogen gearbeitet
This commit is contained in:
475
blight-assets/src/main/resources/Common/MatDefs/Water/Water.frag
Normal file
475
blight-assets/src/main/resources/Common/MatDefs/Water/Water.frag
Normal file
@@ -0,0 +1,475 @@
|
||||
#import "Common/ShaderLib/GLSLCompat.glsllib"
|
||||
#import "Common/ShaderLib/MultiSample.glsllib"
|
||||
#import "Common/ShaderLib/WaterUtil.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 g_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;
|
||||
|
||||
#ifdef ENABLE_AREA
|
||||
uniform vec3 m_Center;
|
||||
uniform float m_Radius;
|
||||
#endif
|
||||
|
||||
#ifdef WAVE_INTERACTION
|
||||
uniform sampler2D m_WaveMap;
|
||||
uniform vec2 m_WaveAreaCenter;
|
||||
uniform float m_WaveAreaInvExtent;
|
||||
uniform float m_WaveStrength;
|
||||
#endif
|
||||
|
||||
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 ;
|
||||
|
||||
vec2 m_FrustumNearFar; //=vec2(1.0,m_UnderWaterFogDistance);
|
||||
const float LOG2 = 1.442695;
|
||||
|
||||
|
||||
varying vec2 texCoord;
|
||||
|
||||
void setGlobals(){
|
||||
scale = vec2(m_WaveScale, m_WaveScale);
|
||||
refractionScale = m_WaveScale;
|
||||
m_FrustumNearFar=vec2(1.0,m_UnderWaterFogDistance);
|
||||
}
|
||||
|
||||
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 = g_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);
|
||||
}
|
||||
|
||||
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 = 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);
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
// 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;
|
||||
#else
|
||||
// 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;
|
||||
#endif
|
||||
|
||||
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);
|
||||
texC = clamp(texC,0.0,1.0);
|
||||
refraction = fetchTextureSample(m_Texture, texC, sampleNum).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.0 * 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){
|
||||
#ifdef ENABLE_AREA
|
||||
if(isOverExtent(m_CameraPosition, m_Center, m_Radius)){
|
||||
return fetchTextureSample(m_Texture, texCoord, sampleNum);
|
||||
}
|
||||
#endif
|
||||
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);
|
||||
|
||||
#ifdef ENABLE_AREA
|
||||
if(isOverExtent(position, m_Center, m_Radius)){
|
||||
return vec4(color2, 1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
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 / float(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);
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
// 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;
|
||||
#else
|
||||
// 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;
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
#if __VERSION__ >= 130 && !defined GL_ES
|
||||
// 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;
|
||||
#else
|
||||
// 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;
|
||||
#endif
|
||||
|
||||
#else
|
||||
normal = myNormal;
|
||||
#endif
|
||||
|
||||
// Overlay dynamic wave normals from CPU simulation (WAVE_INTERACTION define)
|
||||
#ifdef WAVE_INTERACTION
|
||||
vec2 waveUV = (surfacePoint.xz - m_WaveAreaCenter) * m_WaveAreaInvExtent + 0.5;
|
||||
float inWave = step(0.0, waveUV.x) * step(waveUV.x, 1.0)
|
||||
* step(0.0, waveUV.y) * step(waveUV.y, 1.0);
|
||||
float ts = 1.0 / 256.0;
|
||||
float wl = texture2D(m_WaveMap, waveUV + vec2(-ts, 0.0)).r * 2.0 - 1.0;
|
||||
float wr = texture2D(m_WaveMap, waveUV + vec2( ts, 0.0)).r * 2.0 - 1.0;
|
||||
float wd = texture2D(m_WaveMap, waveUV + vec2(0.0, -ts)).r * 2.0 - 1.0;
|
||||
float wu = texture2D(m_WaveMap, waveUV + vec2(0.0, ts)).r * 2.0 - 1.0;
|
||||
vec3 waveNorm = normalize(vec3((wl - wr) * m_WaveStrength, 1.0, (wd - wu) * m_WaveStrength));
|
||||
normal = normalize(mix(normal, normalize(normal + waveNorm), inWave));
|
||||
#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));
|
||||
texC = clamp(texC,vec2(0.0),vec2(0.999));
|
||||
refraction = fetchTextureSample(m_Texture, texC, sampleNum).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;
|
||||
|
||||
vec4 foam1 = texture2D(m_FoamMap, texC);
|
||||
vec4 foam2 = texture2D(m_FoamMap, texCoord2);
|
||||
|
||||
if(depth2 < m_FoamExistence.x){
|
||||
foam = (foam1.r + foam2).rgb * vec3(m_FoamIntensity);
|
||||
}else if(depth2 < m_FoamExistence.y){
|
||||
foam = mix((foam1 + foam2) * 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 += ((foam1 + foam2) * 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(){
|
||||
setGlobals();
|
||||
#ifdef RESOLVE_MS
|
||||
vec4 color = vec4(0.0);
|
||||
for (int i = 0; i < m_NumSamples; i++){
|
||||
color += main_multiSample(i);
|
||||
}
|
||||
gl_FragColor = color / float(m_NumSamples);
|
||||
#else
|
||||
gl_FragColor = main_multiSample(0);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
MaterialDef Advanced Water {
|
||||
|
||||
MaterialParameters {
|
||||
Int BoundDrawBuffer
|
||||
Int NumSamples
|
||||
Int NumSamplesDepth
|
||||
Texture2D FoamMap
|
||||
Texture2D CausticsMap
|
||||
Texture2D NormalMap -LINEAR
|
||||
Texture2D ReflectionMap
|
||||
Texture2D HeightMap -LINEAR
|
||||
Texture2D Texture
|
||||
Texture2D DepthTexture
|
||||
Vector3 CameraPosition
|
||||
Float Time
|
||||
Vector3 frustumCorner
|
||||
Matrix4 TextureProjMatrix
|
||||
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
|
||||
|
||||
Float Radius
|
||||
Vector3 Center
|
||||
Boolean SquareArea
|
||||
|
||||
// Dynamic wave interaction
|
||||
Texture2D WaveMap -LINEAR
|
||||
Vector2 WaveAreaCenter
|
||||
Float WaveAreaInvExtent
|
||||
Float WaveStrength
|
||||
Boolean WaveInteraction
|
||||
}
|
||||
|
||||
Technique {
|
||||
VertexShader GLSL310 GLSL300 GLSL150 GLSL120 : Common/MatDefs/Post/Post.vert
|
||||
FragmentShader GLSL310 GLSL300 GLSL150 GLSL120: Common/MatDefs/Water/Water.frag
|
||||
|
||||
WorldParameters {
|
||||
ViewProjectionMatrixInverse
|
||||
}
|
||||
|
||||
Defines {
|
||||
BOUND_DRAW_BUFFER: BoundDrawBuffer
|
||||
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
|
||||
ENABLE_AREA : Center
|
||||
SQUARE_AREA : SquareArea
|
||||
WAVE_INTERACTION : WaveInteraction
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,6 +4,7 @@ MaterialDef Fern {
|
||||
Color Diffuse (Color) : 0.18 0.60 0.10 1.0
|
||||
Float WindStrength : 0.15
|
||||
Float WindSpeed : 0.6
|
||||
Vector2 WindDir : 0.0 1.0
|
||||
Texture2D DiffuseMap
|
||||
Boolean HasDiffuseMap : false
|
||||
Texture2D NormalMap -LINEAR
|
||||
|
||||
27
blight-assets/src/main/resources/MatDefs/GrassSeed.j3md
Normal file
27
blight-assets/src/main/resources/MatDefs/GrassSeed.j3md
Normal file
@@ -0,0 +1,27 @@
|
||||
MaterialDef GrassSeed {
|
||||
|
||||
MaterialParameters {
|
||||
Texture2D ColorMap
|
||||
Float WindSpeed : 1.0
|
||||
Float WindStrength : 0.15
|
||||
Vector2 WindDir : 0.0 1.0
|
||||
Vector3 SunDir : 0.35 0.8 0.45
|
||||
Color SunColor : 0.95 0.90 0.75 1.0
|
||||
}
|
||||
|
||||
Technique {
|
||||
VertexShader GLSL150: Shaders/GrassSeed.vert
|
||||
FragmentShader GLSL150: Shaders/GrassSeed.frag
|
||||
|
||||
WorldParameters {
|
||||
WorldViewProjectionMatrix
|
||||
WorldMatrix
|
||||
Time
|
||||
AmbientLightColor
|
||||
}
|
||||
|
||||
RenderState {
|
||||
FaceCull Off
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ MaterialDef GrassVertex {
|
||||
MaterialParameters {
|
||||
Float WindSpeed : 1.0
|
||||
Float WindStrength : 0.15
|
||||
Vector2 WindDir : 0.0 1.0
|
||||
Vector3 SunDir : 0.35 0.8 0.45
|
||||
Color SunColor : 0.95 0.90 0.75 1.0
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ MaterialDef Tree {
|
||||
Color Diffuse (Color) : 0.42 0.26 0.10 1.0
|
||||
Float WindStrength : 0.15
|
||||
Float WindSpeed : 0.5
|
||||
Vector2 WindDir : 0.0 1.0
|
||||
Texture2D BarkMap
|
||||
Boolean HasBarkMap : false
|
||||
Vector3 LightDir
|
||||
|
||||
@@ -4,6 +4,7 @@ MaterialDef TreeLeaf {
|
||||
Color Diffuse (Color) : 0.18 0.60 0.10 1.0
|
||||
Float WindStrength : 0.30
|
||||
Float WindSpeed : 0.7
|
||||
Vector2 WindDir : 0.0 1.0
|
||||
Texture2D LeafMap
|
||||
Boolean HasLeafMap : false
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ uniform mat4 g_WorldMatrix;
|
||||
uniform float g_Time;
|
||||
uniform float m_WindStrength;
|
||||
uniform float m_WindSpeed;
|
||||
uniform vec2 m_WindDir;
|
||||
|
||||
in vec3 inPosition;
|
||||
in vec3 inNormal;
|
||||
@@ -21,10 +22,21 @@ void main() {
|
||||
float windW = inColor.r;
|
||||
float t = g_Time * m_WindSpeed;
|
||||
vec4 wp = g_WorldMatrix * vec4(inPosition, 1.0);
|
||||
float phase = wp.x * 0.08 + wp.z * 0.06;
|
||||
float swayX = sin(t + phase) * windW * m_WindStrength;
|
||||
float swayZ = cos(t*0.73 + phase) * windW * m_WindStrength * 0.55;
|
||||
vec3 anim = inPosition + vec3(swayX, 0.0, swayZ);
|
||||
vec2 worldXZ = wp.xz;
|
||||
|
||||
vec2 windN = (dot(m_WindDir, m_WindDir) > 0.001) ? normalize(m_WindDir) : vec2(0.0, 1.0);
|
||||
vec2 perpN = vec2(-windN.y, windN.x);
|
||||
float wavePhase = dot(worldXZ, windN);
|
||||
float randPhase = fract(sin(dot(worldXZ, vec2(127.1, 311.7))) * 43758.5453) * 6.2832;
|
||||
|
||||
float mainSway = sin(t + wavePhase * 0.08 + randPhase) * windW * m_WindStrength;
|
||||
float crossSway = cos(t * 0.73 + wavePhase * 0.06 + randPhase) * windW * m_WindStrength * 0.25;
|
||||
|
||||
vec3 anim = inPosition + vec3(
|
||||
windN.x * mainSway + perpN.x * crossSway,
|
||||
0.0,
|
||||
windN.y * mainSway + perpN.y * crossSway
|
||||
);
|
||||
|
||||
gl_Position = g_WorldViewProjectionMatrix * vec4(anim, 1.0);
|
||||
texCoord = inTexCoord;
|
||||
|
||||
19
blight-assets/src/main/resources/Shaders/GrassSeed.frag
Normal file
19
blight-assets/src/main/resources/Shaders/GrassSeed.frag
Normal file
@@ -0,0 +1,19 @@
|
||||
uniform sampler2D m_ColorMap;
|
||||
uniform vec4 g_AmbientLightColor;
|
||||
uniform vec3 m_SunDir;
|
||||
uniform vec4 m_SunColor;
|
||||
|
||||
in vec2 varUV;
|
||||
|
||||
out vec4 outFragColor;
|
||||
|
||||
void main() {
|
||||
vec4 c = texture(m_ColorMap, varUV);
|
||||
if (c.a < 0.15) discard;
|
||||
|
||||
// Wrapped diffuse – kein Normalvektor nötig für Billboard-Quads
|
||||
float light = 0.5 + 0.5 * max(dot(m_SunDir, vec3(0.0, 1.0, 0.0)), 0.0);
|
||||
vec3 ambient = g_AmbientLightColor.rgb * c.rgb;
|
||||
vec3 diffuse = m_SunColor.rgb * c.rgb * light;
|
||||
outFragColor = vec4(min(ambient + diffuse, c.rgb * 1.5), c.a);
|
||||
}
|
||||
34
blight-assets/src/main/resources/Shaders/GrassSeed.vert
Normal file
34
blight-assets/src/main/resources/Shaders/GrassSeed.vert
Normal file
@@ -0,0 +1,34 @@
|
||||
uniform mat4 g_WorldViewProjectionMatrix;
|
||||
uniform mat4 g_WorldMatrix;
|
||||
uniform float g_Time;
|
||||
|
||||
uniform float m_WindSpeed;
|
||||
uniform float m_WindStrength;
|
||||
uniform vec2 m_WindDir;
|
||||
|
||||
in vec3 inPosition;
|
||||
in vec2 inTexCoord; // echte UV-Koordinaten der Samen-Textur
|
||||
|
||||
out vec2 varUV;
|
||||
|
||||
void main() {
|
||||
vec4 pos = vec4(inPosition, 1.0);
|
||||
|
||||
vec2 worldXZ = (g_WorldMatrix * pos).xz;
|
||||
float t = g_Time * m_WindSpeed;
|
||||
|
||||
vec2 windN = (dot(m_WindDir, m_WindDir) > 0.001) ? normalize(m_WindDir) : vec2(0.0, 1.0);
|
||||
float wavePhase = dot(worldXZ, windN);
|
||||
float randPhase = fract(sin(dot(worldXZ, vec2(127.1, 311.7))) * 43758.5453) * 6.2832;
|
||||
|
||||
float sway = sin(t * 2.1 + wavePhase * 0.10 + randPhase) * 0.6
|
||||
+ sin(t * 1.4 + wavePhase * 0.06 + randPhase * 0.73) * 0.4;
|
||||
|
||||
// Samen sitzen immer an der Spitze → voller Windfaktor (wf = 1.0)
|
||||
float bend = sway * m_WindStrength;
|
||||
pos.x += windN.x * bend;
|
||||
pos.z += windN.y * bend;
|
||||
|
||||
varUV = inTexCoord;
|
||||
gl_Position = g_WorldViewProjectionMatrix * pos;
|
||||
}
|
||||
@@ -4,6 +4,7 @@ uniform float g_Time;
|
||||
|
||||
uniform float m_WindSpeed;
|
||||
uniform float m_WindStrength;
|
||||
uniform vec2 m_WindDir; // normierter XZ-Windvektor
|
||||
|
||||
in vec3 inPosition;
|
||||
in vec3 inNormal;
|
||||
@@ -18,22 +19,28 @@ void main() {
|
||||
float wf = inTexCoord.x;
|
||||
|
||||
if (wf > 0.001) {
|
||||
// Weltposition als Phasenbasis → jeder Halm schwingt anders
|
||||
vec2 worldXZ = (g_WorldMatrix * pos).xz;
|
||||
float t = g_Time * m_WindSpeed;
|
||||
|
||||
float sway = sin(t * 2.1 + worldXZ.x * 0.08 + worldXZ.y * 0.06) * 0.6
|
||||
+ sin(t * 1.4 - worldXZ.x * 0.05 + worldXZ.y * 0.09) * 0.4;
|
||||
// Windrichtung (Fallback: Süd)
|
||||
vec2 windN = (dot(m_WindDir, m_WindDir) > 0.001) ? normalize(m_WindDir) : vec2(0.0, 1.0);
|
||||
|
||||
// Wellenfront: Position entlang der Windachse → Halme in Windrichtung erreicht der Impuls später
|
||||
float wavePhase = dot(worldXZ, windN);
|
||||
|
||||
// Zufälliger Phasenversatz pro Halm (Spatial-Hash → kein synchrones Schwingen)
|
||||
float randPhase = fract(sin(dot(worldXZ, vec2(127.1, 311.7))) * 43758.5453) * 6.2832;
|
||||
|
||||
float sway = sin(t * 2.1 + wavePhase * 0.10 + randPhase) * 0.6
|
||||
+ sin(t * 1.4 + wavePhase * 0.06 + randPhase * 0.73) * 0.4;
|
||||
|
||||
// Quadratische Gewichtung: Spitze biegt sich mehr als Basis
|
||||
float bend = sway * m_WindStrength * wf * wf;
|
||||
pos.x += bend;
|
||||
pos.z += bend * 0.3;
|
||||
pos.x += windN.x * bend;
|
||||
pos.z += windN.y * bend;
|
||||
}
|
||||
|
||||
varColor = inColor;
|
||||
// Normal in Weltkoordinaten (WorldMatrix ist für Gras typischerweise Identität)
|
||||
varNormal = normalize(mat3(g_WorldMatrix) * inNormal);
|
||||
|
||||
gl_Position = g_WorldViewProjectionMatrix * pos;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#import "Common/ShaderLib/GLSLCompat.glsllib"
|
||||
|
||||
|
||||
uniform mat4 g_WorldViewProjectionMatrix;
|
||||
uniform mat4 g_WorldMatrix;
|
||||
uniform mat4 g_WorldViewProjectionMatrix;
|
||||
uniform mat4 g_WorldMatrix;
|
||||
uniform float g_Time;
|
||||
uniform float m_WindStrength;
|
||||
uniform float m_WindSpeed;
|
||||
uniform vec2 m_WindDir;
|
||||
|
||||
in vec3 inPosition;
|
||||
in vec3 inNormal;
|
||||
@@ -16,18 +16,27 @@ out vec2 texCoord;
|
||||
out vec3 worldNormal;
|
||||
|
||||
void main() {
|
||||
float windW = inColor.r;
|
||||
float t = g_Time * m_WindSpeed;
|
||||
float windW = inColor.r;
|
||||
float t = g_Time * m_WindSpeed;
|
||||
|
||||
// Welt-Position für orts-abhängige Phase (verhindert synchrones Schwingen)
|
||||
vec4 worldPos = g_WorldMatrix * vec4(inPosition, 1.0);
|
||||
float phase = worldPos.x * 0.08 + worldPos.z * 0.06;
|
||||
float swayX = sin(t + phase) * windW * m_WindStrength;
|
||||
float swayZ = cos(t * 0.73 + phase) * windW * m_WindStrength * 0.55;
|
||||
vec4 worldPos = g_WorldMatrix * vec4(inPosition, 1.0);
|
||||
vec2 worldXZ = worldPos.xz;
|
||||
|
||||
vec3 animPos = inPosition + vec3(swayX, 0.0, swayZ);
|
||||
vec2 windN = (dot(m_WindDir, m_WindDir) > 0.001) ? normalize(m_WindDir) : vec2(0.0, 1.0);
|
||||
vec2 perpN = vec2(-windN.y, windN.x);
|
||||
float wavePhase = dot(worldXZ, windN);
|
||||
float randPhase = fract(sin(dot(worldXZ, vec2(127.1, 311.7))) * 43758.5453) * 6.2832;
|
||||
|
||||
gl_Position = g_WorldViewProjectionMatrix * vec4(animPos, 1.0);
|
||||
texCoord = inTexCoord;
|
||||
worldNormal = normalize((g_WorldMatrix * vec4(inNormal, 0.0)).xyz);
|
||||
}
|
||||
float mainSway = sin(t + wavePhase * 0.08 + randPhase) * windW * m_WindStrength;
|
||||
float crossSway = cos(t * 0.73 + wavePhase * 0.06 + randPhase) * windW * m_WindStrength * 0.25;
|
||||
|
||||
vec3 animPos = inPosition + vec3(
|
||||
windN.x * mainSway + perpN.x * crossSway,
|
||||
0.0,
|
||||
windN.y * mainSway + perpN.y * crossSway
|
||||
);
|
||||
|
||||
gl_Position = g_WorldViewProjectionMatrix * vec4(animPos, 1.0);
|
||||
texCoord = inTexCoord;
|
||||
worldNormal = normalize((g_WorldMatrix * vec4(inNormal, 0.0)).xyz);
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 277 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 906 KiB |
Binary file not shown.
Binary file not shown.
BIN
blight-assets/src/main/resources/animations/clips/talking1.j3o
Normal file
BIN
blight-assets/src/main/resources/animations/clips/talking1.j3o
Normal file
Binary file not shown.
BIN
blight-assets/src/main/resources/animations/clips/talking2.j3o
Normal file
BIN
blight-assets/src/main/resources/animations/clips/talking2.j3o
Normal file
Binary file not shown.
BIN
blight-assets/src/main/resources/animations/clips/yelling.j3o
Normal file
BIN
blight-assets/src/main/resources/animations/clips/yelling.j3o
Normal file
Binary file not shown.
@@ -13,7 +13,8 @@
|
||||
"stand_up",
|
||||
"stand_up_bench",
|
||||
"tpose",
|
||||
"walking"
|
||||
"walking",
|
||||
"sitting_talking"
|
||||
],
|
||||
"actionMap": {
|
||||
"DEFAULT": "tpose",
|
||||
@@ -31,7 +32,22 @@
|
||||
},
|
||||
"previewModelPath": "Models/Chars/mainchar.j3o",
|
||||
"animOffsets": {
|
||||
"sitting": {"tx": 0.0, "ty": 0.0, "tz": -0.5, "rx": 0.0, "ry": 0.0, "rz": 0.0},
|
||||
"get_up_sitting": {"tx": 0.0, "ty": 0.0, "tz": -0.5, "rx": 0.0, "ry": 0.0, "rz": 0.0}
|
||||
}
|
||||
"sitting": {
|
||||
"tx": 0.0,
|
||||
"ty": 0.0,
|
||||
"tz": -0.5,
|
||||
"rx": 0.0,
|
||||
"ry": 0.0,
|
||||
"rz": 0.0
|
||||
},
|
||||
"get_up_sitting": {
|
||||
"tx": 0.0,
|
||||
"ty": 0.0,
|
||||
"tz": -0.5,
|
||||
"rx": 0.0,
|
||||
"ry": 0.0,
|
||||
"rz": 0.0
|
||||
}
|
||||
},
|
||||
"subClips": {}
|
||||
}
|
||||
Reference in New Issue
Block a user