mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-17 11:00:38 +02:00
Added spotlight support.
This commit is contained in:
@@ -2465,7 +2465,7 @@ void idCommonLocal::Frame(void) {
|
||||
|
||||
eventLoop->RunEventLoop();
|
||||
|
||||
if (1)
|
||||
if (Sys_IsWindowVisible())
|
||||
{
|
||||
//--------------------------------------------
|
||||
// Determine how many game tics we are going to run,
|
||||
|
||||
+220
-15
@@ -1924,9 +1924,11 @@ struct Light
|
||||
float pad1;
|
||||
|
||||
// For point lights, this is the axis-aligned XYZ attenuation radius.
|
||||
// The scalar radius above is still kept as a max/fallback range and for rect lights.
|
||||
// For spot lights, pointRadius.x stores the near clip plane.
|
||||
// The scalar radius above is still kept as a max/fallback range for point lights,
|
||||
// as the influence range for rect lights, and as the far clip distance for spot lights.
|
||||
float3 pointRadius;
|
||||
float pointRadiusPad;
|
||||
float pointRadiusPad; // non-zero disables specular for this light
|
||||
};
|
||||
|
||||
struct ShadowPayload
|
||||
@@ -1958,6 +1960,7 @@ RWTexture2D<float4> gOutputTex : register(u0);
|
||||
|
||||
static const uint GL_RAYTRACING_LIGHT_TYPE_POINT = 0;
|
||||
static const uint GL_RAYTRACING_LIGHT_TYPE_RECT = 1;
|
||||
static const uint GL_RAYTRACING_LIGHT_TYPE_SPOT = 2;
|
||||
|
||||
static const uint GEOMETRY_FLAG_SKELETAL = 1;
|
||||
static const uint GEOMETRY_FLAG_UNLIT = 2;
|
||||
@@ -2097,7 +2100,55 @@ float ComputePointLightAttenuation(float3 worldPos, Light Lgt)
|
||||
// and radius.z controls Z reach in world space.
|
||||
float ellipsoidDistance = length(normalizedOffset);
|
||||
float atten = saturate(1.0 - ellipsoidDistance);
|
||||
return atten * atten;
|
||||
return atten;
|
||||
}
|
||||
|
||||
float ComputeSpotLightAttenuation(float3 worldPos, Light Lgt)
|
||||
{
|
||||
float3 lightToSurface = worldPos - Lgt.position;
|
||||
|
||||
float nearClip = max(Lgt.pointRadius.x, 0.0);
|
||||
float farClip = max(Lgt.radius, nearClip + 1e-4);
|
||||
|
||||
float depth = dot(lightToSurface, Lgt.normal);
|
||||
if (depth <= nearClip || depth >= farClip)
|
||||
return 0.0;
|
||||
|
||||
float invDepth = 1.0 / max(depth, 1e-4);
|
||||
|
||||
float projU = dot(lightToSurface, Lgt.axisU) * invDepth;
|
||||
float projV = dot(lightToSurface, Lgt.axisV) * invDepth;
|
||||
|
||||
float halfU = max(abs(Lgt.halfWidth), 1e-4);
|
||||
float halfV = max(abs(Lgt.halfHeight), 1e-4);
|
||||
|
||||
float edgeU = abs(projU) / halfU;
|
||||
float edgeV = abs(projV) / halfV;
|
||||
float edge = max(edgeU, edgeV);
|
||||
|
||||
if (edge >= 1.0)
|
||||
return 0.0;
|
||||
|
||||
float coneAtten = saturate(1.0 - edge);
|
||||
coneAtten = coneAtten;
|
||||
|
||||
float rangeAtten = saturate((farClip - depth) / max(farClip - nearClip, 1e-4));
|
||||
rangeAtten = rangeAtten;
|
||||
|
||||
return coneAtten * rangeAtten;
|
||||
}
|
||||
|
||||
float TraceSpotShadow(float3 worldPos, float3 N, float3 toLight, float dist)
|
||||
{
|
||||
float3 L = toLight / max(dist, 1e-6);
|
||||
|
||||
float NdotLRaw = saturate(dot(N, L));
|
||||
float normalBias = lerp(gShadowBias * 3.0, gShadowBias * 0.75, NdotLRaw);
|
||||
|
||||
float3 shadowOrigin = worldPos + N * normalBias + L * (gShadowBias * 0.5);
|
||||
float shadowTMax = max(dist - gShadowBias * 0.5, 0.001);
|
||||
|
||||
return TraceShadow(shadowOrigin, L, shadowTMax);
|
||||
}
|
||||
|
||||
float TraceSoftShadow(float3 worldPos, float3 N, Light Lgt, float3 toLight, float dist)
|
||||
@@ -2438,7 +2489,7 @@ void RayGen()
|
||||
float NdotLWrap = saturate((dot(N, L) + wrap) / (1.0 + wrap));
|
||||
|
||||
float shadow = 1.0;
|
||||
if (NdotLWrap > 0.0001 && atten > 0.0 && dist > 0.01)
|
||||
if (Lgt.samples != 0u && NdotLWrap > 0.0001 && atten > 0.0 && dist > 0.01)
|
||||
{
|
||||
shadow = TraceSoftShadow(worldPos, N, Lgt, toLight, dist);
|
||||
}
|
||||
@@ -2446,7 +2497,44 @@ void RayGen()
|
||||
float3 diffuse = Lgt.color * (Lgt.intensity * atten * NdotLWrap * shadow);
|
||||
lightingAccum += diffuse;
|
||||
|
||||
specularAccum += ComputeSpecular(N, V, L, Lgt.color, Lgt.intensity, atten, shadow, baseAlbedo);
|
||||
if (Lgt.pointRadiusPad <= 0.5)
|
||||
{
|
||||
specularAccum += ComputeSpecular(N, V, L, Lgt.color, Lgt.intensity, atten, shadow, baseAlbedo);
|
||||
}
|
||||
}
|
||||
else if (Lgt.type == GL_RAYTRACING_LIGHT_TYPE_SPOT)
|
||||
{
|
||||
float3 toLight = Lgt.position - worldPos;
|
||||
float distSq = dot(toLight, toLight);
|
||||
float dist = sqrt(max(distSq, 1e-6));
|
||||
float3 L = toLight / dist;
|
||||
|
||||
float atten = ComputeSpotLightAttenuation(worldPos, Lgt);
|
||||
|
||||
float wrap = 0.35;
|
||||
float NdotLWrap = saturate((dot(N, L) + wrap) / (1.0 + wrap));
|
||||
|
||||
float shadow = 1.0;
|
||||
if (Lgt.samples != 0u && NdotLWrap > 0.0001 && atten > 0.0 && dist > 0.01)
|
||||
{
|
||||
shadow = TraceSpotShadow(worldPos, N, toLight, dist);
|
||||
}
|
||||
|
||||
float3 diffuse = Lgt.color * (Lgt.intensity * atten * NdotLWrap * shadow);
|
||||
lightingAccum += diffuse;
|
||||
|
||||
if (Lgt.pointRadiusPad <= 0.5)
|
||||
{
|
||||
specularAccum += ComputeSpecular(
|
||||
N,
|
||||
V,
|
||||
L,
|
||||
Lgt.color,
|
||||
Lgt.intensity,
|
||||
atten,
|
||||
shadow,
|
||||
baseAlbedo);
|
||||
}
|
||||
}
|
||||
else if (Lgt.type == GL_RAYTRACING_LIGHT_TYPE_RECT)
|
||||
{
|
||||
@@ -2460,7 +2548,7 @@ void RayGen()
|
||||
atten = atten * atten * atten * atten;
|
||||
|
||||
float shadow = 1.0;
|
||||
if (atten > 0.0 && centerDist > 0.01)
|
||||
if (Lgt.samples != 0u && atten > 0.0 && centerDist > 0.01)
|
||||
{
|
||||
shadow = RectLightShadow(worldPos, N, Lgt, pixel);
|
||||
}
|
||||
@@ -2498,15 +2586,18 @@ void RayGen()
|
||||
|
||||
rectDiffuseAccum += Lgt.color * sampleWeight;
|
||||
|
||||
rectSpecAccum += ComputeSpecular(
|
||||
N,
|
||||
V,
|
||||
L,
|
||||
Lgt.color,
|
||||
Lgt.intensity * faceTerm,
|
||||
1.0,
|
||||
1.0,
|
||||
baseAlbedo);
|
||||
if (Lgt.pointRadiusPad <= 0.5)
|
||||
{
|
||||
rectSpecAccum += ComputeSpecular(
|
||||
N,
|
||||
V,
|
||||
L,
|
||||
Lgt.color,
|
||||
Lgt.intensity * faceTerm,
|
||||
1.0,
|
||||
1.0,
|
||||
baseAlbedo);
|
||||
}
|
||||
}
|
||||
|
||||
rectDiffuseAccum /= (float)sampleCount;
|
||||
@@ -3329,6 +3420,120 @@ glRaytracingLight_t glRaytracingLightingMakePointLight(
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
glRaytracingLight_t glRaytracingLightingMakeSpotLight(
|
||||
float px, float py, float pz,
|
||||
float dx, float dy, float dz,
|
||||
float ux, float uy, float uz,
|
||||
float vx, float vy, float vz,
|
||||
float nearPlane,
|
||||
float farPlane,
|
||||
float tanHalfWidth,
|
||||
float tanHalfHeight,
|
||||
float r, float g, float b,
|
||||
float intensity,
|
||||
uint32_t samples)
|
||||
{
|
||||
glRaytracingLight_t l = {};
|
||||
|
||||
glRaytracingNormalize3(dx, dy, dz);
|
||||
|
||||
// Make U perpendicular to D.
|
||||
{
|
||||
const float du = dx * ux + dy * uy + dz * uz;
|
||||
ux -= dx * du;
|
||||
uy -= dy * du;
|
||||
uz -= dz * du;
|
||||
|
||||
const float uLenSq = ux * ux + uy * uy + uz * uz;
|
||||
if (uLenSq <= 1e-20f)
|
||||
{
|
||||
const float absDz = (dz < 0.0f) ? -dz : dz;
|
||||
if (absDz < 0.999f)
|
||||
{
|
||||
glRaytracingCross3(0.0f, 0.0f, 1.0f, dx, dy, dz, ux, uy, uz);
|
||||
}
|
||||
else
|
||||
{
|
||||
glRaytracingCross3(0.0f, 1.0f, 0.0f, dx, dy, dz, ux, uy, uz);
|
||||
}
|
||||
}
|
||||
glRaytracingNormalize3(ux, uy, uz);
|
||||
}
|
||||
|
||||
// Rebuild V from D x U so the basis is orthonormal, while preserving the
|
||||
// sign of the caller-provided V whenever possible.
|
||||
{
|
||||
float builtVx, builtVy, builtVz;
|
||||
glRaytracingCross3(dx, dy, dz, ux, uy, uz, builtVx, builtVy, builtVz);
|
||||
glRaytracingNormalize3(builtVx, builtVy, builtVz);
|
||||
|
||||
const float sign = builtVx * vx + builtVy * vy + builtVz * vz;
|
||||
if (sign < 0.0f)
|
||||
{
|
||||
builtVx = -builtVx;
|
||||
builtVy = -builtVy;
|
||||
builtVz = -builtVz;
|
||||
}
|
||||
|
||||
vx = builtVx;
|
||||
vy = builtVy;
|
||||
vz = builtVz;
|
||||
}
|
||||
|
||||
if (nearPlane < 0.0f)
|
||||
nearPlane = 0.0f;
|
||||
if (farPlane <= nearPlane)
|
||||
farPlane = nearPlane + 1e-3f;
|
||||
|
||||
if (tanHalfWidth < 0.0f) tanHalfWidth = -tanHalfWidth;
|
||||
if (tanHalfHeight < 0.0f) tanHalfHeight = -tanHalfHeight;
|
||||
|
||||
if (tanHalfWidth <= 1e-4f)
|
||||
tanHalfWidth = 1e-4f;
|
||||
if (tanHalfHeight <= 1e-4f)
|
||||
tanHalfHeight = 1e-4f;
|
||||
|
||||
l.position.x = px;
|
||||
l.position.y = py;
|
||||
l.position.z = pz;
|
||||
|
||||
// For spot lights, radius stores the far clip distance while pointRadius.x
|
||||
// stores the near clip distance.
|
||||
l.radius = farPlane;
|
||||
l.pointRadius.x = nearPlane;
|
||||
l.pointRadius.y = 0.0f;
|
||||
l.pointRadius.z = 0.0f;
|
||||
l.pointRadiusPad = 0.0f;
|
||||
|
||||
l.color.x = r;
|
||||
l.color.y = g;
|
||||
l.color.z = b;
|
||||
l.intensity = intensity;
|
||||
|
||||
l.normal.x = dx;
|
||||
l.normal.y = dy;
|
||||
l.normal.z = dz;
|
||||
l.type = GL_RAYTRACING_LIGHT_TYPE_SPOT;
|
||||
|
||||
l.axisU.x = ux;
|
||||
l.axisU.y = uy;
|
||||
l.axisU.z = uz;
|
||||
l.halfWidth = tanHalfWidth;
|
||||
|
||||
l.axisV.x = vx;
|
||||
l.axisV.y = vy;
|
||||
l.axisV.z = vz;
|
||||
l.halfHeight = tanHalfHeight;
|
||||
|
||||
l.samples = samples ? samples : 1u;
|
||||
l.twoSided = 0;
|
||||
l.persistant = 0.0f;
|
||||
l.pad1 = 0.0f;
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
glRaytracingLight_t glRaytracingLightingMakeRectLight(
|
||||
float px, float py, float pz,
|
||||
float nx, float ny, float nz,
|
||||
|
||||
+37
-12
@@ -1636,27 +1636,38 @@ typedef struct glRaytracingVec3_s
|
||||
typedef struct glRaytracingLight_s
|
||||
{
|
||||
glRaytracingVec3_t position;
|
||||
float radius;
|
||||
float radius; // point: max XYZ radius / fallback range
|
||||
// rect : influence range
|
||||
// spot : far clip distance
|
||||
|
||||
glRaytracingVec3_t color;
|
||||
float intensity;
|
||||
|
||||
glRaytracingVec3_t normal;
|
||||
uint32_t type;
|
||||
glRaytracingVec3_t normal; // rect: emitter normal
|
||||
// spot: forward direction
|
||||
// point: ignored
|
||||
uint32_t type; // POINT / RECT / SPOT
|
||||
|
||||
glRaytracingVec3_t axisU;
|
||||
float halfWidth;
|
||||
glRaytracingVec3_t axisU; // rect: local X axis
|
||||
// spot: right basis
|
||||
float halfWidth; // rect: half extent along axisU
|
||||
// spot: projected half-width slope
|
||||
|
||||
glRaytracingVec3_t axisV;
|
||||
float halfHeight;
|
||||
glRaytracingVec3_t axisV; // rect: local Y axis
|
||||
// spot: up basis
|
||||
float halfHeight; // rect: half extent along axisV
|
||||
// spot: projected half-height slope
|
||||
|
||||
uint32_t samples;
|
||||
uint32_t twoSided;
|
||||
uint32_t samples; // rect: sample count
|
||||
// point/spot: 0 disables shadows, non-zero enables them
|
||||
uint32_t twoSided; // rect: 0/1, ignored for point / spot
|
||||
float persistant;
|
||||
float pad1;
|
||||
|
||||
glRaytracingVec3_t pointRadius;
|
||||
float pointRadiusPad;
|
||||
glRaytracingVec3_t pointRadius; // point: XYZ attenuation radii
|
||||
// spot: x = near clip, y/z unused
|
||||
// rect : scalar range copy
|
||||
float pointRadiusPad; // non-zero disables specular for this light
|
||||
} glRaytracingLight_t;
|
||||
|
||||
typedef struct glRaytracingLightingPassDesc_s
|
||||
@@ -1746,7 +1757,20 @@ glRaytracingLight_t glRaytracingLightingMakePointLight(
|
||||
float r, float g, float b,
|
||||
float intensity);
|
||||
|
||||
glRaytracingLight_t glRaytracingLightingMakeRectLight(
|
||||
glRaytracingLight_t glRaytracingLightingMakeSpotLight(
|
||||
float px, float py, float pz,
|
||||
float dx, float dy, float dz,
|
||||
float ux, float uy, float uz,
|
||||
float vx, float vy, float vz,
|
||||
float nearPlane,
|
||||
float farPlane,
|
||||
float tanHalfWidth,
|
||||
float tanHalfHeight,
|
||||
float r, float g, float b,
|
||||
float intensity,
|
||||
uint32_t samples);
|
||||
|
||||
glRaytracingLight_t glRaytracingLightingMakeRectLight(
|
||||
float px, float py, float pz,
|
||||
float nx, float ny, float nz,
|
||||
float ux, float uy, float uz,
|
||||
@@ -1801,6 +1825,7 @@ static void glRaytracingCross3(
|
||||
|
||||
static const int GL_RAYTRACING_LIGHT_TYPE_POINT = 0;
|
||||
static const int GL_RAYTRACING_LIGHT_TYPE_RECT = 1;
|
||||
static const int GL_RAYTRACING_LIGHT_TYPE_SPOT = 2;
|
||||
|
||||
void TessellatePolygon(const std::vector<GLVertex>& src, std::vector<GLVertex>& out);
|
||||
|
||||
|
||||
@@ -417,55 +417,7 @@ helper function that takes the current width/height and might make them smaller
|
||||
================
|
||||
*/
|
||||
void idImage::GetDownsize( int &scaled_width, int &scaled_height ) const {
|
||||
int size = 0;
|
||||
|
||||
// perform optional picmip operation to save texture memory
|
||||
if ( depth == TD_SPECULAR && globalImages->image_downSizeSpecular.GetInteger() ) {
|
||||
size = globalImages->image_downSizeSpecularLimit.GetInteger();
|
||||
if ( size == 0 ) {
|
||||
size = 64;
|
||||
}
|
||||
} else if ( depth == TD_BUMP && globalImages->image_downSizeBump.GetInteger() ) {
|
||||
size = globalImages->image_downSizeBumpLimit.GetInteger();
|
||||
if ( size == 0 ) {
|
||||
size = 64;
|
||||
}
|
||||
} else if ( ( allowDownSize || globalImages->image_forceDownSize.GetBool() ) && globalImages->image_downSize.GetInteger() ) {
|
||||
size = globalImages->image_downSizeLimit.GetInteger();
|
||||
if ( size == 0 ) {
|
||||
size = 256;
|
||||
}
|
||||
}
|
||||
|
||||
if ( size > 0 ) {
|
||||
while ( scaled_width > size || scaled_height > size ) {
|
||||
if ( scaled_width > 1 ) {
|
||||
scaled_width >>= 1;
|
||||
}
|
||||
if ( scaled_height > 1 ) {
|
||||
scaled_height >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clamp to minimum size
|
||||
if ( scaled_width < 1 ) {
|
||||
scaled_width = 1;
|
||||
}
|
||||
if ( scaled_height < 1 ) {
|
||||
scaled_height = 1;
|
||||
}
|
||||
|
||||
// clamp size to the hardware specific upper limit
|
||||
// scale both axis down equally so we don't have to
|
||||
// deal with a half mip resampling
|
||||
// This causes a 512*256 texture to sample down to
|
||||
// 256*128 on a voodoo3, even though it could be 256*256
|
||||
while ( scaled_width > glConfig.maxTextureSize
|
||||
|| scaled_height > glConfig.maxTextureSize ) {
|
||||
scaled_width >>= 1;
|
||||
scaled_height >>= 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -427,6 +427,14 @@ static bool R_ParseImageProgram_r( idLexer &src, byte **pic, int *width, int *he
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (width2 <= 0 || height2 <= 0) {
|
||||
if (pic) {
|
||||
R_StaticFree(*pic);
|
||||
*pic = NULL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// process it
|
||||
if ( pic ) {
|
||||
|
||||
+200
-20
@@ -2,54 +2,234 @@
|
||||
#pragma hdrstop
|
||||
|
||||
#include "tr_local.h"
|
||||
#include <math.h>
|
||||
|
||||
static idVec3 RB_DXRMakeVec3(float x, float y, float z)
|
||||
{
|
||||
idVec3 v;
|
||||
v.x = x;
|
||||
v.y = y;
|
||||
v.z = z;
|
||||
return v;
|
||||
}
|
||||
|
||||
static idVec3 RB_DXRSubVec3(const idVec3& a, const idVec3& b)
|
||||
{
|
||||
return RB_DXRMakeVec3(a.x - b.x, a.y - b.y, a.z - b.z);
|
||||
}
|
||||
|
||||
static idVec3 RB_DXRScaleVec3(const idVec3& v, float s)
|
||||
{
|
||||
return RB_DXRMakeVec3(v.x * s, v.y * s, v.z * s);
|
||||
}
|
||||
|
||||
static float RB_DXRDotVec3(const idVec3& a, const idVec3& b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z;
|
||||
}
|
||||
|
||||
static idVec3 RB_DXRCrossVec3(const idVec3& a, const idVec3& b)
|
||||
{
|
||||
return RB_DXRMakeVec3(
|
||||
a.y * b.z - a.z * b.y,
|
||||
a.z * b.x - a.x * b.z,
|
||||
a.x * b.y - a.y * b.x);
|
||||
}
|
||||
|
||||
static float RB_DXRLengthVec3(const idVec3& v)
|
||||
{
|
||||
return sqrtf(v.x * v.x + v.y * v.y + v.z * v.z);
|
||||
}
|
||||
|
||||
static idVec3 RB_DXRNormalizeVec3Safe(const idVec3& v, const idVec3& fallback)
|
||||
{
|
||||
const float len = RB_DXRLengthVec3(v);
|
||||
if (len > 1e-20f)
|
||||
{
|
||||
const float invLen = 1.0f / len;
|
||||
return RB_DXRMakeVec3(v.x * invLen, v.y * invLen, v.z * invLen);
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
|
||||
static idVec3 RB_DXRTransformLightVector(const idMat3& axis, const idVec3& v)
|
||||
{
|
||||
return RB_DXRMakeVec3(
|
||||
axis[0].x * v.x + axis[1].x * v.y + axis[2].x * v.z,
|
||||
axis[0].y * v.x + axis[1].y * v.y + axis[2].y * v.z,
|
||||
axis[0].z * v.x + axis[1].z * v.y + axis[2].z * v.z);
|
||||
}
|
||||
|
||||
static glRaytracingLight_t RB_DXRMakeSpotLightFromRenderLight(
|
||||
const renderLight_t& srcLight,
|
||||
const idVec3& worldOrigin,
|
||||
float r, float g, float b,
|
||||
float intensity)
|
||||
{
|
||||
const idVec3 targetW = RB_DXRTransformLightVector(srcLight.axis, srcLight.target);
|
||||
const idVec3 rightW = RB_DXRTransformLightVector(srcLight.axis, srcLight.right);
|
||||
const idVec3 upW = RB_DXRTransformLightVector(srcLight.axis, srcLight.up);
|
||||
const idVec3 startW = RB_DXRTransformLightVector(srcLight.axis, srcLight.start);
|
||||
const idVec3 endW = RB_DXRTransformLightVector(srcLight.axis, srcLight.end);
|
||||
|
||||
idVec3 fallbackDir = RB_DXRCrossVec3(rightW, upW);
|
||||
fallbackDir = RB_DXRNormalizeVec3Safe(fallbackDir, RB_DXRMakeVec3(0.0f, 0.0f, -1.0f));
|
||||
|
||||
const idVec3 dir = RB_DXRNormalizeVec3Safe(targetW, fallbackDir);
|
||||
|
||||
float centerDepth = RB_DXRDotVec3(targetW, dir);
|
||||
if (centerDepth <= 1e-4f)
|
||||
{
|
||||
centerDepth = RB_DXRLengthVec3(targetW);
|
||||
}
|
||||
if (centerDepth <= 1e-4f)
|
||||
{
|
||||
centerDepth = RB_DXRDotVec3(endW, dir);
|
||||
}
|
||||
if (centerDepth <= 1e-4f)
|
||||
{
|
||||
centerDepth = 64.0f;
|
||||
}
|
||||
|
||||
const idVec3 rightPerp = RB_DXRSubVec3(
|
||||
rightW,
|
||||
RB_DXRScaleVec3(dir, RB_DXRDotVec3(rightW, dir)));
|
||||
|
||||
const idVec3 upPerp = RB_DXRSubVec3(
|
||||
upW,
|
||||
RB_DXRScaleVec3(dir, RB_DXRDotVec3(upW, dir)));
|
||||
|
||||
idVec3 axisU = RB_DXRCrossVec3(RB_DXRMakeVec3(0.0f, 0.0f, 1.0f), dir);
|
||||
axisU = RB_DXRNormalizeVec3Safe(axisU, RB_DXRMakeVec3(1.0f, 0.0f, 0.0f));
|
||||
axisU = RB_DXRNormalizeVec3Safe(rightPerp, axisU);
|
||||
|
||||
idVec3 axisV = RB_DXRCrossVec3(dir, axisU);
|
||||
axisV = RB_DXRNormalizeVec3Safe(axisV, RB_DXRMakeVec3(0.0f, 1.0f, 0.0f));
|
||||
if (RB_DXRDotVec3(axisV, upPerp) < 0.0f)
|
||||
{
|
||||
axisV = RB_DXRScaleVec3(axisV, -1.0f);
|
||||
}
|
||||
|
||||
float tanHalfWidth = RB_DXRLengthVec3(rightPerp) / centerDepth;
|
||||
float tanHalfHeight = RB_DXRLengthVec3(upPerp) / centerDepth;
|
||||
|
||||
float nearPlane = RB_DXRDotVec3(startW, dir);
|
||||
if (nearPlane < 0.0f)
|
||||
{
|
||||
nearPlane = 0.0f;
|
||||
}
|
||||
|
||||
float farPlane = RB_DXRDotVec3(endW, dir);
|
||||
if (farPlane < centerDepth)
|
||||
{
|
||||
farPlane = centerDepth;
|
||||
}
|
||||
if (farPlane <= nearPlane)
|
||||
{
|
||||
farPlane = nearPlane + 64.0f;
|
||||
}
|
||||
|
||||
glRaytracingLight_t light = glRaytracingLightingMakeSpotLight(
|
||||
worldOrigin.x, worldOrigin.y, worldOrigin.z,
|
||||
dir.x, dir.y, dir.z,
|
||||
axisU.x, axisU.y, axisU.z,
|
||||
axisV.x, axisV.y, axisV.z,
|
||||
nearPlane,
|
||||
farPlane,
|
||||
tanHalfWidth,
|
||||
tanHalfHeight,
|
||||
r, g, b,
|
||||
intensity,
|
||||
1u);
|
||||
|
||||
light.samples = srcLight.noShadows ? 0u : 1u;
|
||||
light.pointRadiusPad = srcLight.noSpecular ? 1.0f : 0.0f;
|
||||
|
||||
return light;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
RB_DXDrawInteractions
|
||||
====================
|
||||
*/
|
||||
void RB_DXDrawInteractions(void) {
|
||||
void RB_DXDrawInteractions(void)
|
||||
{
|
||||
viewLight_t* vLight;
|
||||
bool hasLight = false;
|
||||
|
||||
for (vLight = backEnd.viewDef->viewLights; vLight; vLight = vLight->next) {
|
||||
for (vLight = backEnd.viewDef->viewLights; vLight; vLight = vLight->next)
|
||||
{
|
||||
backEnd.vLight = vLight;
|
||||
|
||||
// do fogging later
|
||||
if (vLight->lightShader->IsFogLight()) {
|
||||
if (vLight->lightShader->IsFogLight())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (vLight->lightShader->IsBlendLight()) {
|
||||
if (vLight->lightShader->IsBlendLight())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!vLight->localInteractions && !vLight->globalInteractions
|
||||
&& !vLight->translucentInteractions) {
|
||||
&& !vLight->translucentInteractions)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
hasLight = true;
|
||||
const renderLight_t& srcLight = vLight->lightDef->parms;
|
||||
const float r = srcLight.shaderParms[SHADERPARM_RED];
|
||||
const float g = srcLight.shaderParms[SHADERPARM_GREEN];
|
||||
const float b = srcLight.shaderParms[SHADERPARM_BLUE];
|
||||
const float intensity = 1.0f;
|
||||
|
||||
glRaytracingLight_t light = {};
|
||||
light.color.x = vLight->lightDef->parms.shaderParms[SHADERPARM_RED];
|
||||
light.color.y = vLight->lightDef->parms.shaderParms[SHADERPARM_GREEN];
|
||||
light.color.z = vLight->lightDef->parms.shaderParms[SHADERPARM_BLUE];
|
||||
light.type = GL_RAYTRACING_LIGHT_TYPE_POINT;
|
||||
light.pointRadius.x = vLight->lightDef->parms.lightRadius[0] * 2;
|
||||
light.pointRadius.y = vLight->lightDef->parms.lightRadius[1] * 2;
|
||||
light.pointRadius.z = vLight->lightDef->parms.lightRadius[2] * 2;
|
||||
light.intensity = 1;
|
||||
light.position.x = vLight->globalLightOrigin.x;
|
||||
light.position.y = vLight->globalLightOrigin.y;
|
||||
light.position.z = vLight->globalLightOrigin.z;
|
||||
glRaytracingLightingAddLight(&light);
|
||||
bool supported = true;
|
||||
|
||||
if (srcLight.pointLight)
|
||||
{
|
||||
light = glRaytracingLightingMakePointLight(
|
||||
vLight->globalLightOrigin.x,
|
||||
vLight->globalLightOrigin.y,
|
||||
vLight->globalLightOrigin.z,
|
||||
srcLight.lightRadius[0] * 1.4f,
|
||||
srcLight.lightRadius[1] * 1.4f,
|
||||
srcLight.lightRadius[2] * 1.4f,
|
||||
r, g, b,
|
||||
intensity);
|
||||
|
||||
light.samples = srcLight.noShadows ? 0u : 1u;
|
||||
light.pointRadiusPad = srcLight.noSpecular ? 1.0f : 0.0f;
|
||||
}
|
||||
else if (!srcLight.parallel)
|
||||
{
|
||||
light = RB_DXRMakeSpotLightFromRenderLight(
|
||||
srcLight,
|
||||
vLight->globalLightOrigin,
|
||||
r, g, b,
|
||||
intensity);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Parallel projected lights are not spot lights.
|
||||
// Handle them in a separate directional/orthographic path.
|
||||
supported = false;
|
||||
common->Warning("Parallel lights are not needed with raytracing! Just place a skybox.");
|
||||
}
|
||||
|
||||
if (supported && glRaytracingLightingAddLight(&light))
|
||||
{
|
||||
hasLight = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasLight)
|
||||
{
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
glFinish();
|
||||
glLightScene(backEnd.viewDef->renderWorld->dxrWorldId);
|
||||
glRaytracingLightingClearLights(false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user