From 4b1fda9680d44fed49dee43237bf292201c41d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Tue, 27 Feb 2024 17:36:05 -0600 Subject: [PATCH] feat: green penetration --- .../Armor/components/CoreArmor/index.tsx | 25 ++++++++++++++++--- .../CoreArmor/shaders/fragment.glsl | 12 ++++++--- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/components/Armor/components/CoreArmor/index.tsx b/src/components/Armor/components/CoreArmor/index.tsx index ee967dbd1..e13543fa4 100644 --- a/src/components/Armor/components/CoreArmor/index.tsx +++ b/src/components/Armor/components/CoreArmor/index.tsx @@ -14,6 +14,7 @@ import { resolveNearPenetration } from '../../../../core/blitz/resolveNearPenetr import { jsxTree } from '../../../../core/blitzkrieg/jsxTree'; import { ShellDefinition } from '../../../../core/blitzkrieg/tankDefinitions'; import { useDuel } from '../../../../stores/duel'; +import { useTankopediaPersistent } from '../../../../stores/tankopedia'; import fragmentShader from './shaders/fragment.glsl'; import vertexShader from './shaders/vertex.glsl'; @@ -45,6 +46,7 @@ export function CoreArmor({ node, thickness }: CoreArmorProps) { canSplash: { value: null }, damage: { value: null }, explosionRadius: { value: null }, + greenPenetration: { value: null }, resolution: { value: new Vector2() }, spacedArmorBuffer: { value: null }, @@ -53,7 +55,7 @@ export function CoreArmor({ node, thickness }: CoreArmorProps) { }); useEffect(() => { - function handleChange(shell: ShellDefinition) { + function handleShellChange(shell: ShellDefinition) { material.uniforms.penetration.value = resolveNearPenetration( shell.penetration, ); @@ -67,9 +69,26 @@ export function CoreArmor({ node, thickness }: CoreArmorProps) { material.uniforms.damage.value = shell.damage.armor; material.uniforms.explosionRadius.value = shell.explosionRadius; } + function handleGreenPenetrationChange(greenPenetration: boolean) { + material.uniforms.greenPenetration.value = greenPenetration; + } - handleChange(useDuel.getState().antagonist!.shell); - return useDuel.subscribe((state) => state.antagonist!.shell, handleChange); + handleShellChange(useDuel.getState().antagonist!.shell); + handleGreenPenetrationChange( + useTankopediaPersistent.getState().model.visual.greenPenetration, + ); + + const unsubscribes = [ + useDuel.subscribe((state) => state.antagonist!.shell, handleShellChange), + useTankopediaPersistent.subscribe( + (state) => state.model.visual.greenPenetration, + handleGreenPenetrationChange, + ), + ]; + + return () => { + unsubscribes.forEach((unsubscribe) => unsubscribe()); + }; }, []); useFrame(({ gl }) => { diff --git a/src/components/Armor/components/CoreArmor/shaders/fragment.glsl b/src/components/Armor/components/CoreArmor/shaders/fragment.glsl index eb8b31213..4e45e1aa5 100644 --- a/src/components/Armor/components/CoreArmor/shaders/fragment.glsl +++ b/src/components/Armor/components/CoreArmor/shaders/fragment.glsl @@ -12,6 +12,7 @@ uniform bool isExplosive; uniform bool canSplash; uniform float damage; uniform float explosionRadius; +uniform bool greenPenetration; uniform highp sampler2D spacedArmorBuffer; uniform highp sampler2D spacedArmorDepth; @@ -73,8 +74,13 @@ void main() { } vec3 color = vec3(1.0, splashChance * 0.392, 0.0); - gl_FragColor = vec4(color, (1.0 - penetrationChance) * 0.5); + if (greenPenetration) { + // non-trigonometric red-green mixing: https://www.desmos.com/calculator/ceo1oq7l67 + float falling = -pow(penetrationChance, 2.0) + 1.0; + float gaining = -pow(penetrationChance - 1.0, 2.0) + 1.0; + gl_FragColor = vec4(falling * color + gaining * vec3(0.0, 1.0, 0.0), 0.5); + } else { + gl_FragColor = vec4(color, (1.0 - penetrationChance) * 0.5); + } - // non-trigonometric red-green mixing: https://www.desmos.com/calculator/ceo1oq7l67 - // gl_FragColor = vec4(-pow(penetrationChance, 2.0) + 1.0, -pow(penetrationChance - 1.0, 2.0) + 1.0, 0.0, 0.5); } \ No newline at end of file