cnq3/code/renderer/shaders/crp/vl_common.h.hlsli
myT afc81437c3 added NanoVDB support
- added the foundation for a GPU particle system
- reworked volumetric particle injection
2024-07-02 02:06:15 +02:00

262 lines
7.1 KiB
HLSL

/*
===========================================================================
Copyright (C) 2024 Gian 'myT' Schellenbaum
This file is part of Challenge Quake 3 (CNQ3).
Challenge Quake 3 is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Challenge Quake 3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Challenge Quake 3. If not, see <https://www.gnu.org/licenses/>.
===========================================================================
*/
// volumetric lighting: shared data structures and functions
#pragma once
#include "typedefs.h.hlsli"
#if !defined(__cplusplus)
#include "common.hlsli"
#include "simplex_noise.hlsli"
#endif
#if defined(__cplusplus)
#pragma pack(push, 1)
#endif
struct FogVolume
{
float3 scatter;
float absorption;
float3 emissive;
float anisotropy;
float3 boxMin;
float noiseMin;
float3 boxMax;
float noiseMax;
float noiseScale;
float noiseTimeScale;
uint isHeightFog;
#if !defined(__cplusplus)
bool IsPointInside(float3 position)
{
return IsInRange(position, boxMin, boxMax);
}
float DensityAt(float3 position, float time)
{
float4 positionTime = float4(position * noiseScale, time * noiseTimeScale);
float density = noiseMin + (noiseMax - noiseMin) * SimplexNoise4D(positionTime);
if(isHeightFog)
{
float maxHeight = boxMax.z - boxMin.z;
float height = position.z - boxMin.z;
density *= 1.0 - EaseOutCubic(height / maxHeight);
}
return density;
}
#endif
};
struct Tile
{
uint firstParticle;
uint particleCount;
uint particleIndex;
uint pad0;
};
struct Counters
{
uint particleCount;
uint tileCount;
};
#if defined(__cplusplus)
#pragma pack(pop)
#endif
#if !defined(__cplusplus)
// defines voxel sampling offsets for super-sampled fog/particle injection
#if defined(VOXEL_SUPERSAMPLING_1X)
static const int VoxelSampleCount = 1;
static const float3 VoxelSamples[1] =
{
float3(0, 0, 0)
};
#elif defined(VOXEL_SUPERSAMPLING_2X)
static const float Offset = 0.1666666666666666666666666666666;
static const int VoxelSampleCount = 9;
static const float3 VoxelSamples[9] =
{
float3(0, 0, 0),
float3(-Offset, -Offset, -Offset),
float3(-Offset, -Offset, +Offset),
float3(-Offset, +Offset, -Offset),
float3(-Offset, +Offset, +Offset),
float3(+Offset, -Offset, -Offset),
float3(+Offset, -Offset, +Offset),
float3(+Offset, +Offset, -Offset),
float3(+Offset, +Offset, +Offset)
};
#elif defined(VOXEL_SUPERSAMPLING_3X)
static const int VoxelSampleCount = 27;
static const float3 VoxelSamples[27] =
{
float3(-0.25, -0.25, -0.25),
float3(-0.25, -0.25, 0),
float3(-0.25, -0.25, 0.25),
float3(-0.25, 0, -0.25),
float3(-0.25, 0, 0),
float3(-0.25, 0, 0.25),
float3(-0.25, 0.25, -0.25),
float3(-0.25, 0.25, 0),
float3(-0.25, 0.25, 0.25),
float3(0, -0.25, -0.25),
float3(0, -0.25, 0),
float3(0, -0.25, 0.25),
float3(0, 0, -0.25),
float3(0, 0, 0),
float3(0, 0, 0.25),
float3(0, 0.25, -0.25),
float3(0, 0.25, 0),
float3(0, 0.25, 0.25),
float3(0.25, -0.25, -0.25),
float3(0.25, -0.25, 0),
float3(0.25, -0.25, 0.25),
float3(0.25, 0, -0.25),
float3(0.25, 0, 0),
float3(0.25, 0, 0.25),
float3(0.25, 0.25, -0.25),
float3(0.25, 0.25, 0),
float3(0.25, 0.25, 0.25)
};
#elif defined(VOXEL_SUPERSAMPLING_4X)
static const int VoxelSampleCount = 65;
static const float3 VoxelSamples[65] =
{
float3(0, 0, 0),
float3(-0.3, -0.3, -0.3),
float3(-0.3, -0.3, -0.1),
float3(-0.3, -0.3, 0.1),
float3(-0.3, -0.3, 0.3),
float3(-0.3, -0.1, -0.3),
float3(-0.3, -0.1, -0.1),
float3(-0.3, -0.1, 0.1),
float3(-0.3, -0.1, 0.3),
float3(-0.3, 0.1, -0.3),
float3(-0.3, 0.1, -0.1),
float3(-0.3, 0.1, 0.1),
float3(-0.3, 0.1, 0.3),
float3(-0.3, 0.3, -0.3),
float3(-0.3, 0.3, -0.1),
float3(-0.3, 0.3, 0.1),
float3(-0.3, 0.3, 0.3),
float3(-0.1, -0.3, -0.3),
float3(-0.1, -0.3, -0.1),
float3(-0.1, -0.3, 0.1),
float3(-0.1, -0.3, 0.3),
float3(-0.1, -0.1, -0.3),
float3(-0.1, -0.1, -0.1),
float3(-0.1, -0.1, 0.1),
float3(-0.1, -0.1, 0.3),
float3(-0.1, 0.1, -0.3),
float3(-0.1, 0.1, -0.1),
float3(-0.1, 0.1, 0.1),
float3(-0.1, 0.1, 0.3),
float3(-0.1, 0.3, -0.3),
float3(-0.1, 0.3, -0.1),
float3(-0.1, 0.3, 0.1),
float3(-0.1, 0.3, 0.3),
float3(0.1, -0.3, -0.3),
float3(0.1, -0.3, -0.1),
float3(0.1, -0.3, 0.1),
float3(0.1, -0.3, 0.3),
float3(0.1, -0.1, -0.3),
float3(0.1, -0.1, -0.1),
float3(0.1, -0.1, 0.1),
float3(0.1, -0.1, 0.3),
float3(0.1, 0.1, -0.3),
float3(0.1, 0.1, -0.1),
float3(0.1, 0.1, 0.1),
float3(0.1, 0.1, 0.3),
float3(0.1, 0.3, -0.3),
float3(0.1, 0.3, -0.1),
float3(0.1, 0.3, 0.1),
float3(0.1, 0.3, 0.3),
float3(0.3, -0.3, -0.3),
float3(0.3, -0.3, -0.1),
float3(0.3, -0.3, 0.1),
float3(0.3, -0.3, 0.3),
float3(0.3, -0.1, -0.3),
float3(0.3, -0.1, -0.1),
float3(0.3, -0.1, 0.1),
float3(0.3, -0.1, 0.3),
float3(0.3, 0.1, -0.3),
float3(0.3, 0.1, -0.1),
float3(0.3, 0.1, 0.1),
float3(0.3, 0.1, 0.3),
float3(0.3, 0.3, -0.3),
float3(0.3, 0.3, -0.1),
float3(0.3, 0.3, 0.1),
float3(0.3, 0.3, 0.3),
};
#endif
// defines sphere sampling offsets for super-sampled particle injection
#if defined(SPHERE_SUPERSAMPLING_1X)
static const int SphereSampleCount = 1;
static const float3 SphereSamples[1] =
{
float3(0, 0, 0)
};
#elif defined(SPHERE_SUPERSAMPLING_2X)
static const int SphereSampleCount = 13;
static const float3 SphereSamples[13] =
{
float3(-0.000070998815798, -0.000005560663499, -0.666666662862852),
float3(-0.184273763669020, -0.567104158597683, -0.298128324331843),
float3(0.482401099870031, -0.350493177757963, -0.298141167291191),
float3(-0.596343845795264, -0.000022877791848, -0.298024263279293),
float3(0.482326151451980, 0.350363917328204, -0.298414231403936),
float3(-0.184272548445118, 0.567103656272574, -0.298130030986924),
float3(0.000000000000000, 0.000000000000000, 0.000000000000000),
float3(0.184241177452589, -0.567097520996929, 0.298161088431179),
float3(-0.482404802195943, -0.350487719732367, 0.298141593172679),
float3(0.596236953290593, -0.000018337625111, 0.298238058669458),
float3(-0.482641375963473, 0.350268310738867, 0.298016538374417),
float3(0.184262272798761, 0.567101475888716, 0.298140529469443),
float3(-0.000135987657896, -0.000010037080285, 0.666666652721627)
};
#elif defined(SPHERE_SUPERSAMPLING_2X_OLD) // 8x with 0,0,0 added
static const int SphereSampleCount = 9;
static const float3 SphereSamples[9] =
{
float3(0, 0, 0),
float3(-0.378024926878978, -0.378024806866870, -0.317879684372474),
float3(0.378024762722181, -0.378024944670528, -0.317879715711806),
float3(-0.378024789075323, 0.378024882734286, -0.317879758027500),
float3(0.378024900525835, 0.378024744930628, -0.317879789366832),
float3(-0.000000084265328, -0.534607831462839, 0.317879788951622),
float3(-0.534607849254392, 0.000000128410024, 0.317879759029907),
float3(0.534607875607536, -0.000000066473779, 0.317879714709398),
float3(0.000000110618471, 0.534607893399083, 0.317879684787684)
};
#endif
#endif