more
This commit is contained in:
@@ -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"
|
||||
Reference in New Issue
Block a user