• Create Account

# Chimera 3D

Member Since 12 Jan 2011
Offline Last Active Apr 25 2015 03:10 PM

### Emulated Double Precision Subtraction & Division

22 March 2015 - 03:06 PM

Hi, I'm writing a shader which is using emulated double precision (stored as vec2 with high part as vec2.x and low part as vec2.y) as described here https://www.thasler.com/blog/blog/glsl-part2-emu which also fortunately had the functions for computing addition and multiplication with emulated doubles but not for subtraction and division which I also need. In the article the DSFUN90 library is mentioned as the source for the emulated double maths so I followed that link but I couldn't find where the author got their functions from. Afterwards I tried writing my own subtraction and division functions with no success. I imagine that subtraction is relatively simple but I have no idea how division would work.

Here's the addition and multiplication functions from the article (slightly modified):

```vec2 dAdd (vec2 doubleA, vec2 doubleB){

vec2 doubleResult;
float t1, t2, e;

t1 = doubleA.x + doubleB.x;
e = t1 - doubleA.x;
t2 = ((doubleB.x - e) + (doubleA.x - (t1 - e))) + doubleA.y + doubleB.y;

doubleResult.x = t1 + t2;
doubleResult.y = t2 - (doubleResult.x - t1);
return doubleResult;

}

vec2 dMul (vec2 doubleA, vec2 doubleB){

vec2 doubleResult;
float c11, c21, c2, e, t1, t2;
float a1, a2, b1, b2, cona, conb, split = 8193.0; //what is the significance of the split value?

cona = doubleA.x * split;
conb = doubleB.x * split;
a1 = cona - (cona - doubleA.x);
b1 = conb - (conb - doubleB.x);
a2 = doubleA.x - a1;
b2 = doubleB.x - b1;

c11 = doubleA.x * doubleB.x;
c21 = a2 * b2 + (a2 * b1 + (a1 * b2 + (a1 * b1 - c11)));

c2 = doubleA.x * doubleB.y + doubleA.y * doubleB.x;

t1 = c11 + c2;
e = t1 - c11;
t2 = doubleA.y * doubleB.y + ((c2 - e) + (c11 - (t1 - e))) + c21;

doubleResult.x = t1 + t2;
doubleResult.y = t2 - (doubleResult.x - t1);

return doubleResult;

}```

Can anyone explain what would be necessary for the subtraction and division functions?

### Atmospheric Scattering Errors

03 January 2015 - 09:42 AM

Hi, I've been playing around with Eric Bruneton's precomputed atmospheric scattering code and I've encountered a strange error that I simply cannot fix and I've checked and rechecked all of the code I'm using and it's pretty much identical to the original code but for some reason the atmosphere seems to be repeated from the top atmosphere boundary (Rt - in the original code) into space. I've been trying to find the cause of this error for many, many hours now and I have no idea what's causing it. Like I said my code is almost identical to Bruneton's (save for some different variable names) and I've checked my code to make sure that everything would supposedly work the same, here's a link to the original code. Here's a few screenshots of my problem.

In addition to the atmosphere repeating itself problem, there's also some strange errors when viewing the repeated atmosphere (only visible in space) at certain angles and the normal atmosphere from below the top atmosphere boundary and I have no idea what it is, hopefully they are part of the same problem though.

And finally here's my inscattering function which is mostly similar to the original code except for some different variable names and such but I've made sure none of my little modifications were the problem.

```float3 InscatteredLight (float3 camera, float3 surfacePos, out float3 attenuation, out float irradianceFactor){

float3 result;
float3 viewDir = surfacePos - camera;
float3 sunDir = SUN_DIR;
float pathLength = length(viewDir);
viewDir /= pathLength;

float startAlt = length(camera);
float muStart = dot(camera, viewDir) / startAlt;

float t = -startAlt * muStart - sqrt(startAlt * startAlt * (muStart * muStart - 1.0) + Rg * Rg);

float3 g = camera - float3(0.0, 0.0, Rg + 10.0);
float a = viewDir.x * viewDir.x + viewDir.y * viewDir.y - viewDir.z * viewDir.z;
float b = 2.0 * (g.x * viewDir.x + g.y * viewDir.y - g.z * viewDir.z);
float c = g.x * g.x + g.y * g.y - g.z * g.z;
float d = -(b + sqrt(b * b - 4.0 * a * c)) / (2.0 * a);
bool cone = d > 0.0 && abs(camera.z + d * viewDir.z - Rg) <= 10.0;

if (t > 0.0) {
if (cone && d < t) {
t = d;
}
} else if (cone) {
t = d;
}

t = pathLength; //this line seems to cause the secondary error I described, however it otherwise seems to improve the inscattering results, not the cause of the main error

float din = -startAlt * muStart - sqrt(startAlt * startAlt * (muStart * muStart - 1.0) + Rt * Rt);
if (din > 0.0) { // if x in space and ray intersects atmosphere
// move x to nearest intersection of ray with top atmosphere boundary
camera += din * viewDir;
t -= din;
muStart = (startAlt * muStart + din) / Rt;
startAlt = Rt;
}

if (startAlt <= Rt) { // if ray intersects atmosphere
float nu = dot(viewDir, sunDir);
float muS = dot(camera, sunDir) / startAlt;
float phaseR = PhaseFunctionR(nu);
float phaseM = PhaseFunctionM(nu);
float4 inscatter = max(Texture4D(_Inscatter, startAlt, muStart, muS, nu), 0.0);
if (t > 0.0) {
float3 x0 = surfacePos; //improves inscattering results, doesn't seem to cause any errors
float r0 = length(x0);
float rMu0 = dot(x0, viewDir);
float mu0 = rMu0 / r0;
float muS0 = dot(x0, sunDir) / r0;

// avoids imprecision problems in transmittance computations based on textures
attenuation = AnalyticTransmittance(startAlt, muStart, t);

if (r0 > Rg + 0.01) {
// computes S[L]-T(x,x0)S[L]|x0
if(r0 < Rt){
inscatter = max(inscatter - attenuation.rgbr * Texture4D(_Inscatter, r0, mu0, muS0, nu), 0.0);
}

// avoids imprecision problems near horizon by interpolating between two points above and below horizon
float muHorizon = -sqrt(1.0 - (Rg / startAlt) * (Rg / startAlt));
if (abs(muStart - muHorizon) < EPSILON_INSCATTER) {
float a = ((muStart - muHorizon) + EPSILON_INSCATTER) / (2.0 * EPSILON_INSCATTER);

float mu = muHorizon - EPSILON_INSCATTER;
r0 = sqrt(startAlt * startAlt + t * t + 2.0 * startAlt * t * mu);
mu0 = (startAlt * mu + t) / r0;
float4 inscatter0 = Texture4D(_Inscatter, startAlt, mu, muS, nu);
float4 inscatter1 = Texture4D(_Inscatter, r0, mu0, muS0, nu);
float4 inscatterA = max(inscatter0 - attenuation.rgbr * inscatter1, 0.0);

mu = muHorizon + EPSILON_INSCATTER;
r0 = sqrt(startAlt * startAlt + t * t + 2.0 * startAlt * t * mu);
mu0 = (startAlt * mu + t) / r0;
inscatter0 = Texture4D(_Inscatter, startAlt, mu, muS, nu);
inscatter1 = Texture4D(_Inscatter, r0, mu0, muS0, nu);
float4 inscatterB = max(inscatter0 - attenuation.rgbr * inscatter1, 0.0);

inscatter = lerp(inscatterA, inscatterB, a);
}
}
}

// avoids imprecision problems in Mie scattering when sun is below horizon
inscatter.w *= smoothstep(0.00, 0.02, muS);

result = max(inscatter.rgb * phaseR + GetMie(inscatter) * phaseM, 0.0);

} else { // camera in space and ray looking in space
result = float3(0,0,0);
attenuation = float3(1,1,1);
}

return result * SUN_INTENSITY;

}```

I'm pretty sure someone who knows the in's and out's of this algorithm more than I do can tell me what probably is causing the repeated atmosphere error since it's a pretty obvious problem. After doing some careful analysis of the code and maths involved I still wasn't able to figure what could be causing the problem, so I really just need someone to point out to me some possible causes and I should be on my way.

### Anybody got some ideas on how to do this?

10 March 2011 - 06:31 PM

Hello Everybody,
Our team is working on ( well not yet, we are still trying to build up our team and create a GDD ) a video game called Planet X. I'm not that much of a C++ programmer, but I specialize in most of the other fields. We decided to develop our own game engine. No need to tell me about all the work and stuff that goes into a game engine, and that we must first get the skd's to publish on consoles and all that stuff. Okay, for the engine we will implement a feature where the player could enter a planet's atmosphere ( from space ) and land on the planet in a realistic manner, without using pretty all of your computer's resources. Also we would like to have the ability to edit the planet's terrain features in the editor ( the engine's editor ). In order to simulate the scene realistically, we also would have to render the stars, clouds, sun, nearby planets, and space stations all at the same time without making the models look like they are made from one polygon with one shader! The game engine will be coded in C++ and using Direct 3D software development kit ( DirectX 11 ), Microsoft Visual Studio 2010, and would use the Havok physics engine for well, physics. Any help, assistance, advice ( again not, "that is too much you need to stop dreaming, that would take too long to create", and replies like that ), or help with finding a way to do this would be great.

I hate declaring variables!