Add day/night cycle

This commit is contained in:
Flashfyre committed 2023-12-29 21:04:40 -05:00
1 parent b04c7c8c3b
commit 5ef6f2da88
13 files changed
+392 -111

No files matched your search

+149
View File
@@ -0,0 +1,149 @@
import BattleScene from "../battle-scene";
import * as Utils from "../utils";
const spriteFragShader = `
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
uniform sampler2D uMainSampler[%count%];
varying vec2 outTexCoord;
varying float outTexId;
varying float outTintEffect;
varying vec4 outTint;
uniform float time;
uniform int isOutside;
uniform vec3 dayTint;
uniform vec3 duskTint;
uniform vec3 nightTint;
float blendOverlay(float base, float blend) {
return base<0.5?(2.0*base*blend):(1.0-2.0*(1.0-base)*(1.0-blend));
}
vec3 blendOverlay(vec3 base, vec3 blend) {
return vec3(blendOverlay(base.r,blend.r),blendOverlay(base.g,blend.g),blendOverlay(base.b,blend.b));
}
vec3 blendHardLight(vec3 base, vec3 blend) {
return blendOverlay(blend, base);
}
void main()
{
vec4 texture;
%forloop%
vec4 texel = vec4(outTint.bgr * outTint.a, outTint.a);
// Multiply texture tint
vec4 color = texture * texel;
if (outTintEffect == 1.0) {
// Solid color + texture alpha
color.rgb = mix(texture.rgb, outTint.bgr * outTint.a, texture.a);
} else if (outTintEffect == 2.0) {
// Solid color, no texture
color = texel;
}
/* Apply day/night tint */
if (color.a > 0.0) {
vec3 dayNightTint;
if (time < 0.25) {
dayNightTint = dayTint;
} else if (isOutside == 0 && time < 0.5) {
dayNightTint = mix(dayTint, nightTint, (time - 0.25) / 0.25);
} else if (time < 0.375) {
dayNightTint = mix(dayTint, duskTint, (time - 0.25) / 0.125);
} else if (time < 0.5) {
dayNightTint = mix(duskTint, nightTint, (time - 0.375) / 0.125);
} else if (time < 0.75) {
dayNightTint = nightTint;
} else if (isOutside == 0) {
dayNightTint = mix(nightTint, dayTint, (time - 0.75) / 0.25);
} else if (time < 0.875) {
dayNightTint = mix(nightTint, duskTint, (time - 0.75) / 0.125);
} else {
dayNightTint = mix(duskTint, dayTint, (time - 0.875) / 0.125);
}
color = vec4(blendHardLight(color.rgb, dayNightTint), color.a);
}
gl_FragColor = color;
}
`;
const spriteVertShader = `
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
uniform mat4 uProjectionMatrix;
attribute vec2 inPosition;
attribute vec2 inTexCoord;
attribute float inTexId;
attribute float inTintEffect;
attribute vec4 inTint;
varying vec2 outTexCoord;
varying float outTexId;
varying float outTintEffect;
varying vec4 outTint;
void main()
{
gl_Position = uProjectionMatrix * vec4(inPosition, 1.0, 1.0);
outTexCoord = inTexCoord;
outTexId = inTexId;
outTint = inTint;
outTintEffect = inTintEffect;
}
`;
export default class FieldSpritePipeline extends Phaser.Renderer.WebGL.Pipelines.MultiPipeline {
constructor(game: Phaser.Game, config?: Phaser.Types.Renderer.WebGL.WebGLPipelineConfig) {
super(config || {
game: game,
name: 'field-sprite',
fragShader: spriteFragShader,
vertShader: spriteVertShader
});
}
onPreRender(): void {
this.set1f('time', 0);
}
onBind(gameObject: Phaser.GameObjects.GameObject): void {
super.onBind();
const sprite = (gameObject as Phaser.GameObjects.Sprite);
const scene = sprite.scene as BattleScene;
let time = scene.currentBattle?.waveIndex
? ((scene.currentBattle.waveIndex + scene.getWaveCycleOffset()) % 40) / 40 // ((new Date().getSeconds() * 1000 + new Date().getMilliseconds()) % 10000) / 10000
: Utils.getCurrentTime();
this.set1f('time', time);
this.set1i('isOutside', scene.arena.isOutside() ? 1 : 0);
this.set3fv('dayTint', scene.arena.getDayTint().map(c => c / 255));
this.set3fv('duskTint', scene.arena.getDuskTint().map(c => c / 255));
this.set3fv('nightTint', scene.arena.getNightTint().map(c => c / 255));
}
onBatch(gameObject: Phaser.GameObjects.GameObject): void {
if (gameObject)
this.flush();
}
}
+48 -8
View File
@@ -1,5 +1,6 @@
import Pokemon from "../pokemon";
import Trainer from "../trainer";
import FieldSpritePipeline from "./field-sprite";
const spriteFragShader = `
#ifdef GL_FRAGMENT_PRECISION_HIGH
@@ -16,6 +17,11 @@ varying vec2 outPosition;
varying float outTintEffect;
varying vec4 outTint;
uniform float time;
uniform int isOutside;
uniform vec3 dayTint;
uniform vec3 duskTint;
uniform vec3 nightTint;
uniform int hasShadow;
uniform int yCenter;
uniform float vCutoff;
@@ -28,6 +34,18 @@ uniform ivec4 fusionSpriteColors[32];
const vec3 lumaF = vec3(.299, .587, .114);
float blendOverlay(float base, float blend) {
return base<0.5?(2.0*base*blend):(1.0-2.0*(1.0-base)*(1.0-blend));
}
vec3 blendOverlay(vec3 base, vec3 blend) {
return vec3(blendOverlay(base.r,blend.r),blendOverlay(base.g,blend.g),blendOverlay(base.b,blend.b));
}
vec3 blendHardLight(vec3 base, vec3 blend) {
return blendOverlay(blend, base);
}
void main()
{
vec4 texture;
@@ -68,6 +86,31 @@ void main()
/* Apply tone */
color.rgb += tone.rgb * (color.a / 255.0);
/* Apply day/night tint */
if (color.a > 0.0) {
vec3 dayNightTint;
if (time < 0.25) {
dayNightTint = dayTint;
} else if (isOutside == 0 && time < 0.5) {
dayNightTint = mix(dayTint, nightTint, (time - 0.25) / 0.25);
} else if (time < 0.375) {
dayNightTint = mix(dayTint, duskTint, (time - 0.25) / 0.125);
} else if (time < 0.5) {
dayNightTint = mix(duskTint, nightTint, (time - 0.375) / 0.125);
} else if (time < 0.75) {
dayNightTint = nightTint;
} else if (isOutside == 0) {
dayNightTint = mix(nightTint, dayTint, (time - 0.75) / 0.25);
} else if (time < 0.875) {
dayNightTint = mix(nightTint, duskTint, (time - 0.75) / 0.125);
} else {
dayNightTint = mix(duskTint, dayTint, (time - 0.875) / 0.125);
}
color = vec4(blendHardLight(color.rgb, dayNightTint), color.a);
}
if (hasShadow == 1) {
float width = size.x - (yOffset / 2.0);
@@ -131,11 +174,11 @@ void main()
}
`;
export default class SpritePipeline extends Phaser.Renderer.WebGL.Pipelines.MultiPipeline {
export default class SpritePipeline extends FieldSpritePipeline {
private _tone: number[];
constructor(game: Phaser.Game) {
super({
super(game, {
game: game,
name: 'sprite',
fragShader: spriteFragShader,
@@ -146,6 +189,8 @@ export default class SpritePipeline extends Phaser.Renderer.WebGL.Pipelines.Mult
}
onPreRender(): void {
super.onPreRender();
this.set1i('hasShadow', 0);
this.set1i('yCenter', 0);
this.set2f('relPosition', 0, 0);
@@ -155,7 +200,7 @@ export default class SpritePipeline extends Phaser.Renderer.WebGL.Pipelines.Mult
}
onBind(gameObject: Phaser.GameObjects.GameObject): void {
super.onBind();
super.onBind(gameObject);
const sprite = (gameObject as Phaser.GameObjects.Sprite);
@@ -188,11 +233,6 @@ export default class SpritePipeline extends Phaser.Renderer.WebGL.Pipelines.Mult
this.set4iv(`fusionSpriteColors`, flatFusionSpriteColors.flat());
}
onBatch(gameObject: Phaser.GameObjects.GameObject): void {
if (gameObject)
this.flush();
}
batchQuad(gameObject: Phaser.GameObjects.GameObject, x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number,
u0: number, v0: number, u1: number, v1: number, tintTL: number, tintTR: number, tintBL: number, tintBR: number, tintEffect: number | boolean,
texture?: WebGLTexture, unit?: number): boolean {