package org.pollux3d.glsl;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
public class NearIntersection {
/**
* @param args
*/
public static void main(String[] args) {
Vector3f v3Pos = new Vector3f(0,5,0);
Vector3f m_v3CameraPos = new Vector3f(20,0,0);
Vector3f m_v3LightPos = Vector3f.UNIT_X;
float m_fCameraHeight = 15f;
float m_fSamples = 3f;
float m_fInnerRadius = 5f;
float m_fOuterRadius = m_fInnerRadius * 1.025f;
float m_fCameraHeight2 = m_fCameraHeight * m_fCameraHeight;
float m_fOuterRadius2 = m_fOuterRadius * m_fOuterRadius;
float fInvScaleDepth = (1.0f / m_fScaleDepth);
float m_nSamples = 3f;
float m_fScale = 1.0f / ((m_fInnerRadius * 1.025f) - m_fInnerRadius);
float m_fScaleOverScaleDepth = m_fScale / m_fScaleDepth;
float m_v3InvWavelength = 0;
float m_fKr4PI = 0;
float m_fKm4PI = 0;
System.out.println(scale(0));
System.out.println(scale(1));
System.out.println(scale(2));
System.out.println(scale(3));
//vec3 v3Ray = v3Pos - m_v3CameraPos;
//float fFar = length(v3Ray);
//v3Ray /= fFar;
Vector3f v3Ray = v3Pos.subtract(m_v3CameraPos);
System.out.println("v3Ray: "+v3Ray);
float fFar = v3Ray.length();
System.out.println("fFar: "+fFar);
v3Ray.divideLocal(fFar);
System.out.println("v3Ray: "+v3Ray);
// Calculate the closest intersection of the ray with the outer atmosphere (which is the near point of the ray passing through the atmosphere)
// float fNear = getNearIntersection(m_v3CameraPos, v3Ray, m_fCameraHeight2, m_fOuterRadius2);
float fNear = getNearIntersection(m_v3CameraPos, v3Ray, m_fCameraHeight2, m_fOuterRadius2);
System.out.println("fNear: "+fNear);
// Calculate the ray's starting position, then calculate its scattering offset
// vec3 v3Start = m_v3CameraPos + v3Ray * fNear;
// fFar -= fNear;
Vector3f v3Start = m_v3CameraPos.add(v3Ray.mult(fNear));
System.out.println("v3Start: "+v3Start);
fFar -= fNear;
System.out.println("fFar: "+fFar);
// Calculate the ray's start and end positions in the atmosphere, then calculate its scattering offset
// float fStartAngle = dot(v3Ray, v3Start) / m_fOuterRadius;
// float fStartDepth = exp(-fInvScaleDepth);
// float fStartOffset = fStartDepth*scale(fStartAngle);
float fStartAngle = v3Ray.dot(v3Start) / m_fOuterRadius;
System.out.println("fStartAngle: "+fStartAngle);
float fStartDepth = FastMath.exp(-fInvScaleDepth);
System.out.println("fStartDepth: "+fStartDepth);
float fStartOffset = fStartDepth*scale(fStartAngle);
System.out.println("fStartOffset: "+fStartOffset);
// Initialize the scattering loop variables
// float fSampleLength = fFar / m_fSamples;
// float fScaledLength = fSampleLength * m_fScale;
// vec3 v3SampleRay = v3Ray * fSampleLength;
// vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;
float fSampleLength = fFar / m_fSamples;
System.out.println("fSampleLength: "+fSampleLength);
float fScaledLength = fSampleLength * m_fScale;
System.out.println("fScaledLength: "+fScaledLength);
Vector3f v3SampleRay = v3Ray.mult(fSampleLength);
System.out.println("v3SampleRay: "+v3SampleRay);
Vector3f v3SamplePoint = v3Start.add(v3SampleRay.mult(0.5f));
System.out.println("v3SamplePoint: "+v3SamplePoint);
// Now loop through the sample rays
/*
vec3 v3FrontColor = vec3(0.0, 0.0, 0.0);
for(int i=0; i<m_nSamples; i++)
{
float fHeight = length(v3SamplePoint);
float fDepth = exp(m_fScaleOverScaleDepth * (m_fInnerRadius - fHeight));
float fLightAngle = dot(m_v3LightPos, v3SamplePoint) / fHeight;
float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
float fScatter = (fStartOffset + fDepth*(scale(fLightAngle) - scale(fCameraAngle)));
vec3 v3Attenuate = exp(-fScatter * (m_v3InvWavelength * m_fKr4PI + m_fKm4PI));
v3FrontColor += v3Attenuate * (fDepth * fScaledLength);
v3SamplePoint += v3SampleRay;
}
*/
Vector3f v3FrontColor = Vector3f.ZERO;
for(int i=0; i<m_nSamples; i++) {
System.out.println("sample: "+i);
float fHeight = v3SamplePoint.length();
System.out.println("\tfHeight: "+fHeight);
float fDepth = FastMath.exp(m_fScaleOverScaleDepth * (m_fInnerRadius - fHeight));
System.out.println("\tfDepth: "+fDepth);
float fLightAngle = m_v3LightPos.dot(v3SamplePoint) / fHeight;
System.out.println("\tfLightAngle: "+fLightAngle);
float fCameraAngle = v3Ray.dot(v3SamplePoint) / fHeight;
System.out.println("\tfCameraAngle: "+fCameraAngle);
float fScatter = (fStartOffset + fDepth*(scale(fLightAngle) - scale(fCameraAngle)));
System.out.println("\tfScatter: "+fScatter);
float v3Attenuate = FastMath.exp(-fScatter * (m_v3InvWavelength * m_fKr4PI + m_fKm4PI));
System.out.println("\tv3Attenuate: "+v3Attenuate);
v3FrontColor.addLocal(new Vector3f(v3Attenuate,v3Attenuate,v3Attenuate));
v3SamplePoint.addLocal(v3SampleRay);
}
System.out.println("v3FrontColor: "+v3FrontColor);
System.out.println("v3SamplePoint: "+v3SamplePoint);
}
public static float getNearIntersection(Vector3f v3Pos, Vector3f v3Ray, float fDistance2, float fRadius2)
{
//float B = 2.0 * dot(v3Pos, v3Ray);
float B = 2.0f * v3Pos.dot(v3Ray);
System.out.println("B: "+B);
float C = fDistance2 - fRadius2;
System.out.println("C: "+C);
//float fDet = max(0.0, B*B - 4.0 * C);
float fDet = B*B - 4.0f * C;
if (fDet < 0f ) fDet = 0f;
System.out.println("fDet: "+fDet);
System.out.println("sqr fDet: "+FastMath.sqrt(fDet));
return 0.5f * (-B - FastMath.sqrt(fDet));
}
public static float m_fScaleDepth = 0.25f;
public static float scale(float fCos)
{
float x = 1.0f - fCos;
float preExp = -0.00287f + x*(0.459f + x*(3.83f + x*(-6.80f + x*5.25f)));
//System.out.println("preExp: "+preExp);
return m_fScaleDepth * FastMath.exp(preExp);
//return (float) (m_fScaleDepth * Math.exp(-0.00287f + x*(0.459f + x*(3.83f + x*(-6.80f + x*5.25f)))));
}
}