Dynamic Water in Barrens and Glen

This commit is contained in:
Issac332 2026-05-28 22:42:10 +03:00
parent 549bd44cce
commit 7763b998a6
12 changed files with 334 additions and 111 deletions

View file

@ -191,6 +191,7 @@ set(EMBEDDED_INPUT
shader/hue.frag
shader/sprite.frag
shader/worldMachine.frag
shader/water.frag
shader/plane.frag
shader/gray.frag
shader/bitmapBlit.frag
@ -205,7 +206,6 @@ set(EMBEDDED_INPUT
shader/simple.vert
shader/simpleColor.vert
shader/sprite.vert
shader/worldMachine.vert
shader/tilemap.vert
shader/blur.frag
shader/blurH.vert

View file

@ -50,6 +50,7 @@ DEF_PROP_I(Plane, OX)
DEF_PROP_I(Plane, OY)
DEF_PROP_I(Plane, Opacity)
DEF_PROP_I(Plane, BlendType)
DEF_PROP_I(Plane, Shader)
DEF_PROP_F(Plane, ZoomX)
DEF_PROP_F(Plane, ZoomY)
@ -75,4 +76,5 @@ void planeBindingInit(){
INIT_PROP_BIND( Plane, BlendType, "blend_type" );
INIT_PROP_BIND( Plane, Color, "color" );
INIT_PROP_BIND( Plane, Tone, "tone" );
INIT_PROP_BIND( Plane, Shader, "shader" );
}

View file

@ -62,10 +62,7 @@ class Game_Map
ANIMATED = [
'blue_water',
]
FADE_ANIMATION_PANORAMA = [
'dark_water',
'green_water',
]
FADE_ANIMATION_PANORAMA = []
ONETOONE = [
'blue_water',
'green_water',
@ -73,7 +70,7 @@ class Game_Map
]
NOZOOM = [
'dark_water',
#'green_water',
'green_water',
]
ALWAYS_MOVING = [

View file

@ -28,12 +28,12 @@ class Spriteset_Map
if $game_map.tileset_name == "blank"
@tilemap.tileset = nil
else
translation_name = "#{$persistent.langcode}/#{$game_map.tileset_name}"
if File.exist?("Graphics/Tilesets/#{translation_name}.png")
@tilemap.tileset = RPG::Cache.tileset(translation_name)
else
@tilemap.tileset = RPG::Cache.tileset($game_map.tileset_name)
end
translation_name = "#{$persistent.langcode}/#{$game_map.tileset_name}"
if File.exist?("Graphics/Tilesets/#{translation_name}.png")
@tilemap.tileset = RPG::Cache.tileset(translation_name)
else
@tilemap.tileset = RPG::Cache.tileset($game_map.tileset_name)
end
end
for i in 0..6
autotile_name = $game_map.autotile_names[i]
@ -173,17 +173,33 @@ class Spriteset_Map
end
if @panorama_name != ""
if $game_map.pan_fade_animate
@panorama.shader = Shader::Plane
if @panorama2 == nil
@panorama2 = Plane.new(@viewport_bg)
@panorama2.z = -999
@panorama2.opacity = 0
@pan_frame_index = 0
end
@panorama.bitmap = RPG::Cache.panorama(@panorama_name + (1 + @pan_frame_index).to_s, @panorama_hue)
@panorama2.bitmap = RPG::Cache.panorama(@panorama_name + (1 + @pan_frame_index).to_s, @panorama_hue)
@panorama.bitmap = RPG::Cache.panorama(@panorama_name + (1 + @pan_frame_index).to_s, @panorama_hue)
@panorama2.bitmap = RPG::Cache.panorama(@panorama_name + (1 + @pan_frame_index).to_s, @panorama_hue)
else
@panorama.bitmap = RPG::Cache.panorama(@panorama_name, @panorama_hue)
if @panorama_name == "dark_water"
@panorama.shader = Shader::Water
@panorama.color.set(0, 0, 127, 0)
@panorama.tone.set(0, 0, 255, 63)
@panorama.blend_type = 1
elsif @panorama_name == "green_water"
@panorama.shader = Shader::Water
@panorama.color.set(0, 21, 43, 100)
@panorama.tone.set(13, 236, 255, 200)
@panorama.blend_type = 1
else
@panorama.shader = Shader::Plane
@panorama.color.set(0, 0, 0, 0)
@panorama.tone.set(0, 0, 0, 0)
@panorama.blend_type = 0
end
@panorama.bitmap = RPG::Cache.panorama(@panorama_name, @panorama_hue)
end
end
Graphics.frame_reset
@ -272,7 +288,7 @@ class Spriteset_Map
end
end
if $game_map.pan_fade_animate
if $game_map.pan_fade_animate && @panorama2 != nil
@panorama2.opacity += 3
@panorama2.ox = @panorama.ox
@panorama2.oy = @panorama.oy
@ -307,19 +323,19 @@ class Spriteset_Map
# based on its current width and height
# no point in updating the sprite if offscreen
# this greatly increases performance on larger maps
if Graphics.width == 1280
((sprite.character.real_x + (sprite.ox*4) > Graphics.width - 128) &&
(sprite.character.real_x - (sprite.ox*4) < Graphics.width + (21 * 128)) &&
(sprite.character.real_y + (sprite.oy*4) > (Graphics.height) - 128) &&
(sprite.character.real_y - (sprite.oy*4) < (Graphics.height) + (17 * 128)))
if Graphics.width == 1280
((sprite.character.real_x + (sprite.ox*4) > Graphics.width - 128) &&
(sprite.character.real_x - (sprite.ox*4) < Graphics.width + (21 * 128)) &&
(sprite.character.real_y + (sprite.oy*4) > (Graphics.height) - 128) &&
(sprite.character.real_y - (sprite.oy*4) < (Graphics.height) + (17 * 128)))
sprite.update
else
((sprite.character.real_x + (sprite.ox*4) > Graphics.width - 128) &&
(sprite.character.real_x - (sprite.ox*4) < Graphics.width + (10 * 128)) &&
(sprite.character.real_y + (sprite.oy*4) > (Graphics.height) - 128) &&
(sprite.character.real_y - (sprite.oy*4) < (Graphics.height) + (6 * 128)))
else
((sprite.character.real_x + (sprite.ox*4) > Graphics.width - 128) &&
(sprite.character.real_x - (sprite.ox*4) < Graphics.width + (10 * 128)) &&
(sprite.character.real_y + (sprite.oy*4) > (Graphics.height) - 128) &&
(sprite.character.real_y - (sprite.oy*4) < (Graphics.height) + (6 * 128)))
sprite.update
end
end
else
sprite.update_fast
end

104
shader/water.frag Normal file
View file

@ -0,0 +1,104 @@
uniform sampler2D texture;
uniform lowp vec4 tone;
uniform lowp float opacity;
uniform lowp vec4 color;
uniform lowp vec4 modulate;
uniform float bushDepth;
uniform lowp float bushOpacity;
uniform float uTime;
varying vec2 v_texCoord;
uniform vec2 texSizeInv;
const vec3 lumaF = vec3(.299, .587, .114);
const float WATER_DISTORTION = 0.75;
vec4 mod289(vec4 x)
{
return x - floor(x * (1.0 / 289.0)) * 289.0;
}
vec4 permute(vec4 x)
{
return mod289(((x*34.0)+1.0)*x);
}
vec4 taylorInvSqrt(vec4 r)
{
return 1.79284291400159 - 0.85373472095314 * r;
}
vec2 fade(vec2 t) {
return t*t*t*(t*(t*6.0-15.0)+10.0);
}
float pnoise(vec2 P)
{
vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0);
vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0);
Pi = mod289(Pi); // To avoid truncation effects in permutation
vec4 ix = Pi.xzxz;
vec4 iy = Pi.yyww;
vec4 fx = Pf.xzxz;
vec4 fy = Pf.yyww;
vec4 i = permute(permute(ix) + iy);
vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0 ;
vec4 gy = abs(gx) - 0.5 ;
vec4 tx = floor(gx + 0.5);
gx = gx - tx;
vec2 g00 = vec2(gx.x,gy.x);
vec2 g10 = vec2(gx.y,gy.y);
vec2 g01 = vec2(gx.z,gy.z);
vec2 g11 = vec2(gx.w,gy.w);
vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));
g00 *= norm.x;
g01 *= norm.y;
g10 *= norm.z;
g11 *= norm.w;
float n00 = dot(g00, vec2(fx.x, fy.x));
float n10 = dot(g10, vec2(fx.y, fy.y));
float n01 = dot(g01, vec2(fx.z, fy.z));
float n11 = dot(g11, vec2(fx.w, fy.w));
vec2 fade_xy = fade(Pf.xy);
vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x);
float n_xy = mix(n_x.x, n_x.y, fade_xy.y);
return 2.3 * n_xy;
}
void main(){
vec2 uv = v_texCoord * texSizeInv * 8192.0;
uv = floor(uv * 16.0) / 16.0;
float noise = (pnoise(uv) + 1.0) / 2.0;
vec2 uv1 = uv - vec2(uTime, uTime * 0.5 + 0.5) * 0.56;
float noise1 = (pnoise(uv1 + vec2(WATER_DISTORTION, -WATER_DISTORTION) * noise) + 1.0) / 2.0;
float p = pow(noise1 + 0.02, 20.0);
vec2 uv2 = uv - vec2(uTime - 1.5, -uTime * 0.5) * 0.24;
float noise2 = (pnoise(uv2 + vec2(WATER_DISTORTION, -WATER_DISTORTION) * noise) + 1.0) / 2.0;
float p2 = pow(noise2 + 0.02, 20.0);
vec4 frag = mix(vec4(color.r, color.g, color.b, 1.0) * color.a, vec4(color.r, color.g, color.b, 1.0) * tone.a, noise1) + vec4(p, p, p, 1.0) * tone;
frag += mix(vec4(color.r, color.g, color.b, 1.0) * color.a, vec4(color.r, color.g, color.b, 1.0) * tone.a, noise2) + vec4(p2, p2, p2, 1.0) * tone;
/* Apply opacity */
frag.a *= opacity;
/* Apply modulation */
frag *= modulate;
gl_FragColor = frag;
}

View file

@ -1,16 +0,0 @@
uniform mat4 projMat;
uniform mat4 spriteMat;
uniform vec2 texSizeInv;
attribute vec2 position;
attribute vec2 texCoord;
varying vec2 v_texCoord;
void main(){
gl_Position = projMat * spriteMat * vec4(position, 0, 1);
v_texCoord = texCoord * texSizeInv;
}

View file

@ -55,6 +55,8 @@ struct PlanePrivate{
int ox, oy;
float zoomX, zoomY;
int shader;
Scene::Geometry sceneGeo;
bool quadSourceDirty;
@ -75,7 +77,8 @@ struct PlanePrivate{
tone(&tmp.tone),
ox(0), oy(0),
zoomX(1), zoomY(1),
quadSourceDirty(false)
quadSourceDirty(false),
shader(ShaderType::SHADER_plane)
{
updateSrcRectCon();
prepareCon = shState->prepareDraw.connect
@ -176,6 +179,7 @@ DEF_ATTR_SIMPLE(Plane, SrcRect, Rect&, *p->srcRect)
DEF_ATTR_SIMPLE(Plane, Opacity, int, p->opacity)
DEF_ATTR_SIMPLE(Plane, Color, Color&, *p->color)
DEF_ATTR_SIMPLE(Plane, Tone, Tone&, *p->tone)
DEF_ATTR_SIMPLE(Plane, Shader, int, p->shader)
Plane::~Plane(){
dispose();
@ -269,26 +273,87 @@ void Plane::draw(){
ShaderBase *base;
if (p->color->hasEffect() || p->tone->hasEffect() || p->opacity != 255){
PlaneShader &shader = shState->shaders().plane;
shader.bind();
shader.applyViewportProj();
shader.setTone(p->tone->norm);
shader.setColor(p->color->norm);
shader.setFlash(Vec4());
shader.setOpacity(p->opacity.norm);
bool renderEffect = p->color->hasEffect() ||
p->tone->hasEffect();
switch (p->shader)
{
case ShaderType::SHADER_plane:
{
PlaneShader &shader = shState->shaders().plane;
base = &shader;
}else{
SimpleShader &shader = shState->shaders().simple;
shader.bind();
shader.applyViewportProj();
shader.setTone(p->tone->norm);
shader.setColor(p->color->norm);
shader.setFlash(Vec4());
shader.setOpacity(p->opacity.norm);
shader.bind();
shader.applyViewportProj();
shader.setTranslation(Vec2i());
base = &shader;
break;
}
case ShaderType::SHADER_obscured:
{
ObscuredShader &shader = shState->shaders().obscured;
shader.bind();
shader.applyViewportProj();
shader.setObscured(shState->graphics().obscuredTex());
base = &shader;
break;
}
case ShaderType::SHADER_water:
{
WaterShader &shader = shState->shaders().water;
base = &shader;
defaultSpriteShaderInit(shader);
base = &shader;
break;
}
case ShaderType::SHADER_worldMachine:
{
WMShader &shader = shState->shaders().worldMachine;
defaultSpriteShaderInit(shader);
base = &shader;
break;
}
default:
{
if (renderEffect){
SpriteShader &shader = shState->shaders().sprite;
defaultSpriteShaderInit(shader);
base = &shader;
}
else if (p->opacity != 255){
AlphaSpriteShader &shader = shState->shaders().alphaSprite;
shader.bind();
shader.setAlpha(p->opacity.norm);
shader.applyViewportProj();
base = &shader;
}
else{
SimpleSpriteShader &shader = shState->shaders().simpleSprite;
shader.bind();
shader.applyViewportProj();
base = &shader;
}
break;
}
}
boost::chrono::high_resolution_clock::time_point currentTime = boost::chrono::high_resolution_clock::now();
boost::chrono::duration<float> elapsed = currentTime - startTime;
base->setTime(elapsed.count());
base->setTranslation(Vec2i());
glState.blendMode.pushSet(p->blendType);
@ -318,3 +383,16 @@ void Plane::releaseResources(){
delete p;
}
void Plane::defaultSpriteShaderInit(SpriteShaderBase &shader){
shader.bind();
shader.applyViewportProj();
shader.setTone(p->tone->norm);
shader.setOpacity(p->opacity.norm);
shader.setBushOpacity(1.0f);
shader.setColor(p->color->norm);
shader.setModulate(Vec4(1.0f, 1.0f, 1.0f, 1.0f));
}

View file

@ -24,6 +24,9 @@
#include "disposable.h"
#include "viewport.h"
#include "shader.h"
#include <boost/chrono.hpp>
class Bitmap;
struct Color;
@ -33,6 +36,8 @@ struct PlanePrivate;
class Plane : public ViewportElement, public Disposable{
public:
boost::chrono::high_resolution_clock::time_point startTime = boost::chrono::high_resolution_clock::now();
Plane(Viewport *viewport = 0);
~Plane();
@ -46,6 +51,7 @@ public:
DECL_ATTR( BlendType, int )
DECL_ATTR( Color, Color& )
DECL_ATTR( Tone, Tone& )
DECL_ATTR( Shader, int )
void initDynAttribs();
@ -54,6 +60,7 @@ private:
void draw();
void onGeometryChange(const Scene::Geometry &);
void defaultSpriteShaderInit(SpriteShaderBase &);
void releaseResources();
const char *klassName() const { return "plane"; }

View file

@ -31,6 +31,7 @@
#include "common.h.xxd"
#include "sprite.frag.xxd"
#include "worldMachine.frag.xxd"
#include "water.frag.xxd"
#include "hue.frag.xxd"
#include "trans.frag.xxd"
#include "transSimple.frag.xxd"
@ -47,7 +48,6 @@
#include "simple.vert.xxd"
#include "simpleColor.vert.xxd"
#include "sprite.vert.xxd"
#include "worldMachine.vert.xxd"
#include "tilemap.vert.xxd"
#include "blur.frag.xxd"
#include "simpleMatrix.vert.xxd"
@ -378,9 +378,7 @@ void SimpleTransShader::setProg(float value){
}
SpriteShader::SpriteShader(){
INIT_SHADER(sprite, sprite, SpriteShader);
void SpriteShaderBase::SpriteShaderInit(){
ShaderBase::init();
GET_U(spriteMat);
@ -392,38 +390,50 @@ SpriteShader::SpriteShader(){
GET_U(bushOpacity);
}
void SpriteShader::setSpriteMat(const float value[16]){
void SpriteShaderBase::setSpriteMat(const float value[16]){
gl.UniformMatrix4fv(u_spriteMat, 1, GL_FALSE, value);
}
void SpriteShader::setTone(const Vec4 &tone){
void SpriteShaderBase::setTone(const Vec4 &tone){
setVec4Uniform(u_tone, tone);
}
void SpriteShader::setColor(const Vec4 &color){
void SpriteShaderBase::setColor(const Vec4 &color){
setVec4Uniform(u_color, color);
}
void SpriteShader::setModulate(const Vec4 &color){
void SpriteShaderBase::setModulate(const Vec4 &color){
setVec4Uniform(u_modulate, color);
}
void SpriteShader::setOpacity(float value){
void SpriteShaderBase::setOpacity(float value){
gl.Uniform1f(u_opacity, value);
}
void SpriteShader::setBushDepth(float value){
void SpriteShaderBase::setBushDepth(float value){
gl.Uniform1f(u_bushDepth, value);
}
void SpriteShader::setBushOpacity(float value){
void SpriteShaderBase::setBushOpacity(float value){
gl.Uniform1f(u_bushOpacity, value);
}
SpriteShader::SpriteShader(){
INIT_SHADER(sprite, sprite, SpriteShader);
SpriteShaderBase::SpriteShaderInit();
}
WMShader::WMShader(){
INIT_SHADER(worldMachine, worldMachine, WMShader);
SpriteShader::init();
INIT_SHADER(sprite, worldMachine, WMShader);
SpriteShaderBase::SpriteShaderInit();
}
WaterShader::WaterShader(){
INIT_SHADER(simple, water, WaterShader);
SpriteShaderBase::SpriteShaderInit();
}

View file

@ -160,9 +160,9 @@ private:
GLint u_currentScene, u_frozenScene, u_prog;
};
class SpriteShader : public ShaderBase{
class SpriteShaderBase : public ShaderBase{
public:
SpriteShader();
void SpriteShaderInit();
void setSpriteMat(const float value[16]);
void setTone(const Vec4 &value);
@ -176,11 +176,21 @@ private:
GLint u_spriteMat, u_tone, u_opacity, u_color, u_modulate, u_bushDepth, u_bushOpacity;
};
class WMShader : public SpriteShader{
class SpriteShader : public SpriteShaderBase{
public:
SpriteShader();
};
class WMShader : public SpriteShaderBase{
public:
WMShader();
};
class WaterShader : public SpriteShaderBase{
public:
WaterShader();
};
class PlaneShader : public ShaderBase{
public:
PlaneShader();
@ -308,6 +318,7 @@ private:
X(alphaSprite, AlphaSpriteShader, AlphaSprite) \
X(sprite, SpriteShader, Sprite) \
X(worldMachine, WMShader, WorldMachine) \
X(water, WaterShader, Water) \
X(plane, PlaneShader, Plane) \
X(gray, GrayShader, Gray) \
X(tilemap, TilemapShader, TileMap) \

View file

@ -505,7 +505,7 @@ void Sprite::draw(){
flashing ||
p->bushDepth != 0;
if (p->obscured){
if (p->obscured || p->shader == ShaderType::SHADER_obscured){
ObscuredShader &shader = shState->shaders().obscured;
shader.bind();
shader.applyViewportProj();
@ -513,27 +513,37 @@ void Sprite::draw(){
base = &shader;
}
else{
switch (p->shader){
switch (p->shader)
{
case ShaderType::SHADER_plane:
{
PlaneShader &shader = shState->shaders().plane;
shader.bind();
shader.applyViewportProj();
shader.setTone(p->tone->norm);
shader.setColor(p->color->norm);
shader.setFlash(Vec4());
shader.setOpacity(p->opacity.norm);
base = &shader;
break;
}
case ShaderType::SHADER_water:
{
WaterShader &shader = shState->shaders().water;
defaultSpriteShaderInit(shader);
base = &shader;
break;
}
case ShaderType::SHADER_worldMachine:
{
WMShader &shader = shState->shaders().worldMachine;
shader.bind();
shader.applyViewportProj();
shader.setSpriteMat(p->trans.getMatrix());
shader.setTone(p->tone->norm);
shader.setOpacity(p->opacity.norm);
shader.setBushDepth(p->efBushDepth);
shader.setBushOpacity(p->bushOpacity.norm);
/* When both flashing and effective color are set,
* the one with higher alpha will be blended */
const Vec4 *blend = (flashing && flashColor.w > p->color->norm.w) ?
&flashColor : &p->color->norm;
shader.setColor(*blend);
shader.setModulate(p->modulate->norm);
defaultSpriteShaderInit(shader);
base = &shader;
@ -544,22 +554,7 @@ void Sprite::draw(){
if (renderEffect){
SpriteShader &shader = shState->shaders().sprite;
shader.bind();
shader.applyViewportProj();
shader.setSpriteMat(p->trans.getMatrix());
shader.setTone(p->tone->norm);
shader.setOpacity(p->opacity.norm);
shader.setBushDepth(p->efBushDepth);
shader.setBushOpacity(p->bushOpacity.norm);
/* When both flashing and effective color are set,
* the one with higher alpha will be blended */
const Vec4 *blend = (flashing && flashColor.w > p->color->norm.w) ?
&flashColor : &p->color->norm;
shader.setColor(*blend);
shader.setModulate(p->modulate->norm);
defaultSpriteShaderInit(shader);
base = &shader;
}
@ -615,3 +610,22 @@ void Sprite::releaseResources(){
delete p;
}
void Sprite::defaultSpriteShaderInit(SpriteShaderBase &shader){
shader.bind();
shader.applyViewportProj();
shader.setSpriteMat(p->trans.getMatrix());
shader.setTone(p->tone->norm);
shader.setOpacity(p->opacity.norm);
shader.setBushDepth(p->efBushDepth);
shader.setBushOpacity(p->bushOpacity.norm);
/* When both flashing and effective color are set,
* the one with higher alpha will be blended */
const Vec4 *blend = (flashing && flashColor.w > p->color->norm.w) ?
&flashColor : &p->color->norm;
shader.setColor(*blend);
shader.setModulate(p->modulate->norm);
}

View file

@ -73,7 +73,6 @@ public:
DECL_ATTR( WavePhase, float )
DECL_ATTR( Obscured, bool )
DECL_ATTR( Shader, int )
DECL_ATTR( startTime, boost::chrono::high_resolution_clock::time_point)
void initDynAttribs();
@ -82,6 +81,7 @@ private:
void draw();
void onGeometryChange(const Scene::Geometry &);
void defaultSpriteShaderInit(SpriteShaderBase &);
void releaseResources();
const char *klassName() const { return "sprite"; }