RTRay RTRayTracer::genRefractRay(RTVector d, RTVector normal, RTVector closestPoint, double refractionIndex,bool isInside)
{

    double n,nt,ni;

    if(isInside) {
        ni=refractionIndex;
        nt=AIR_REFRA;
        normal=-normal;

    } else {
        ni=AIR_REFRA;
        nt=refractionIndex;
    }



    n = ni / nt;
    double cosI = -normal.dot(d);
    double sinT2 = n * n * (1.0 - cosI * cosI);

    if (sinT2 > 1.0) {
        exit(EXIT_FAILURE);
    }

    double cosT = sqrt(1.0 - sinT2);
    RTVector refracVector= d * n + normal * (n * cosI - cosT);



    double bias = 1e-4;
    RTVector ori = (closestPoint-normal)*bias;

    // RTVector ori=closestPoint;
    RTPoint vertice(ori.getX(),ori.getY(),ori.getZ());

    RTRay refracRay(vertice,refracVector);
    return refracRay;
}
Exemple #2
0
    bool Scene::traceRay(Ray& ray, RenderOption option, float refractiveIndex, int level, Color* acc, HitInfo* hitInfo)
    {
        if (level > kMaxTraceLevel) {
            return false;
        }
        *acc = kColorBlack;
        
        if (m_rootGroup->hit(ray, hitInfo)) {
            Vector3 hitPosition = hitInfo->position;
            Vector3 hitNormal = hitInfo->normal;
            MaterialRef hitMaterial = hitInfo->material;
            
            if (option & RenderMaterialAmbience) {
                Color materialColor;
                if (hitMaterial->texture()) {
                    materialColor = hitMaterial->texture()->texelAt(hitInfo->uv);
                } else {
                    materialColor = hitMaterial->color();
                }

                *acc += hitMaterial->ambient() * materialColor * (1.0f - hitMaterial->transparency());
            }
            
            for (unsigned int i = 0; i < m_lights.size(); i++) {
                LightRef light = m_lights[i];
                *acc += light->luminanceOfMaterialAt(*hitInfo, this, option) * (1.0f - hitMaterial->transparency());
                
                if (option & RenderReflection) {
                    if (hitMaterial->reflectivity() > 0.0f && level < kMaxTraceLevel) {
                        float reflection = 2.0 * ray.direction().dot(hitNormal);
                        Vector3 reflectionDirection = (ray.direction() - (hitNormal * reflection)).normalize();
                        Ray reflectedRay(hitPosition, reflectionDirection);
                        
                        HitInfo reflectionInfo;
                        Color reflectedColor = kColorBlack;
                        if (traceRay(reflectedRay, option, refractiveIndex, level + 1, &reflectedColor, &reflectionInfo)) {
                            reflectedColor = reflectedColor * hitMaterial->reflectivity();
                            *acc += reflectedColor * (1.0f - hitMaterial->transparency());
                        }
                    }
                }
                
                if (option & RenderTransparency) {
                    if (hitMaterial->transparency() > 0.0f && level < kMaxTraceLevel) {
                        float n = refractiveIndex / hitMaterial->refractiveIndex();
                        float cosA = -ray.direction().dot(hitNormal);
                        float cosB = sqrtf(1.0f - n * n * (1 - cosA * cosA));
                        if (cosB > 0.0f) {
                            Vector3 refracDirection = (n * ray.direction()) + (n * cosA - cosB) * hitNormal;
                            
                            Vector3 refracRayOrigin = hitPosition + refracDirection * EPSILON;
                            Ray refracRay(refracRayOrigin, refracDirection);
                            
                            HitInfo refracInfo;
                            Color refracColor = kColorBlack;
                            if (traceRay(refracRay, option, refractiveIndex, level + 1, &refracColor, &refracInfo)) {
                                refracColor = refracColor * hitMaterial->transparency();
                                Color absorbance = hitMaterial->color() * 0.15f * -refracInfo.distance;
                                Color transparency = Color(expf(absorbance.red), expf(absorbance.green), expf(absorbance.blue));
                                refracColor = refracColor * transparency;
                                *acc += refracColor;
                            }
                        }
                    }
                }
            }
        }
        
        
        return true;
    }