mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-22 19:19:52 +02:00
feat: 3CR exception mask
This commit is contained in:
1 parent
66016dedf0
commit
80b161b9fc
9 files changed
+509
-171
No files matched your search
@@ -0,0 +1,96 @@
|
||||
import { MeshProps, useFrame } from '@react-three/fiber';
|
||||
import { useRef } from 'react';
|
||||
import { MeshStandardMaterial, ShaderMaterial, Vector2 } from 'three';
|
||||
import ThreeCustomShaderMaterial from 'three-custom-shader-material';
|
||||
import { degToRad } from 'three/src/math/MathUtils';
|
||||
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 { externalModuleMaskRenderTarget } from '../ExternalModuleMask';
|
||||
import fragmentShader from './shaders/fragment.glsl';
|
||||
import vertexShader from './shaders/vertex.glsl';
|
||||
|
||||
interface ArmorMeshProps extends MeshProps {
|
||||
duel: Duel;
|
||||
isSpaced: boolean;
|
||||
isExternalModule?: boolean;
|
||||
thickness: number;
|
||||
}
|
||||
|
||||
export function ArmorMesh({
|
||||
isSpaced,
|
||||
isExternalModule = false,
|
||||
thickness,
|
||||
duel,
|
||||
...props
|
||||
}: ArmorMeshProps) {
|
||||
const { shell } = duel.antagonist;
|
||||
const material = useRef<ShaderMaterial>(null);
|
||||
const resolution = new Vector2();
|
||||
|
||||
useFrame(({ gl }) => {
|
||||
if (material.current) {
|
||||
material.current.uniforms.externalModuleMask.value =
|
||||
externalModuleMaskRenderTarget.texture;
|
||||
material.current.uniforms.resolution.value = resolution.set(
|
||||
gl.domElement.width,
|
||||
gl.domElement.height,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<mesh {...props} renderOrder={0}>
|
||||
<meshBasicMaterial colorWrite={false} />
|
||||
</mesh>
|
||||
|
||||
<mesh {...props} renderOrder={1}>
|
||||
<ThreeCustomShaderMaterial
|
||||
ref={material}
|
||||
silent
|
||||
baseMaterial={MeshStandardMaterial}
|
||||
transparent
|
||||
depthWrite={false}
|
||||
fragmentShader={fragmentShader}
|
||||
vertexShader={vertexShader}
|
||||
uniforms={{
|
||||
externalModuleMask: { value: null },
|
||||
resolution: { value: null },
|
||||
isSpaced: { value: isSpaced },
|
||||
isExplosive: { value: isExplosive(shell.type) },
|
||||
canSplash: { value: canSplash(shell.type) },
|
||||
isExternalModule: { value: isExternalModule },
|
||||
thickness: { value: thickness },
|
||||
penetration: {
|
||||
value: resolveNearPenetration(shell.penetration),
|
||||
},
|
||||
caliber: { value: shell.caliber },
|
||||
ricochet: { value: degToRad(shell.ricochet ?? 90) },
|
||||
normalization: {
|
||||
value: degToRad(shell.normalization ?? 0),
|
||||
},
|
||||
}}
|
||||
/>
|
||||
{/* <shaderMaterial
|
||||
ref={material}
|
||||
depthFunc={EqualDepth}
|
||||
depthWrite={false}
|
||||
transparent
|
||||
args={[
|
||||
{
|
||||
vertexShader,
|
||||
fragmentShader,
|
||||
uniforms: {
|
||||
externalModuleMask: { value: null },
|
||||
resolution: { value: null },
|
||||
isSpaced: { value: isSpaced },
|
||||
},
|
||||
},
|
||||
]}
|
||||
/> */}
|
||||
</mesh>
|
||||
</>
|
||||
);
|
||||
}
|
||||
+5
-1
@@ -8,8 +8,12 @@ uniform float penetration;
|
||||
uniform float caliber;
|
||||
uniform float ricochet;
|
||||
uniform float normalization;
|
||||
uniform sampler2D externalModuleMask;
|
||||
uniform vec2 resolution;
|
||||
|
||||
void main() {
|
||||
vec4 externalModuleMaskColor = texture2D(externalModuleMask, gl_FragCoord.xy / resolution);
|
||||
bool isUnderExternalModule = externalModuleMaskColor.r == 1.0;
|
||||
vec3 normalizedNormal = normalize(vNormal);
|
||||
vec3 normalizedViewPosition = normalize(vCSMViewPosition);
|
||||
float dotProduct = dot(normalizedNormal, -normalizedViewPosition);
|
||||
@@ -19,7 +23,7 @@ void main() {
|
||||
float splashChance = -1.0;
|
||||
bool threeCalibersRule = caliber > 3.0 * thickness;
|
||||
|
||||
if (!isExternalModule && !isExplosive && !threeCalibersRule && angle >= ricochet) {
|
||||
if (!isUnderExternalModule && !isExternalModule && !isExplosive && !threeCalibersRule && angle >= ricochet) {
|
||||
penetrationChance = 0.0;
|
||||
splashChance = 0.0;
|
||||
} else {
|
||||
File renamed without changes.
@@ -0,0 +1,29 @@
|
||||
import { MeshProps } from '@react-three/fiber';
|
||||
import { WebGLRenderTarget } from 'three';
|
||||
|
||||
export const externalModuleMaskRenderTarget = new WebGLRenderTarget();
|
||||
|
||||
interface ArmorMeshExternalModuleMaskProps extends MeshProps {
|
||||
exclude?: boolean;
|
||||
}
|
||||
|
||||
export function ArmorMeshExternalModuleMask({
|
||||
exclude = false,
|
||||
...props
|
||||
}: ArmorMeshExternalModuleMaskProps) {
|
||||
return (
|
||||
<>
|
||||
{exclude && (
|
||||
<mesh {...props} renderOrder={0}>
|
||||
<meshBasicMaterial colorWrite={false} />
|
||||
</mesh>
|
||||
)}
|
||||
|
||||
{!exclude && (
|
||||
<mesh {...props} renderOrder={1}>
|
||||
<meshBasicMaterial color="#ff0000" depthWrite={false} />
|
||||
</mesh>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,63 +1,2 @@
|
||||
import { MeshProps } from '@react-three/fiber';
|
||||
import { MeshStandardMaterial } from 'three';
|
||||
import CustomShaderMaterial from 'three-custom-shader-material';
|
||||
import { degToRad } from 'three/src/math/MathUtils';
|
||||
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 fragmentShader from './shaders/fragment.glsl';
|
||||
import vertexShader from './shaders/vertex.glsl';
|
||||
|
||||
interface ArmorMeshProps extends MeshProps {
|
||||
duel: Duel;
|
||||
isSpaced: boolean;
|
||||
isExternalModule?: boolean;
|
||||
thickness: number;
|
||||
}
|
||||
|
||||
export function ArmorMesh({
|
||||
isSpaced,
|
||||
isExternalModule = false,
|
||||
thickness,
|
||||
duel,
|
||||
...props
|
||||
}: ArmorMeshProps) {
|
||||
const { shell } = duel.antagonist;
|
||||
|
||||
return (
|
||||
<>
|
||||
{!isSpaced && (
|
||||
<mesh {...props}>
|
||||
<meshBasicMaterial colorWrite={false} />
|
||||
</mesh>
|
||||
)}
|
||||
|
||||
<mesh {...props}>
|
||||
<CustomShaderMaterial
|
||||
silent
|
||||
baseMaterial={MeshStandardMaterial}
|
||||
transparent
|
||||
depthWrite={false}
|
||||
fragmentShader={fragmentShader}
|
||||
vertexShader={vertexShader}
|
||||
uniforms={{
|
||||
isExplosive: { value: isExplosive(shell.type) },
|
||||
canSplash: { value: canSplash(shell.type) },
|
||||
isSpaced: { value: isSpaced },
|
||||
isExternalModule: { value: isExternalModule },
|
||||
thickness: { value: thickness },
|
||||
penetration: {
|
||||
value: resolveNearPenetration(shell.penetration),
|
||||
},
|
||||
caliber: { value: shell.caliber },
|
||||
ricochet: { value: degToRad(shell.ricochet ?? 90) },
|
||||
normalization: {
|
||||
value: degToRad(shell.normalization ?? 0),
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</mesh>
|
||||
</>
|
||||
);
|
||||
}
|
||||
export * from './components/Armor';
|
||||
export * from './components/ExternalModuleMask';
|
||||
Reference in new issue
Block a user