示例#1
0
 public void ScatterPhoton(ShadingState state, Color power)
 {
     Color refr = Color.mul(1 - f0, color);
     Color refl = Color.mul(f0, color);
     float avgR = refl.getAverage();
     float avgT = refr.getAverage();
     double rnd = state.getRandom(0, 0, 1);
     if (rnd < avgR)
     {
         state.faceforward();
         // don't reflect internally
         if (state.isBehind())
             return;
         // photon is reflected
         float cos = state.getCosND();
         power.mul(refl).mul(1.0f / avgR);
         float dn = 2 * cos;
         Vector3 dir = new Vector3();
         dir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x;
         dir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y;
         dir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z;
         state.traceReflectionPhoton(new Ray(state.getPoint(), dir), power);
     }
     else if (rnd < avgR + avgT)
     {
         state.faceforward();
         // photon is refracted
         float cos = state.getCosND();
         float neta = state.isBehind() ? eta : 1.0f / eta;
         power.mul(refr).mul(1.0f / avgT);
         float wK = -neta;
         float arg = 1 - (neta * neta * (1 - (cos * cos)));
         Vector3 dir = new Vector3();
         if (state.isBehind() && absorptionDistance > 0)
         {
             // this ray is inside the object and leaving it
             // compute attenuation that occured along the ray
             power.mul(Color.mul(-state.getRay().getMax() / absorptionDistance, absorptionColor.copy().opposite()).exp());
         }
         if (arg < 0)
         {
             // TIR
             float dn = 2 * cos;
             dir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x;
             dir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y;
             dir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z;
             state.traceReflectionPhoton(new Ray(state.getPoint(), dir), power);
         }
         else
         {
             float nK = (neta * cos) - (float)Math.Sqrt(arg);
             dir.x = (-wK * state.getRay().dx) + (nK * state.getNormal().x);
             dir.y = (-wK * state.getRay().dy) + (nK * state.getNormal().y);
             dir.z = (-wK * state.getRay().dz) + (nK * state.getNormal().z);
             state.traceRefractionPhoton(new Ray(state.getPoint(), dir), power);
         }
     }
 }
示例#2
0
        public void ScatterPhoton(ShadingState state, Color power)
        {
            Color  refr = Color.mul(1 - f0, color);
            Color  refl = Color.mul(f0, color);
            float  avgR = refl.getAverage();
            float  avgT = refr.getAverage();
            double rnd  = state.getRandom(0, 0, 1);

            if (rnd < avgR)
            {
                state.faceforward();
                // don't reflect internally
                if (state.isBehind())
                {
                    return;
                }
                // photon is reflected
                float cos = state.getCosND();
                power.mul(refl).mul(1.0f / avgR);
                float   dn  = 2 * cos;
                Vector3 dir = new Vector3();
                dir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x;
                dir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y;
                dir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z;
                state.traceReflectionPhoton(new Ray(state.getPoint(), dir), power);
            }
            else if (rnd < avgR + avgT)
            {
                state.faceforward();
                // photon is refracted
                float cos  = state.getCosND();
                float neta = state.isBehind() ? eta : 1.0f / eta;
                power.mul(refr).mul(1.0f / avgT);
                float   wK  = -neta;
                float   arg = 1 - (neta * neta * (1 - (cos * cos)));
                Vector3 dir = new Vector3();
                if (state.isBehind() && absorptionDistance > 0)
                {
                    // this ray is inside the object and leaving it
                    // compute attenuation that occured along the ray
                    power.mul(Color.mul(-state.getRay().getMax() / absorptionDistance, absorptionColor.copy().opposite()).exp());
                }
                if (arg < 0)
                {
                    // TIR
                    float dn = 2 * cos;
                    dir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x;
                    dir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y;
                    dir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z;
                    state.traceReflectionPhoton(new Ray(state.getPoint(), dir), power);
                }
                else
                {
                    float nK = (neta * cos) - (float)Math.Sqrt(arg);
                    dir.x = (-wK * state.getRay().dx) + (nK * state.getNormal().x);
                    dir.y = (-wK * state.getRay().dy) + (nK * state.getNormal().y);
                    dir.z = (-wK * state.getRay().dz) + (nK * state.getNormal().z);
                    state.traceRefractionPhoton(new Ray(state.getPoint(), dir), power);
                }
            }
        }