Commit dc7417ed authored by paps's avatar paps

Ajout de la methode de calcul du rayon refracté

la methode de cacul de la couleur par refraction n'est pas implementée a cause des modif sur getintersection
 (choisir la methode si on a le temps, avant j'utilisais un booleen mais sur ce projet il faut voir)
ajout de la methode naive pour la refraction lors du calcul des ombres
ajout d'un parametre pour les optic, l'indice de refraction necessaire au calcul du rayon refracté
Donc on peut faire de la refraction mais avec un seul rayon refracté en entrée d'un objet et pas de refraction en sorti
il faut aussi prendre en compte les reflexion totale pouvant survenir à l'interieur de l'objet 
parent d0762dfd
......@@ -76,11 +76,13 @@ void LrEntityElementary::pack(const LrMatrix &mat){
bool LrEntityElementary::getIntersection(const LrRay &ray, LrHit *hit,
Real minBound, Real maxBound) const
{
if (hit!=NULL)
hit->entity=(LrEntity*)this;
if (m_geometry->getIntersection(ray,hit,m_transf,m_transfInv,m_transfInvTransp,minBound,maxBound))
{
if (hit!=NULL)
{
hit->entity=(LrEntity*)this;
//hit->entity=(LrEntity*)this;
hit->optic=m_optic;
}
return true;
......@@ -94,11 +96,13 @@ bool LrEntityElementary::getIntersection(const LrRay &ray, LrHit *hit,
bool LrEntityElementary::getIntersection(const LrRay &ray, LrHit *hit, int fragment,
Real minBound, Real maxBound) const
{
if (hit!=NULL)
hit->entity=(LrEntity*)this;
if (m_geometry->getIntersection(ray,hit,fragment,m_transf,m_transfInv,m_transfInvTransp,minBound,maxBound))
{
if (hit!=NULL)
{
hit->entity=(LrEntity*)this;
//hit->entity=(LrEntity*)this;
hit->optic=m_optic;
}
return true;
......
......@@ -40,10 +40,10 @@ LrOpticBasic* LrOpticBasic::clone() const
return new LrOpticBasic(*this);
}
LrOpticBasic::LrOpticBasic(Real specular, Real diffuse, Real transparency,
LrPertColor *pertColor,LrPertNormal *pertNormal)
LrOpticBasic::LrOpticBasic(Real specular, Real diffuse, Real transparency, int refraction,
LrPertColor *pertColor,LrPertNormal *pertNormal)
:
LrOpticElementary(specular,diffuse,transparency,pertColor,pertNormal)
LrOpticElementary(specular,diffuse,transparency, refraction, pertColor,pertNormal)
{
}
......
......@@ -44,10 +44,12 @@ public:
* @param specular Real object reference.
* @param diffuse Real object reference.
* @param transparency Real object reference.
* @param refraction indice de refraction de l'objet (lié a la transparence)
* @param pertColor LrPertColor object pointer
* @param pertNormal LrPertNormal object pointer.
*/
LrOpticBasic(Real specular, Real diffuse, Real transparency, LrPertColor *pertColor,LrPertNormal *pertNormal);
LrOpticBasic(Real specular, Real diffuse, Real transparency, int refraction,
LrPertColor *pertColor,LrPertNormal *pertNormal);
/**
* @brief LrOpticBasic clone.
......
......@@ -43,18 +43,20 @@ LrOpticElementary::LrOpticElementary(const LrOpticElementary &source)
m_specular(source.m_specular),
m_diffuse(source.m_diffuse),
m_transparency(source.m_transparency),
m_refraction(source.m_refraction),
m_pertColor(source.m_pertColor),
m_pertNormal(source.m_pertNormal)
{
}
LrOpticElementary::LrOpticElementary(Real specular, Real diffuse, Real transparency,
LrOpticElementary::LrOpticElementary(Real specular, Real diffuse, Real transparency, int refraction,
LrPertColor *pertColor,LrPertNormal *pertNormal)
:
LrOptic(),
m_specular(specular),
m_diffuse(diffuse),
m_transparency(transparency),
m_refraction(refraction),
m_pertColor(pertColor),
m_pertNormal(pertNormal)
......@@ -79,6 +81,7 @@ LrOpticElementary& LrOpticElementary::operator = (const LrOpticElementary &sourc
m_specular = source.m_specular;
m_diffuse = source.m_diffuse;
m_transparency = source.m_transparency;
m_refraction = source.m_refraction;
m_pertColor = source.m_pertColor;
m_pertNormal = source.m_pertNormal;
......@@ -96,6 +99,7 @@ bool operator == (const LrOpticElementary &lhs, const LrOpticElementary &rhs)
&& (lhs.m_specular == rhs.m_specular)
&& (lhs.m_diffuse == rhs.m_diffuse)
&& (lhs.m_transparency == rhs.m_transparency)
&& (lhs.m_refraction == rhs.m_refraction)
&& (lhs.m_pertColor == rhs.m_pertColor)
&& (lhs.m_pertNormal == rhs.m_pertNormal);
}
......@@ -139,6 +143,16 @@ void LrOpticElementary::setTransparency(Real transparency)
m_transparency = transparency;
}
Real LrOpticElementary::getRefract(Real u, Real v) const
{
return m_refraction;
}
void LrOpticElementary::setRefract(int refraction)
{
m_refraction = refraction;
}
LrPertColor* LrOpticElementary::getPertColor(Real u, Real v, LrPoint &pointInter) const
{
return m_pertColor;
......
......@@ -45,10 +45,12 @@ public:
* @param specular Real object reference.
* @param diffuse Real object reference.
* @param transparency Real object reference.
* @param refraction indice de refraction de l'objet (lié a la transparence)
* @param pertColor LrPertColor object pointer
* @param pertNormal LrPertNormal object pointer.
*/
LrOpticElementary(Real specular, Real diffuse, Real transparency, LrPertColor *pertColor,LrPertNormal *pertNormal);
LrOpticElementary(Real specular, Real diffuse, Real transparency, int refraction,
LrPertColor *pertColor,LrPertNormal *pertNormal);
/**
......@@ -80,6 +82,9 @@ public:
virtual Real getTransparency(Real u, Real v) const;
virtual void setTransparency(Real transparency);
virtual Real getRefract(Real u, Real v) const;
virtual void setRefract(int refraction);
virtual LrPertColor* getPertColor(Real u, Real v, LrPoint &pointInter) const;
virtual void setPertColor(LrPertColor *color);
......@@ -93,6 +98,7 @@ protected:
Real m_specular; ///@brief Facteur de spécularité.
Real m_diffuse; ///@brief Facteur de diffusion.
Real m_transparency; ///@brief Facteur de transparence.
int m_refraction; ///@brief indice de refraction.
LrPertColor *m_pertColor; ///@brief La perturbation de couleur de l'optique.
LrPertNormal *m_pertNormal; ///@brief La perturbation de normal de l'optique.
......
......@@ -42,10 +42,10 @@ LrOpticPhong* LrOpticPhong::clone() const
return new LrOpticPhong(*this);
}
LrOpticPhong::LrOpticPhong(Real specular, Real diffuse, Real transparency,
LrPertColor *pertColor,LrPertNormal *pertNormal,int n)
LrOpticPhong::LrOpticPhong(Real specular, Real diffuse, Real transparency, int refraction,
LrPertColor *pertColor,LrPertNormal *pertNormal,int n)
:
LrOpticElementary(specular,diffuse,transparency,pertColor,pertNormal),
LrOpticElementary(specular,diffuse,transparency,refraction, pertColor,pertNormal),
m_n(n)
{
}
......
......@@ -42,12 +42,14 @@ public:
* @brief LrOpticPhong personnal constructor
* @param specular Real object reference.
* @param diffuse Real object reference.
* @param transparency Real object reference.
* @param transparency Real object reference.
* @param refraction indice de refraction de l'objet (lié a la transparence)
* @param pertColor LrPertColor object pointer
* @param pertNormal LrPertNormal object pointer.
* @param n int coef pour le calcul specularite
*/
LrOpticPhong(Real specular, Real diffuse, Real transparency, LrPertColor *pertColor,LrPertNormal *pertNormal,int n);
LrOpticPhong(Real specular, Real diffuse, Real transparency, int refraction,
LrPertColor *pertColor,LrPertNormal *pertNormal,int n);
/**
* @brief LrOpticPhong clone.
......
......@@ -22,6 +22,7 @@
#include "LrSceneRayTracing.h"
#include "LrOptic.h"
#include "LrOpticElementary.h"
// ############################################################################
......@@ -116,8 +117,6 @@ void LrSceneRayTracing::generateImagePart(int lOffset, int lNb)
{
for (int c = 0; c < m_image->getWidth(); c++)
{
LrColor pixel = LrColor::BLACK;
for (int i = 0; i < nbRayPerPixel; i++)
......@@ -227,14 +226,24 @@ LrColor LrSceneRayTracing::computeFromSource(const LrRay &ray, LrHit &hit)
if ((vectorLight*hit.normal) > 0.0f)
{
LrRay rayLight(vectorLight, tmpOrig);
if (m_binder->getIntersection(rayLight, NULL, 0.0f, dist) == false)
LrHit hitShadow;
if (m_binder->getIntersection(rayLight, &hitShadow, 0.0f, dist) == false)
{
colorTmp += (((LrEntityLight*)(*itObjs))->getColor())*
hit.optic->compute(rayLight,-ray.getDirection(),
hit.normal,hit.tangent,
hit.u,hit.v);
}
else
{
Real transp = hitShadow.optic->getTransparency(hitShadow.u, hitShadow.v);
if(transp > 0.0 )
{
LrColor optic = ((LrOpticElementary*)(hitShadow.optic))->getPertColor(hitShadow.u,
hitShadow.v, hitShadow.point)->getColor(hitShadow.u, hitShadow.v, hitShadow.point);
colorTmp += optic * (((LrEntityLight*)(*itObjs))->getColor()) * transp;
}
}
}
colorResult += colorTmp/nbRayOnLight;
}
......@@ -243,4 +252,38 @@ LrColor LrSceneRayTracing::computeFromSource(const LrRay &ray, LrHit &hit)
}
bool LrSceneRayTracing::getRefract(LrVector &refract, LrVector &dir, LrVector &normal,
Real milieu_1, Real milieu_2)
{
// Lois de Snell-Descartes :
//on a 2 milieux dans lequel se déplace un rayon, le fait de passer d'un milieu 1 à un milieu 2 provoque
//une réfraction du rayon qui est caractésisé par n1 sin 0_1 = n2 sin 0_2
//où n1 = le coeff de réfraction du milieu 1 et n2 celui du milieu 2
//0_1 = angle formé par le rayon incident et la normal
//0_2 = angle 0_1 au carré
//si n2 < n1 alors angle limite = arcsin (n2/n1) si angle d'incidence > angle limite alors reflexion total
//ou (n1 sin 0_1) / n2 = sin 0_2 et 0 <= sin 0_2 <= 1 et si sin 0_2 > 1 alors reflexion total
//equation du rayon T transmis :
//on pose n = n1/n2
// N = normal au point d'incidence
//R = rayon incident entrant
//T = (ncos (0_1) - cos (0_2))N - nR // -R pour mettre le rayon T dans la bonne direction
//T = (ncos (0_1) - SQRT(1 - (sin(0_2))²)) * N - nR
//T = (ncos (0_1) - SQRT(1 - n²(sin(0_2))²)) * N - nR
//T = (ncos (0_1) - SQRT(1 - n²(1 - cos(0_1)²)) * N - nR
//cos 0_1 = N * R
if(milieu_1 == milieu_2)
{
refract = dir;
return true;
}
Real n = milieu_1 / milieu_2; //n = n1 / n2
Real n_carre = n * n;
Real angle_milieu_1 = normal * dir;
Real angle_m1_carre = angle_milieu_1 * angle_milieu_1;
Real sin2 = n_carre * (1.0 - angle_m1_carre);
if(sin2 > 1.0) return false;
refract = (n * dir) - ((n * angle_milieu_1) + sqrt(1.0 - sin2)) * normal;
return true;
}
// ############################################################################
......@@ -115,6 +115,17 @@ private :
LrAntiAliasing *m_antialiasing;
//nombre de rebonds
int m_nbRebonds;
/**
* @brief calcul le rayon réfracté ou indique si il y a reflexion totale
* @param refract le vecteur de direction à calculer pour la réfraction
* @param dir le vecteur directeur du rayon incident au point d'impact
* @param normal la normale au point d'impact
* @param milieu_1 indice de réfraction du milieu sortant
* @param milieu_2 indice de réfraction du milieu entrant
* @return bool true si réfraction false si reflexion totale
*/
bool getRefract(LrVector &refract, LrVector &dir, LrVector &normal,
Real milieu_1, Real milieu_2);
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment