Jump to content

DanW58

Community Members
  • Content Count

    417
  • Joined

  • Last visited

  • Days Won

    5

Everything posted by DanW58

  1. float getDiffuseEscapeFractionFromDielectric( float RI ) { float temp = (2.207 * RI) + (RI * RI) - 1.585; return 0.6217 / temp; } float getCosOfAvgReReflectionAngle( float RI ) { return (0.7012 * RI - 0.6062) / (RI - 0.4146); } // getLODbiasFromIR() will be used in ambient lighting. float getLODbiasFromIR( float IR ) //add 5 for 512; add 6 for 1024 cubes { float denominator = IR - 0.3472; float numerator = 0.1342 + (1.293*IR) - (0.123*IR*IR); return numerator / denominator; } void RealFresnel ( vec3 NdotL, vec3 IOR_RGB, out vec3 Frefl, inout vec3 sin_t, inout vec3 c
  2. Wait! What would be so wrong if we used the same diffuse correction factor for specularity? If we can't see some part of the terrain due to bump over-shadowing, it's no different whether the bounce is diffuse or specular. Let's try it and see what happens: We were talking about subtracting the sine of the mean roughness angle from NdotL. We'd want to do that when the sun is away from us, like on the other side of the object. When the sun is on our side of the object, such as behind us, we'd probably want to add the roughness angle to NdotL. Thus, NdotL += sqrt(1-0.5^(2/n))*(
  3. Let's see: NdotL is the cosine of the sun's angle to the normal. It is also the sine of the sun's angle to the un-roughened surface. If the sun's angle to the surface is small, the sine is roughly same value as the angle. If the sine of the sun's angle to the surface is comparable to the sine of mean surface angularity, the effect is the same as if the sun had an angle to surface that much lower. So we could just subtract the sine of the surface mean angle from the sun's NdotL, and that would have a similar effect to rotating the sun by the same angle. Right? We don't ev
  4. This is what I'm talking about: The effect of the sun's shading on an angular surface is the same as if the surface was flat but the sun was angled away from us by an angle equal to the very surface angularity. The normal here is irrelevant, I think... I now have to figure out how to implement this light vector rotation.
  5. Holly cow! I just remembered that 20 years ago I resolved this very problem, and it's just starting to come back how I did it ... It was in the context of planet rendering. Just a very vague memory ... I ended up scaling the angle of the sun as a function of roughness. A very angular surface caused the light source to move towards its horizon, or even fall behind it. Of course I wasn't moving the Sun itself; --not even the virtual one--; I mean for that pixel I was rendering, surface's mean angularity got added to the light vector's angle to the eye vector, I think it was, -
  6. Okay, I'm starting to see the light at the end of the tunnel... Okay, we are looking at a sphere. Our eyes are fixated on a point near the left horizon on the sphere. Now let's play with the Sun's position: If it is right behind us, it makes the bumpiness near the horizon of the sphere light up like phosphoro-cheese-cake. If it is right on the other side, or barely to the left of the sphere's horizon, it makes the far-side of the bumps light up, but our side of them is in darkness; so the net result is darkening. However, the effect is not symmetrical. Or, is it? I thi
  7. Could it simply be that this should be a function of the light vector, and NOT the eye vector? EDIT: Nope.
  8. No; that's not correct. I was only considering in the case of the light being on the other side, litting the back-faces. Should the light direction figure into this? Well, if the light is behind us, roughness at shallow angles will make the surface look MORE bright, not less; so yes, the light direction is important. In fact, this is why the full moon shades like a flat disk of cheese: It's the fact that it's not terribly smooth. Think, think, think ...
  9. Indeed. SpotRadius = arccos( 0.5^(1/n) ) In other words, cos(radius) = 0.5^(1/specpower); sin(x) = sqrt(1-cos(x)^2), so sin(x) = sqrt(1-0.5^(2/n)) Our dimming factor could be computed as PhongDF = clamp( dot(eyeVec, normal) / sqrt(1.0-pow(0.5, 2.0/specpower)); Thus, our full Pong function could look like this: float getPhongFactor(vec3 eyedotnormal, vec3 halfdotnormal, float SpecPower) { float FunnyNumber = pow(0.5, (1.0 / SpecPower)); float PhongDispersionFactor = 0.5 / ( 1.0 - FunnyNumber ); float PhongSelfOccludFactor = clamp(eye
  10. Phong sucks! Yes, I've said it. The way it is traditionally used in shaders is particularly retarded. People forget that the lower the spec power, and the wider the reflection spots, the more dispersed the reflection is, and therefore the less bright each pixel looks. The total light is invariant with spec power, but the per-pixel light needs to be adjusted for spread. But article after article on Phong shading fails to mention this. That's why I have a PhongDispersionFactor variable in the code of the last post. But there's more to the crappiness of Phong; and no; it's no
  11. Revised code to include Phong: float getDiffuseEscapeFractionFromDielectric( float RI ) { float temp = (2.207 * RI) + (RI * RI) - 1.585; return 0.6217 / temp; } float getCosOfAvgReReflectionAngle( float RI ) { return (0.7012 * RI - 0.6062) / (RI - 0.4146); } // getLODbiasFromIR() will be used in ambient lighting. float getLODbiasFromIR( float IR ) //add 5 for 512; add 6 for 1024 cubes { float denominator = IR - 0.3472; float numerator = 0.1342 + (1.293*IR) - (0.123*IR*IR); return numerator / denominator; } void RealFresnel ( vec3 NdotL, vec3 IOR_RGB, out vec3 Frefl,
  12. So, as I was saying, "...next stage in the pipeline would be the eyeVector Fresnel refraction modulation and Fresnel reflection modulated environment mapping, plus ambient. This next stage would also compute Phong." Oh, no! Another HUGE mistake ... Phong has to be computed per-light. So, our previous routine HAS to include Phong. Well, better to discover mistakes at this stage than to discover them at revision 42...
  13. I've just decided against testing this by itself. It is too difficult, given that nothing like this function exists in any of the current shaders, and therefore the interfaces are not there to plug this in. To plug this in I need to modify the existing code to conform to this model. But what is easier to do? Modify old code?, or write new code? Definitely the latter; so might as well complete the pipeline here, and test the whole thing. This function gives us reflectivity per light, excluding emerging fresnel modulation. The next stage in the pipeline would be the eyeVector Fre
  14. Coffee is having its desired effect. I just realized that indeed, the diffuse light coming out of a dielectric absolutely HAS to be modulated by Fresnel refractivity computed on the view vector. However: The emerging light figure that our unified formula yields is for total light going out. There are two ways we could proceed with this modulation: Compute a modulation that goes above and below 1.0 as to be neutral on a spherical average. Compute a standard refractive modulation, but have our universal formula scale the light back up so that it represents the maximum light c
  15. I knew this was a tough one; I tried hard to get anything to work; infinite thanks. And it works perfectly. float getLODbiasFromIR( float IR ) //add 5 for 512; add 6 for 1024 cubes { float denominator = IR - 0.3472; float numerator = 0.1342 + (1.293*IR) - (0.123*IR*IR); return numerator / denominator; } One subject not dealt with yet is rougness/smoothness, improving the Phong model, and how spec power and Fresnel combine. But I'm just waking up for now. EDIT: Spreadsheet updated: EDIT2: LOL, when someone complains "it's too dark", "it's too bri
  16. I've just been re-reading previous posts, thinking at times I had found faults with this idea of a combined diffuse and specular reflectivity function. Chief among my false "aha!" moments is every time I think about the fact that I'm going to need to call the Fresnel function again when I add environment mapping. But then the "aha!" becomes a "bah!" when I remember that the Fresnel I compute in this function is based on the light ray dot normal. In the case of the normalmap I will need to compute Fresnel again, yes, but based on eyeVector dot normal. Different animals. Also, let us not fo
  17. Actually, @nani if I can bother you one more time. I calculated roughly what LOD bias I need for fetching ambient light from an LOD skybox for the base layer to receive, under a dielectric. It is based not on 0.5*(1+escaperatio), but rather on sqrt(escaperatio); it makes a lot more sense. The number 2 on the table is arbitrary. If I have a 512 box, I have to add 5 to all the numbers. If I have a 1024 box I have to add 6 to all the numbers. Moving this to the 0~2 range might make it easier to fit a function to it. So, at a refractive index of 1, the entire sky is game, an AO equival
  18. Done! (But some secretive cabal out there has blown its cover for accusing me of "not doing anything productive" ... Figures!) void Reflectivity( float raydotnormal, vec3 RefractiveIndex, vec3 specColRGB, vec3 MatDiffuseRGB, out vec3 specularFactorRGB, out vec3 diffuseFactorRGB ) { vec3 FReflectivityRGB; vec3 sinRefrAngle; vec3 cosRefrAngle; RealFresnel( vec3(raydotnormal), RefractiveIndex, ReflectivityRGB, sinRefrAngle, cosRefrAngle ); vec3 FRefractivityRGB = WHITE-FReflectivityRGB; vec3 EscapeFraction = getDiffuseEscapeFractionFromDielectric( RefractiveIndex ); f
  19. Quoting myself, That's where we left off the specular case. I don't remember why I called this "FresnelSplit"; it should be called "DielectricOverMSpec()". Anyways, one thing to say is, I am not sure yet, in the case of dielectric over specular, when a specular power (smoothness) is specified, whether it applies to the metallic specularity underneath or to the dielectric surface above (or both). And necessity may force the choice... Thing is, roughness in the dielectric surface would affect the appearance of an ultra-smooth metallic reflector underneath by refraction.
  20. Here it is: float getDiffuseEscapeFractionFromDielectric( float RI ) { float temp = (2.207 * RI) + (RI * RI) - 1.585; return 0.6217 / temp; } float getCosOfAvgReReflectionAngle( float RI ) { return (0.7012 * RI - 0.6062) / (RI - 0.4146); } void RealFresnel ( vec3 NdotL, vec3 IOR_RGB, out vec3 Frefl, inout vec3 sin_t, inout vec3 cos_t ) { vec3 Z2 = WHITE / IOR_RGB; // Assumes n1 = 1 thus Z1 = 1. vec3 cos_i = NdotL; // assignnment for name's sake vec3 sin_i = sqrt( WHITE - cos_i*cos_i ); sin_t = min(WHITE, sin_i * Z2); // Outputs sin(
  21. In the repeating cycle, LightEscapingRGB = ExplodingRGBlight * EscapeFraction; diffuseFactorRGBacc += LightEscapingRGB; LightIncomingRGB = ExplodingRGBlight - LightEscapingRGB; ExplodingRGBlight = LightIncoming * cosAvgReflAngle * MatDiffuseRGB; LightEscapingRGB = ExplodingRGBlight * EscapeFraction; //..... all that matters to us is light escaping. The ratio of light escaping's for subsequent cycles is constant; we just have to work out what it is, now. The second line is just output to an accumulator. The third line is a bit of a problem, as it relies on the pr
  22. Okay, this is the whole thing put together now: const vec3 WHITE = vec3(1.0); const vec3 BLACK = vec3(0.0); float getDiffuseEscapeFractionFromDielectric( float RI ) { float temp = (2.207 * RI) + (RI * RI) - 1.585; return 0.6217 / temp; } float getCosOfAvgReReflectionAngle( float RI ) { return (0.7012 * RI - 0.6062) / (RI - 0.4146); } void RealFresnel( vec3 NdotL, vec3 IOR_RGB, out vec3 Frefl, inout vec3 sin_t, inout vec3 cos_t ) { vec3 Z2 = WHITE / IOR_RGB; // Assumes n1 = 1 thus Z1 = 1. vec3 cos_i = NdotL; // assignnment for name's sake vec3 sin_i
  23. Seems to be as good as my old beloved DataFit, which never thought would be surpassed or reached. It had whole families of forms of formulas to look for, like if you preferred a straight polynomial it tried that way, or if you didn't mind an inverse of a polynomial, or something with logs... you could pick and choose the type of formula you wanted, or just tell it to minimize computation costs, and it would go to work. Seems from what you found that matlab has similar capabilities.
  24. Many thanks, friend! EDIT: I would never have found that in a million years! EDIT2: ABSOLUTELY PERFECT!
  25. In fact, it is not important that it include refractive index of 1.0, as that will never be used. Instead, it would be more important that it include water's refractivity... refractive cos of average index reflect angle ========== =========== 1.335 (H2O) 0.3576 1.5 0.4115 2.0 0.5023 2.5 0.5494 3.0 0.5786 3.5 0.5985 4.0 0.6132 4.5 0.6242 5.0 0.6329 You might ask why ... Because this modeling of glossy paint is applicable to meters-thick dielectrics as muc
×
×
  • Create New...