Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
da553f6
use metadata to fetch IES profile, use new API and create CDC texture…
AnastaZIuk Mar 14, 2024
ec48b03
Add IESExampleEventReceiver and events handling, have CDC mode and 3D…
AnastaZIuk Mar 15, 2024
eb97f88
Add IESCompute interface for compute shaders, add cdc.comp & common.h…
AnastaZIuk Mar 15, 2024
12b7d00
Have single binding per vector in the 0 set, update the shader and ma…
AnastaZIuk Mar 16, 2024
f9be2b3
Implement compute shader which generates CDC texture, update main.cpp…
AnastaZIuk Mar 16, 2024
2e84730
Spot bugs and fix them, generate CDC texture with GL CS, perform tests
AnastaZIuk Mar 17, 2024
b124163
Refactor & clean whole IES example, have entire interface API put int…
AnastaZIuk Mar 17, 2024
74fbcbc
Change degrees by mouse wheel
AnastaZIuk Mar 17, 2024
48cf46a
Have 4 modes for displaying data - CDC, IES Candela, Spherical Coordi…
AnastaZIuk Mar 19, 2024
d737a90
Add half a pixel to compute uv, define UINT16_MAX only if not defined…
AnastaZIuk Mar 24, 2024
ddc1ac0
Merge branch 'new_ditt' of github.com:Devsh-Graphics-Programming/Nabl…
AnastaZIuk Mar 24, 2024
3893b16
Remove 028e97564391140b1476695ae7a46fa4.ies file, use the one from me…
AnastaZIuk Mar 24, 2024
6a3ca12
Add outPassTMask image binding with RG8 format for debugging purposes…
AnastaZIuk Mar 24, 2024
053258b
add QUANT_ERROR_ADMISSIBLE, make it more close to IES Viewer, give co…
AnastaZIuk Mar 25, 2024
1e20cb6
make it almost 1:1 IES Viewer like, now I have divergence at last angle
AnastaZIuk Mar 25, 2024
aeeed75
get data from the loader, no manual copy buffer & shifts
AnastaZIuk Mar 27, 2024
4b2c54a
correct var names in IES fragment shader leading to bugs, NDC != UV, …
AnastaZIuk Mar 27, 2024
8f632d2
update cdc.comp shader with horizontal angles wrapping methods
AnastaZIuk Mar 29, 2024
3d46c60
debug session, update wrapHAngle with clamps to eliminate edge issues
AnastaZIuk Mar 31, 2024
b38f832
Remove shifting phi in spherical coordinates getter, have the spheric…
AnastaZIuk Apr 2, 2024
6d2712d
save ies input grid data into png
AnastaZIuk Apr 2, 2024
d1ba535
optimize call to lower/upper bound by setting horizontal indices to 0…
AnastaZIuk Apr 2, 2024
7cb1c2f
Fix upper & lower bound implementations and eliminate bilinear interp…
AnastaZIuk Apr 2, 2024
21d14c3
Add profile type logs
AnastaZIuk Apr 2, 2024
3deefd4
Perform tests with all types of type-C plane IES symmetry, correct bu…
AnastaZIuk Apr 3, 2024
0ea5cae
write all CPU outputs at the end, spot .png writer write path bug
AnastaZIuk Apr 4, 2024
6efa445
update main.cpp
AnastaZIuk Apr 5, 2024
112e991
use profile.getSymmetry() to determine offset for horizontal angles f…
AnastaZIuk Apr 8, 2024
41bd477
update main.cpp, add elapsed time to measure cpu cdc texture creation
AnastaZIuk Apr 9, 2024
67de7e8
force the loader to create CDC not meta only
AnastaZIuk Apr 10, 2024
6ed94b0
update media submodule
AnastaZIuk Apr 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
260 changes: 260 additions & 0 deletions 50.IESProfileTest/compute/cdc.comp
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
#version 430 core

// Copyright (C) 2018-2024 - DevSH Graphics Programming Sp. z O.O.
// This file is part of the "Nabla Engine".
// For conditions of distribution and use, see copyright notice in nabla.h

#include "common.h"

layout(local_size_x = WORKGROUP_DIMENSION, local_size_y = WORKGROUP_DIMENSION) in;

layout(set = 0, binding = 0, r16) restrict uniform image2D outIESCandelaImage;
layout(set = 0, binding = 1, rg32f) restrict uniform image2D outSphericalCoordinatesImage;
layout(set = 0, binding = 2, rgba32f) restrict uniform image2D outOUVProjectionDirectionImage;
layout(set = 0, binding = 3, rg8) restrict uniform image2D outPassTMask;

layout(std430, set = 0, binding = 4) readonly buffer HorizontalAngles
{
double hAngles[];
};

layout(std430, set = 0, binding = 5) readonly buffer VerticalAngles
{
double vAngles[];
};

layout(std430, set = 0, binding = 6) readonly buffer Data
{
double data[];
};

layout(push_constant) uniform PushConstants
{
float maxIValue;
float zAngleDegreeRotation;
uint mode;
uint dummy;
} pc;

vec3 octahedronUVToDir(vec2 uv)
{
vec3 position = vec3((uv * 2.0 - 1.0).xy, 0.0);
vec2 absP = vec2(abs(position.x), abs(position.y));

position.z = 1.0 - absP.x - absP.y;

if (position.z < 0.0)
{
position.x = sign(position.x) * (1.0 - absP.y);
position.y = sign(position.y) * (1.0 - absP.x);
}

// rotate position vector around Z-axis with "pc.zAngleDegreeRotation"
if(pc.zAngleDegreeRotation != 0.0)
{
float rDegree = pc.zAngleDegreeRotation;

const float zAngleRadians = float(rDegree * M_PI / 180.0);
const float cosineV = cos(zAngleRadians);
const float sineV = sin(zAngleRadians);

position = vec3(cosineV * position.x - cosineV * position.y, sineV * position.x + sineV * position.y, position.z);
//position = vec3((cosineV * position.x) - (sineV * position.y), (cosineV * position.x) + (sineV * position.y), position.z);
}

return normalize(position);
}

//! Returns spherical coordinates with physics convention in radians
/*
https://en.wikipedia.org/wiki/Spherical_coordinate_system#/media/File:3D_Spherical.svg
Retval.x is "theta" polar angle in range [0, PI] & Retval.y "phi" is azimuthal angle
in range [-PI, PI] range
*/

vec2 sphericalDirToRadians(vec3 direction)
{
double theta = acos(clamp(direction.z/length(direction), -1.0, 1.0));
double phi = atan(direction.y, direction.x);

return vec2(theta, phi);
}

uint implGetVUB(const float angle)
{
const uint len = vAngles.length();

for(uint i = 0; i < len; ++i)
if(vAngles[i] > angle)
return i;

return len;
}

uint implGetHUB(const float angle)
{
const uint len = hAngles.length();

for(uint i = 0; i < len; ++i)
if(hAngles[i] > angle)
return i;

return len;
}

uint getVLB(const float angle)
{
return uint(max(int(implGetVUB(angle)) - 1, 0));
}

uint getHLB(const float angle)
{
return uint(max(int(implGetHUB(angle)) - 1, 0));
}

uint getVUB(const float angle)
{
return uint(min(int(implGetVUB(angle)), int(vAngles.length()) - 1));
}

uint getHUB(const float angle)
{
return uint(min(int(implGetHUB(angle)), int(hAngles.length()) - 1));
}

double getValue(uint i, uint j)
{
return data[vAngles.length() * i + j];
}

// symmetry
#define ISOTROPIC 0u
#define QUAD_SYMETRIC 1u
#define HALF_SYMETRIC 2u
#define NO_LATERAL_SYMMET 3u

uint getSymmetry() // TODO: to reduce check time we could pass it with PCs
{
const uint hALength = hAngles.length();
if(hALength < 2) // careful here, somebody can break it by feeding us with too much data by mistake
return ISOTROPIC;

const double hABack = hAngles[hALength - 1];

if(hABack == 90)
return QUAD_SYMETRIC;
else if(hABack == 180) // note that OTHER_HALF_SYMMETRIC = HALF_SYMETRIC here
return HALF_SYMETRIC;
else
return NO_LATERAL_SYMMET;
}

float wrapPhi(const float phi, const uint symmetry) //! wrap phi spherical coordinate compoment to range defined by symmetry
{
switch (symmetry)
{
case ISOTROPIC:
return 0.0;
case QUAD_SYMETRIC: //! phi MIRROR_REPEAT wrap onto [0, 90] degrees range
{
float wrapPhi = abs(phi); //! first MIRROR

if(wrapPhi > M_HALF_PI) //! then REPEAT
wrapPhi = clamp(M_HALF_PI - (wrapPhi - M_HALF_PI), 0, M_HALF_PI);

return wrapPhi; //! eg. maps (in degrees) 91,269,271 -> 89 and 179,181,359 -> 1
}
case HALF_SYMETRIC: //! phi MIRROR wrap onto [0, 180] degrees range
return abs(phi); //! eg. maps (in degress) 181 -> 179 or 359 -> 1
case NO_LATERAL_SYMMET:
{
if(phi < 0)
return phi + 2.0 * M_PI;
else
return phi;
}
}

return 69;
}

double sampleI(const vec2 sphericalCoordinates, const uint symmetry)
{
const float vAngle = degrees(sphericalCoordinates.x), hAngle = degrees(wrapPhi(sphericalCoordinates.y, symmetry));

double vABack = vAngles[vAngles.length() - 1];
double hABack = hAngles[hAngles.length() - 1];

if (vAngle > vABack)
return 0.0;

// bilinear interpolation
uint j0 = getVLB(vAngle);
uint j1 = getVUB(vAngle);
uint i0 = symmetry == ISOTROPIC ? 0 : getHLB(hAngle);
uint i1 = symmetry == ISOTROPIC ? 0 : getHUB(hAngle);

double uReciprocal = i1 == i0 ? 1.0 : 1.0 / (hAngles[i1] - hAngles[i0]);
double vReciprocal = j1 == j0 ? 1.0 : 1.0 / (vAngles[j1] - vAngles[j0]);

double u = (hAngle - hAngles[i0]) * uReciprocal;
double v = (vAngle - vAngles[j0]) * vReciprocal;

double s0 = getValue(i0, j0) * (1.0 - v) + getValue(i0, j1) * (v);
double s1 = getValue(i1, j0) * (1.0 - v) + getValue(i1, j1) * (v);

return s0 * (1.0 - u) + s1 * u;
}

//! Checks if (x,y) /in [0,PI] x [-PI,PI] product
/*
IES vertical range is [0, 180] degrees
and horizontal range is [0, 360] degrees
but for easier computations (MIRROR & MIRROW_REPEAT operations)
we represent horizontal range as [-180, 180] given spherical coordinates
*/

bool isWithinSCDomain(vec2 point)
{
const vec2 lb = vec2(0, -M_PI);
const vec2 ub = vec2(M_PI, M_PI);

return all(lessThanEqual(lb, point)) && all(lessThanEqual(point, ub));
}

void main()
{
const float VERTICAL_INVERSE = 1.0f / TEXTURE_SIZE;
const float HORIZONTAL_INVERSE = 1.0f / TEXTURE_SIZE;

const ivec2 pixelCoordinates = ivec2(gl_GlobalInvocationID.xy);
const ivec2 destinationSize = imageSize(outIESCandelaImage);

if (all(lessThan(pixelCoordinates, destinationSize)))
{
const vec2 uv = vec2((float(pixelCoordinates.x) + 0.5) * VERTICAL_INVERSE, (float(pixelCoordinates.y) + 0.5) * HORIZONTAL_INVERSE);
const vec3 direction = octahedronUVToDir(uv);
const vec2 sphericalCoordinates = sphericalDirToRadians(direction); // third radius spherical compoment is normalized and skipped

const double intensity = sampleI(sphericalCoordinates, getSymmetry());
const vec4 value = vec4(intensity / pc.maxIValue, 0, 0, 0);

const double normD = length(direction);
vec2 mask;

if(1.0 - QUANT_ERROR_ADMISSIBLE <= normD && normD <= 1.0 + QUANT_ERROR_ADMISSIBLE)
mask.x = 1.0; // pass
else
mask.x = 0;

if(isWithinSCDomain(sphericalCoordinates))
mask.y = 1.0; // pass
else
mask.y = 0;

imageStore(outIESCandelaImage, pixelCoordinates, value);
imageStore(outSphericalCoordinatesImage, pixelCoordinates, vec4(sphericalCoordinates, 0, 1));
imageStore(outOUVProjectionDirectionImage, pixelCoordinates, vec4(direction.xyz, 1));
imageStore(outPassTMask, pixelCoordinates, vec4(mask.xy, 1, 1));
}
}
15 changes: 15 additions & 0 deletions 50.IESProfileTest/compute/common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef _COMMON_INCLUDED_
#define _COMMON_INCLUDED_

#ifndef UINT16_MAX
#define UINT16_MAX 65535u // would be cool if we have this define somewhere or GLSL do
#endif
#define M_PI 3.1415926535897932384626433832795f // would be cool if we have this define somewhere or GLSL do
#define M_HALF_PI M_PI/2.0f // would be cool if we have this define somewhere or GLSL do
#define QUANT_ERROR_ADMISSIBLE 1/1024

#define TEXTURE_SIZE 1024u
#define WORKGROUP_SIZE 256u
#define WORKGROUP_DIMENSION 16u

#endif // _COMMON_INCLUDED_
Loading