Jump to content
• Advertisement # Silver Ray Studios

Member

45

130 Neutral

## About Silver Ray Studios

• Rank
Member
1. ## Emulated Double Precision Subtraction & Division

Yeah, what is the best way to do this considering I only have addition, subtraction, and multiplication (and division for some constants) to work with, is my question. EDIT: Nevermind I found an implementation of exactly what I needed here: http://andrewthall.org/papers/df64_qf128.pdf
2. ## Emulated Double Precision Subtraction & Division

Apologies for bumping this thread but I have another question, how could I go about implementing an emulated double precision exp function?
3. ## Emulated Double Precision Subtraction & Division

Oh, yeah that is really simple, but why wouldn't the low part of doubleB also be negative?
4. ## Emulated Double Precision Subtraction & Division

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?
5. ## Atmospheric Scattering Errors

Well I made the shader output muStart^2 (not at my computer atm so no screenshots) and it demonstrated similar behavior to the first image in the OP as muStart^2 starts out as white (near 1 or 1) towards the center of the planet and approaches 0 (black) towards the top atmosphere boundary then begins to approach 1 again from Rt out into space and after a certain distance (I'm guessing the startAlt), from either the center of the planet or the top atmosphere boundary, abruptly cuts off. So I'm pretty sure that's the ultimate cause of the repeating problem, still not sure why this isn't a problem in the original implementation as the computation of muStart and pretty much everything else is the same.
6. ## Atmospheric Scattering Errors

After finally getting around to fixing the errors I tried adding this bit of code to check if the "surfacePos" was not above the top atmosphere boundary when doing the multiple scattering and it removed the secondary error described above. if(r0 < Rt){ inscatter = max(inscatter - attenuation.rgbr * Texture4D(_Inscatter, r0, mu0, muS0, nu), 0.0); } I updated the code in the OP to reflect this change. As it turns out the atmosphere repeating error is not related to the other error shown in the last two screenshots, I haven't figured out exactly what's causing that yet. However if in the line: float din = -startAlt * muStart - sqrt(startAlt * startAlt * (muStart * muStart - 1.0) + Rt * Rt); I check if the input of the sqrt function is negative and if it is output a really large number it seems to fix the first problem.     But technically this isn't supposed to be necessary so I'm trying to figure why startAlt * startAlt * (muStart * muStart - 1.0) + Rt * Rt < 0 if startAlt > Rt and if muStart (assuming that this is the only value that could be negative if startAlt > Rt) being negative causes the repeat error.   After implementing the fix and sort-of-fix above I discovered some artifacts that seem to appear when viewing the atmosphere at a grazing angle (when the view direction [camera to surfacePos] is nearly perpendicular to the sun direction). Screens below.      Anybody know what could be causing this? Anyhow I'll post my final code once I get everything else resolved.   EDIT: Quickly realized that muStart being negative or positive doesn't matter so I guess only if muStart^2 -1 < 0 then that produces the error.
7. ## Atmospheric Scattering Errors

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.
• Advertisement
×

## Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!