From 080af86e1b2eb388276fdff8e766d689eb214651 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 10:31:49 -0600 Subject: [PATCH] feat: shaders --- .../TankArmor/components/Spaced.tsx | 6 +- .../Armor/components/SpacedArmor.tsx | 49 ------------- .../Armor/components/SpacedArmor/index.tsx | 71 +++++++++++++++++++ .../materials/externalModule/fragment.glsl | 6 ++ .../materials/externalModule/index.ts | 19 +++++ .../materials/externalModule/vertex.glsl | 4 ++ .../materials/spaced/fragment.glsl | 6 ++ .../SpacedArmor/materials/spaced/index.ts | 19 +++++ .../SpacedArmor/materials/spaced/vertex.glsl | 11 +++ 9 files changed, 139 insertions(+), 52 deletions(-) delete mode 100644 src/components/Armor/components/SpacedArmor.tsx create mode 100644 src/components/Armor/components/SpacedArmor/index.tsx create mode 100644 src/components/Armor/components/SpacedArmor/materials/externalModule/fragment.glsl create mode 100644 src/components/Armor/components/SpacedArmor/materials/externalModule/index.ts create mode 100644 src/components/Armor/components/SpacedArmor/materials/externalModule/vertex.glsl create mode 100644 src/components/Armor/components/SpacedArmor/materials/spaced/fragment.glsl create mode 100644 src/components/Armor/components/SpacedArmor/materials/spaced/index.ts create mode 100644 src/components/Armor/components/SpacedArmor/materials/spaced/vertex.glsl diff --git a/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/Spaced.tsx b/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/Spaced.tsx index 1f768debe..3db354953 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/Spaced.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/Spaced.tsx @@ -268,9 +268,9 @@ export const SpacedArmorScene = memo( {modelNodes.map((node) => { - const isCurrentGun = node.name.startsWith( - `gun_${gunModelDefinition.model.toString().padStart(2, '0')}`, - ); + const isCurrentGun = + node.name === + `gun_${gunModelDefinition.model.toString().padStart(2, '0')}`; const isVisible = isCurrentGun; if (!isVisible) return null; diff --git a/src/components/Armor/components/SpacedArmor.tsx b/src/components/Armor/components/SpacedArmor.tsx deleted file mode 100644 index afc2745b4..000000000 --- a/src/components/Armor/components/SpacedArmor.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import { AdditiveBlending, Color, MeshBasicMaterial, Object3D } from 'three'; -import { ArmorType } from '../../../app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/Spaced'; -import { resolveNearPenetration } from '../../../core/blitz/resolveNearPenetration'; -import { jsxTree } from '../../../core/blitzkrieg/jsxTree'; -import { useDuel } from '../../../stores/duel'; - -interface SpacedArmorProps { - node: Object3D; - ornamental?: boolean; - type: ArmorType; - thickness: number; -} - -const omitColor = new Color(0, 0, 0); - -export function SpacedArmor({ node, type, thickness }: SpacedArmorProps) { - const penetrationRaw = useDuel( - (state) => state.antagonist!.shell.penetration, - ); - const penetration = resolveNearPenetration(penetrationRaw); - - return ( - <> - {type === ArmorType.External && - jsxTree(node, { - renderOrder: 0, - - material: new MeshBasicMaterial({ - colorWrite: false, - }), - })} - - {jsxTree(node, { - renderOrder: 1, - - material: new MeshBasicMaterial({ - color: - type === ArmorType.Core - ? omitColor - : type === ArmorType.Spaced - ? new Color(0, 0, 0) - : new Color(thickness / penetration, 0, 0), - depthWrite: type === ArmorType.Core, - blending: type === ArmorType.Core ? undefined : AdditiveBlending, - }), - })} - - ); -} diff --git a/src/components/Armor/components/SpacedArmor/index.tsx b/src/components/Armor/components/SpacedArmor/index.tsx new file mode 100644 index 000000000..228df8f10 --- /dev/null +++ b/src/components/Armor/components/SpacedArmor/index.tsx @@ -0,0 +1,71 @@ +import { MeshBasicMaterial, Object3D } from 'three'; +import { ArmorType } from '../../../../app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/Spaced'; +import { resolveNearPenetration } from '../../../../core/blitz/resolveNearPenetration'; +import { jsxTree } from '../../../../core/blitzkrieg/jsxTree'; +import { useDuel } from '../../../../stores/duel'; +import { externalModuleMaterial } from './materials/externalModule'; +import { spacedMaterial } from './materials/spaced'; +// import fragmentShader from './shaders/fragment.glsl'; +// import vertexShader from './shaders/vertex.glsl'; + +interface SpacedArmorProps { + node: Object3D; + ornamental?: boolean; + type: ArmorType; + thickness: number; +} + +const omitMaterial = new MeshBasicMaterial({ + colorWrite: false, + depthWrite: true, +}); + +export function SpacedArmor({ node, type, thickness }: SpacedArmorProps) { + const penetrationRaw = useDuel( + (state) => state.antagonist!.shell.penetration, + ); + const penetration = resolveNearPenetration(penetrationRaw); + + /** + * Render orders allocations: + * - 0 : core omission + * - 1-2: spaced without depth buffer write but do test to allow additive blending + * - 3-4: external with depth buffer write in first pass and read in second to simplify geometry + */ + + return ( + <> + {type === ArmorType.Core && + jsxTree(node, { + renderOrder: 0, + material: omitMaterial, + })} + + {type === ArmorType.Spaced && ( + <> + {jsxTree(node, { + renderOrder: 2, + material: spacedMaterial(thickness, penetration), + })} + + )} + + {type === ArmorType.External && ( + <> + {jsxTree(node, { + renderOrder: 4, + material: externalModuleMaterial(thickness, penetration), + })} + {jsxTree(node, { + renderOrder: 3, + material: new MeshBasicMaterial({ + colorWrite: false, + depthTest: true, + depthWrite: true, + }), + })} + + )} + + ); +} diff --git a/src/components/Armor/components/SpacedArmor/materials/externalModule/fragment.glsl b/src/components/Armor/components/SpacedArmor/materials/externalModule/fragment.glsl new file mode 100644 index 000000000..0ab70c10d --- /dev/null +++ b/src/components/Armor/components/SpacedArmor/materials/externalModule/fragment.glsl @@ -0,0 +1,6 @@ +uniform float thickness; +uniform float penetration; + +void main() { + gl_FragColor = vec4(thickness / penetration, 0.0, 0.0, 1.0); +} \ No newline at end of file diff --git a/src/components/Armor/components/SpacedArmor/materials/externalModule/index.ts b/src/components/Armor/components/SpacedArmor/materials/externalModule/index.ts new file mode 100644 index 000000000..df5683ddc --- /dev/null +++ b/src/components/Armor/components/SpacedArmor/materials/externalModule/index.ts @@ -0,0 +1,19 @@ +import { AdditiveBlending, ShaderMaterial } from 'three'; +import fragmentShader from './fragment.glsl'; +import vertexShader from './vertex.glsl'; + +export function externalModuleMaterial(thickness: number, penetration: number) { + return new ShaderMaterial({ + fragmentShader, + vertexShader, + + depthTest: true, + depthWrite: false, + blending: AdditiveBlending, + + uniforms: { + thickness: { value: thickness }, + penetration: { value: penetration }, + }, + }); +} diff --git a/src/components/Armor/components/SpacedArmor/materials/externalModule/vertex.glsl b/src/components/Armor/components/SpacedArmor/materials/externalModule/vertex.glsl new file mode 100644 index 000000000..5f9df37ef --- /dev/null +++ b/src/components/Armor/components/SpacedArmor/materials/externalModule/vertex.glsl @@ -0,0 +1,4 @@ +void main() { + vec4 vViewPosition4 = modelViewMatrix * vec4(position, 1.0); + gl_Position = projectionMatrix * vViewPosition4; +} \ No newline at end of file diff --git a/src/components/Armor/components/SpacedArmor/materials/spaced/fragment.glsl b/src/components/Armor/components/SpacedArmor/materials/spaced/fragment.glsl new file mode 100644 index 000000000..0ab70c10d --- /dev/null +++ b/src/components/Armor/components/SpacedArmor/materials/spaced/fragment.glsl @@ -0,0 +1,6 @@ +uniform float thickness; +uniform float penetration; + +void main() { + gl_FragColor = vec4(thickness / penetration, 0.0, 0.0, 1.0); +} \ No newline at end of file diff --git a/src/components/Armor/components/SpacedArmor/materials/spaced/index.ts b/src/components/Armor/components/SpacedArmor/materials/spaced/index.ts new file mode 100644 index 000000000..1e0fb7f4d --- /dev/null +++ b/src/components/Armor/components/SpacedArmor/materials/spaced/index.ts @@ -0,0 +1,19 @@ +import { AdditiveBlending, ShaderMaterial } from 'three'; +import fragmentShader from './fragment.glsl'; +import vertexShader from './vertex.glsl'; + +export function spacedMaterial(thickness: number, penetration: number) { + return new ShaderMaterial({ + fragmentShader, + vertexShader, + + depthTest: true, + depthWrite: false, + blending: AdditiveBlending, + + uniforms: { + thickness: { value: thickness }, + penetration: { value: penetration }, + }, + }); +} diff --git a/src/components/Armor/components/SpacedArmor/materials/spaced/vertex.glsl b/src/components/Armor/components/SpacedArmor/materials/spaced/vertex.glsl new file mode 100644 index 000000000..82f94e255 --- /dev/null +++ b/src/components/Armor/components/SpacedArmor/materials/spaced/vertex.glsl @@ -0,0 +1,11 @@ +varying vec3 vNormal; +varying vec3 vViewPosition; + +void main() { + vec4 vViewPosition4 = modelViewMatrix * vec4(position, 1.0); + + vViewPosition = vViewPosition4.xyz; + vNormal = normalMatrix * normal; + + gl_Position = projectionMatrix * vViewPosition4; +} \ No newline at end of file