mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-22 03:07:04 +02:00
feat: spaced armor thickness
This commit is contained in:
1 parent
a11975adec
commit
8f4ea5f2fd
9 files changed
+128
-25
No files matched your search
@@ -18,6 +18,7 @@ interface ArmorMeshProps extends MeshProps {
|
||||
isExternalModule?: boolean;
|
||||
thickness: number;
|
||||
maxExternalModuleThickness: number;
|
||||
maxSpacedArmorThickness: number;
|
||||
}
|
||||
|
||||
export function ArmorMesh({
|
||||
@@ -25,6 +26,7 @@ export function ArmorMesh({
|
||||
isExternalModule = false,
|
||||
thickness,
|
||||
maxExternalModuleThickness,
|
||||
maxSpacedArmorThickness,
|
||||
duel,
|
||||
...props
|
||||
}: ArmorMeshProps) {
|
||||
@@ -43,6 +45,8 @@ export function ArmorMesh({
|
||||
externalModuleMaskRenderTarget.texture;
|
||||
material.current.uniforms.spacedArmorDepth.value =
|
||||
spacedArmorDepthRenderTarget.depthTexture;
|
||||
material.current.uniforms.spacedArmorMask.value =
|
||||
spacedArmorDepthRenderTarget.texture;
|
||||
material.current.uniforms.projectionMatrixInverse.value =
|
||||
camera.projectionMatrixInverse;
|
||||
}
|
||||
@@ -69,10 +73,12 @@ export function ArmorMesh({
|
||||
resolution: { value: null },
|
||||
externalModuleMask: { value: null },
|
||||
spacedArmorDepth: { value: null },
|
||||
spacedArmorMask: { value: null },
|
||||
projectionMatrixInverse: { value: null },
|
||||
zNear: { value: camera.near },
|
||||
zFar: { value: camera.far },
|
||||
maxExternalModuleThickness: { value: maxExternalModuleThickness },
|
||||
maxSpacedArmorThickness: { value: maxSpacedArmorThickness },
|
||||
isSpaced: { value: isSpaced },
|
||||
isExplosive: { value: isExplosive(shell.type) },
|
||||
canSplash: { value: canSplash(shell.type) },
|
||||
|
||||
@@ -10,9 +10,11 @@ uniform float ricochet;
|
||||
uniform float normalization;
|
||||
uniform sampler2D externalModuleMask;
|
||||
uniform sampler2D spacedArmorDepth;
|
||||
uniform sampler2D spacedArmorMask;
|
||||
uniform vec2 resolution;
|
||||
varying mat4 vProjectionMatrix;
|
||||
uniform float maxExternalModuleThickness;
|
||||
uniform float maxSpacedArmorThickness;
|
||||
|
||||
float depthToDistance(float depth) {
|
||||
mat4 projectionMatrixInverse = inverse(vProjectionMatrix);
|
||||
@@ -26,12 +28,14 @@ float depthToDistance(float depth) {
|
||||
|
||||
void main() {
|
||||
vec2 screenCoordinates = gl_FragCoord.xy / resolution;
|
||||
float spacedArmorDepthValue = texture2D(spacedArmorDepth, screenCoordinates).r;
|
||||
float spacedArmorDepth = texture2D(spacedArmorDepth, screenCoordinates).r;
|
||||
float currentDistance = depthToDistance(gl_FragCoord.z);
|
||||
float spacedArmorDistance = depthToDistance(spacedArmorDepthValue);
|
||||
float spacedArmorDistance = depthToDistance(spacedArmorDepth);
|
||||
float distanceFromSpacedArmor = currentDistance - spacedArmorDistance;
|
||||
vec4 externalModuleMaskColor = texture2D(externalModuleMask, screenCoordinates);
|
||||
vec4 spacedArmorMaskColor = texture2D(spacedArmorMask, screenCoordinates);
|
||||
bool isUnderExternalModule = externalModuleMaskColor.r == 1.0;
|
||||
bool isUnderSpacedArmor = spacedArmorMaskColor.a == 1.0;
|
||||
vec3 normalizedNormal = normalize(vNormal);
|
||||
vec3 normalizedViewPosition = normalize(vCSMViewPosition);
|
||||
float dotProduct = dot(normalizedNormal, -normalizedViewPosition);
|
||||
@@ -53,6 +57,14 @@ void main() {
|
||||
piercedPenetration -= externalModuleThickness;
|
||||
}
|
||||
|
||||
if (isUnderSpacedArmor) {
|
||||
float spacedArmorAngle = spacedArmorMaskColor.r * PI;
|
||||
float normalizedSpacedArmorThickness = spacedArmorMaskColor.g;
|
||||
float spacedArmorNominalThickness = normalizedSpacedArmorThickness * maxSpacedArmorThickness;
|
||||
float spacedArmorThickness = spacedArmorNominalThickness / cos(spacedArmorAngle);
|
||||
piercedPenetration -= spacedArmorThickness;
|
||||
}
|
||||
|
||||
if (isExplosive) {
|
||||
// 50% loss of remaining penetration per meter
|
||||
piercedPenetration -= 0.5 * piercedPenetration * distanceFromSpacedArmor;
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import { MeshProps } from '@react-three/fiber';
|
||||
import { WebGLRenderTarget } from 'three';
|
||||
|
||||
export const spacedArmorDepthRenderTarget = new WebGLRenderTarget();
|
||||
|
||||
interface ArmorMeshSpacedArmorDepthProps extends MeshProps {
|
||||
exclude?: boolean;
|
||||
}
|
||||
|
||||
export function ArmorMeshSpacedArmorDepth({
|
||||
exclude = false,
|
||||
...props
|
||||
}: ArmorMeshSpacedArmorDepthProps) {
|
||||
return (
|
||||
<mesh {...props}>
|
||||
<meshBasicMaterial colorWrite={false} />
|
||||
</mesh>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { MeshProps } from '@react-three/fiber';
|
||||
import { MeshStandardMaterial, WebGLRenderTarget } from 'three';
|
||||
import ThreeCustomShaderMaterial from 'three-custom-shader-material';
|
||||
import fragmentShader from './shaders/fragment.glsl';
|
||||
import vertexShader from './shaders/vertex.glsl';
|
||||
|
||||
export const spacedArmorDepthRenderTarget = new WebGLRenderTarget();
|
||||
|
||||
type ArmorMeshSpacedArmorDepthProps = MeshProps &
|
||||
(
|
||||
| {
|
||||
include?: false;
|
||||
}
|
||||
| {
|
||||
include: true;
|
||||
thickness: number;
|
||||
maxThickness: number;
|
||||
}
|
||||
);
|
||||
|
||||
export function ArmorMeshSpacedArmorDepth(
|
||||
props: ArmorMeshSpacedArmorDepthProps,
|
||||
) {
|
||||
return (
|
||||
<mesh {...props}>
|
||||
{!props.include && <meshBasicMaterial colorWrite={false} />}
|
||||
{props.include && (
|
||||
<ThreeCustomShaderMaterial
|
||||
silent
|
||||
baseMaterial={MeshStandardMaterial}
|
||||
fragmentShader={fragmentShader}
|
||||
vertexShader={vertexShader}
|
||||
uniforms={{
|
||||
thickness: { value: props.thickness },
|
||||
maxThickness: { value: props.maxThickness },
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</mesh>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
varying vec3 vCSMViewPosition;
|
||||
uniform float thickness;
|
||||
uniform float maxThickness;
|
||||
|
||||
void main() {
|
||||
vec3 normalizedNormal = normalize(vNormal);
|
||||
vec3 normalizedViewPosition = normalize(vCSMViewPosition);
|
||||
float dotProduct = dot(normalizedNormal, -normalizedViewPosition);
|
||||
float angle = acos(dotProduct);
|
||||
|
||||
csm_FragColor = vec4(angle / PI, thickness / maxThickness, 0.0, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
varying vec3 vCSMViewPosition;
|
||||
|
||||
void main() {
|
||||
vec4 vViewPosition4 = modelViewMatrix * vec4(position, 1.0);
|
||||
vCSMViewPosition = vViewPosition4.xyz;
|
||||
}
|
||||
Reference in new issue
Block a user