diff --git a/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx b/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx index b0a77603f..58b958fe8 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx @@ -16,6 +16,9 @@ interface OptionsProps { export function Options({ isFullScreen, canvas }: OptionsProps) { const showGrid = useTankopedia((state) => state.model.visual.showGrid); + const greenPenetration = useTankopedia( + (state) => state.model.visual.greenPenetration, + ); return ( Show grid + + { + mutateTankopedia((draft) => { + draft.model.visual.greenPenetration = checked; + }); + }} + > + Greene penetration + diff --git a/src/components/ArmorMesh/components/Armor/index.tsx b/src/components/ArmorMesh/components/Armor/index.tsx index f3c702784..d5b296a2b 100644 --- a/src/components/ArmorMesh/components/Armor/index.tsx +++ b/src/components/ArmorMesh/components/Armor/index.tsx @@ -7,6 +7,7 @@ import { Duel } from '../../../../app/tools/tankopedia/[id]/page'; import { canSplash } from '../../../../core/blitz/canSplash'; import { isExplosive } from '../../../../core/blitz/isExplosive'; import { resolveNearPenetration } from '../../../../core/blitz/resolveNearPenetration'; +import { useTankopedia } from '../../../../stores/tankopedia'; import { externalModuleMaskRenderTarget } from '../ExternalModuleMask'; import { spacedArmorDepthRenderTarget } from '../SpacedArmorDepth'; import fragmentShader from './shaders/fragment.glsl'; @@ -28,6 +29,9 @@ export function ArmorMesh({ duel, ...props }: ArmorMeshProps) { + const greenPenetration = useTankopedia( + (state) => state.model.visual.greenPenetration, + ); const camera = useThree((state) => state.camera); const { shell } = duel.antagonist; const material = useRef(null); @@ -73,6 +77,7 @@ export function ArmorMesh({ projectionMatrixInverse: { value: null }, zNear: { value: camera.near }, zFar: { value: camera.far }, + greenPenetration: { value: greenPenetration }, maxExternalModuleThickness: { value: maxExternalModuleThickness }, maxSpacedArmorThickness: { value: maxSpacedArmorThickness }, isExplosive: { value: isExplosive(shell.type) }, diff --git a/src/components/ArmorMesh/components/Armor/shaders/fragment.glsl b/src/components/ArmorMesh/components/Armor/shaders/fragment.glsl index 1e37a1be2..cfa1111dc 100644 --- a/src/components/ArmorMesh/components/Armor/shaders/fragment.glsl +++ b/src/components/ArmorMesh/components/Armor/shaders/fragment.glsl @@ -14,6 +14,7 @@ uniform vec2 resolution; varying mat4 vProjectionMatrix; uniform float maxExternalModuleThickness; uniform float maxSpacedArmorThickness; +uniform bool greenPenetration; float depthToDistance(float depth) { mat4 projectionMatrixInverse = inverse(vProjectionMatrix); @@ -101,5 +102,10 @@ void main() { } } - csm_FragColor = vec4(1.0, splashChance * 0.392, 0.0, (1.0 - penetrationChance) * 0.5); + vec3 color = vec3(1.0, splashChance * 0.392, 0.0); + if (greenPenetration) { + csm_FragColor = vec4(mix(color, vec3(0.0, 1.0, 0.0), penetrationChance), 0.5); + } else { + csm_FragColor = vec4(color, (1.0 - penetrationChance) * 0.5); + } } \ No newline at end of file diff --git a/src/stores/tankopedia.ts b/src/stores/tankopedia.ts index 4d8603f42..ce3bbcbca 100644 --- a/src/stores/tankopedia.ts +++ b/src/stores/tankopedia.ts @@ -40,6 +40,7 @@ interface Tankopedia { visual: { controlsEnabled: boolean; showGrid: boolean; + greenPenetration: boolean; }; }; mode: TankopediaMode; @@ -66,6 +67,7 @@ export const useTankopedia = create()( visual: { controlsEnabled: true, showGrid: true, + greenPenetration: false, }, }, areTanksAssigned: false,