This commit is contained in:
Mathias Agopian
2024-10-18 23:35:24 -07:00
parent dcf51ba20e
commit cb9eba3b3e

View File

@@ -48,7 +48,7 @@ void RainbowGenerator::build(JobSystem& js) {
uint32_t const angleCount = mAngleCount;
float const n0 = indexOfRefraction(350);
float const n1 = indexOfRefraction(700);
float const minDeviation = 35*f::DEG_TO_RAD; //deviation(n0, maxIncidentAngle(n0)); // phi = 39.7
float const minDeviation = 30*f::DEG_TO_RAD; //deviation(n0, maxIncidentAngle(n0)); // phi = 39.7
float const maxDeviation = 60*f::DEG_TO_RAD; //deviation(n1, maxIncidentAngle(n1)); // phi = 42.5
std::cout << minDeviation * f::RAD_TO_DEG << std::endl;
std::cout << maxDeviation * f::RAD_TO_DEG << std::endl;
@@ -56,24 +56,37 @@ void RainbowGenerator::build(JobSystem& js) {
std::vector<float3> rainbow(angleCount, float3{});
// The sun appears as about half a degree in the sky
std::default_random_engine const rng{ std::random_device{}() };
std::uniform_real_distribution<float> const dist{ -f::DEG_TO_RAD * 0.25f, f::DEG_TO_RAD * 0.25f };
std::default_random_engine rng{ std::random_device{}() };
std::uniform_real_distribution<float> dist{ -f::DEG_TO_RAD * 0.5f, f::DEG_TO_RAD * 0.5f };
size_t count = 16384;
size_t count = 65536;
float const s = 2.0f * float(angleCount) / ((maxDeviation - minDeviation) * count * CIE_XYZ_COUNT);
for (size_t i = 0; i < count; i++) {
float const impact = (float(i) / count) * 2.0f - 1.0f;
radian_t const impactAngle = 0; //dist(rng);
radian_t const incident = std::asin(impact) - impactAngle;
for (size_t j = 0; j < CIE_XYZ_COUNT; j++) {
// Current wavelength
float const w = float(CIE_XYZ_START + j);
float const n = indexOfRefraction(w);
for (size_t j = 0; j < CIE_XYZ_COUNT; j++) {
// Current wavelength
float const w = float(CIE_XYZ_START + j);
float const n = indexOfRefraction(w);
for (size_t i = 0; i < count; i++) {
float const impact = (float(i) / count) * 2.0f - 1.0f;
radian_t const impactAngle = dist(rng);
radian_t const incident = std::asin(impact) - impactAngle;
radian_t const refracted = refract(n, incident);
// water-air fresnel is equal to 1 - air-water fresnel, so we only need to
// air-water non-polarized fresnel
float const F = fresnel(incident, refracted);
// intensity reflected upon entering the droplet (air-water)
float const Raw = fresnel(incident, refracted);
// intensity reflected upon exiting the droplet (water-air)
float const Rwa = fresnel(refracted, incident);
// intensity transmitted at air-water interface
float const Taw = 1 - Raw;
// intensity transmitted at water-air interface
float const Twa = 1 - Rwa;
for (int order = 0; order < 2; order++) {
float const internalBounces = float(order + 1);
@@ -82,7 +95,7 @@ void RainbowGenerator::build(JobSystem& js) {
size_t const index = (size_t)std::round(
((phi - minDeviation) / (maxDeviation - minDeviation)) * angleCount);
if (index < angleCount) {
float const T = (1 - F) * std::pow(1 - F, internalBounces) * F;
float const T = Taw * std::pow(Rwa, internalBounces) * Twa;
rainbow[index] += (T * s) * (CIE_XYZ[j] / 118.518f);
}
}
@@ -90,35 +103,23 @@ void RainbowGenerator::build(JobSystem& js) {
}
}
auto* image = tga_new(angleCount, 16 * 4);
auto* image = tga_new(angleCount, 32);
for (size_t index = 0; index < angleCount; index++) {
for (int i = 0; i < 4; i++) {
for (int y = 0; y < 16; y++) {
float3 c = rainbow[index];
c = XYZ_to_sRGB(c);
// float3 const sun = sRGB_to_linear(float3(255, 161, 72) / 255.0f);
// float3 const sky = sRGB_to_linear(float3(135, 206, 235) / 255.0f);
printf("vec3( %g, %g, %g ),\n", c.r, c.g, c.b);
float3 c;
if (i == 3) {
c = rainbow[index];
auto d = c;
d = linear_to_sRGB(XYZ_to_sRGB(d));
if (y == 0) std::cout << d.r << ", " << d.g << ", " << d.b << std::endl;
// if (y == 0) std::cout << d.r << std::endl;
} else {
c = float3{ i == 0, i == 1, i == 2 } * rainbow[index][i];
}
c = linear_to_sRGB(c*1075);
c = XYZ_to_sRGB(c);
c = linear_to_sRGB(c) * 56;// * sun*0.5 + sky*0.5);
uint3 const rgb = uint3(saturate(c) * 255);
tga_set_pixel(image, index, y+i*16, {
.b = (uint8_t)rgb.v[2],
.g = (uint8_t)rgb.v[1],
.r = (uint8_t)rgb.v[0]
});
}
}
uint3 const rgb = uint3(saturate(c) * 255);
for (int y=0;y<32;y++)
tga_set_pixel(image, index, y, {
.b = (uint8_t)rgb.v[2],
.g = (uint8_t)rgb.v[1],
.r = (uint8_t)rgb.v[0]
});
}
tga_write("toto.tga", image);
tga_free(image);
@@ -142,5 +143,17 @@ void RainbowGenerator::build(JobSystem& js) {
// };
//vec3 sun = frameUniforms.lightColorIntensity.rgb *
// (frameUniforms.lightColorIntensity.a * (4.0 * PI));
//vec3 direction = normalize(variable_eyeDirection.xyz);
//float cosAngle = dot(direction, -frameUniforms.lightDirection);
//float angle = acos(cosAngle) * 180.0 / 3.14159;
//float first = 35.0;
//float range = (60.0 - 35.0);
//float s = saturate((angle - first)/range);
//int index = int(s * 255);
//fragColor.rgb += rainbow[index]*sun;
#define TARGALIB_IMPLEMENTATION
#include "targa.h"