Гэрлийн үүсгүүрийн төрлүүд

Компютер графикт ерөнхий хэрэглэгддэг directional light, point light, spot light гэсэн гурван төрлийн гэрлийн үүсгүүрүүд байдаг.
directional, point, spot гэрэлүүд


Directional light
Энэ бол ганцхан чиглэлтэй байдаг мөртөө гэрлийн эх үүсвэр нь хязгааргүй хол оршин байдаг тийм төрлийн үүсгүүр юм, иймээс энэ төрлийн гэрлийн тооцоололд гэрлийн туяа гадаргуу дээр тусах үед эдгээр туяануудыг параллелиар авч үзэн тооцоолдог. directional light-ийн бодит жишээ гэвэл манай нар байна. directional light буюу чиглэлийн гэрэлд байрлал гэж байхгүй бөгөөд зөвхөн чиглэлийг илтгэсэн вектор л байна мөн гэрлийн эрч нь зайнаас хамааран сулардаггүй. Яагаад вэ гэвэл гэрлийг хязгааргүй хол зайд байгаа гэж үздэг болохоор тэр. Объектийг бүрдүүлж байгаа бүх оройнуудын хувьд гэрлийн чиглэл нь бүгд ижилхэн байна. Тиймээс тооцооллыг ганц удаа л хийхэд хангалттай. shader програмд гэрлийн чиглэлийг гэрлийн эх үүсвэрлүү чиглэсэн байдалтай буюу эсрэг чиглэлд тооцон авч үздэг. Ихэнхи тохиолдолд гэрлийн тооцооллыг view-огторгуй дотор тооцоолдог. Тиймээс гэрлийн чиглэлийг урьдчилан тооцон олж байгаад хэрэглэх нь тооцооллын нөөц хэмнэх үр ашигтай.
хаха ийм зураг тавьсанд уучлаарай гэхдээ энд
Directional Light хэрэглэсэн байна

// гэрлийн чиглэлийг diffuse intensity-г олохын тулд 
// бүх цэцэн оройнуудад ижилхэн хэрэглэнэ
float diffuseIntensity = max(dot(normal, lightDirection), 0.0);
float specularIntensity = 0.0;
if (diffuseIntensity > 0.0) {
    // Blinn-Phong ийн томъёог ашиглан specular intensity-г тооцон олох
    vec3 eyeDir = normalize(varEyeDir);
    vec3 halfwayVector = normalize(lightDirection + eyeDir);
    float specTmp = max(dot(normal, halfwayVector), 0.0);
    specularIntensity = pow(specTmp, cShininess);
}
float finalIntensity = ambientIntensity + (diffuseIntensity + specularIntensity) * pointLightIntensity;

Point Light
Энэ төрлийн гэрлийн эх үүсвэрт гэрлийн байрлал байдаг бөгөөд тэр байрлал дээрээсээ чиглэл бүрлүү гэрэл цацаргадаг. Зай холдох тусам гэрлийнх нь эрч буюу intensity утга нь буурч байдаг. Объектийн гадаргуу дээрхи дээр хүрч очих гэрлийн intensity утгыг нь дараах томъёогоор тооцон олдог.
энд d нь гэрлийн гадаргуу дээр туссан цэг болон тэндээс гэрлийн үүсгүүрийн байрлал хүртлэх зайн урт юм харин Kc, Kl, Kq утгууд нь харгалзан linear, quadratic, attenuation тогтмолууд юм. attenuation гэдэг нь гэрлийн шингэлт буюу сулрах зэргийг нь илтгэнэ.

Эдгээр объектүүдийн сүүдрийг хараарай, дунд нь Point Light
тал бүрнээ гэрэл цацаргаж байна


// light.position ийг view-огторгуй дотор тодорхойлж өгсөн байх хэрэгтэй
vec3 pointToLightVector = light.position - vec3(modelViewPos);

// гэрлийн чиглэлийн нормчилсон векторыг аваад гадаргуу дээрхи цэгээс гэрлийн байрлал хүртлэх 
// зайг нь олох
vec3 lightDirection = normalize(pointToLightVector);
float lightDist = length(pointToLightVector);

// diffuse intensity
float diffuseIntensity = max(dot(normal, lightDirection), 0.0);

float specularIntensity = 0.0;
float pointLightIntensity = 0.0;

if(diffuseIntensity > 0.0)
{
    // point light intensity
    pointLightIntensity = 1.0 / (light.att.x + light.att.y * lightDist + light.att.z * lightDist * lightDist);
        
    // specular intensity ийг Blinn-Phong ийн томъёо ашиглаж олох
    vec3 eyeDir = normalize(varEyeDir);
    vec3 halfwayVector = normalize(lightDirection + eyeDir);
    float specTmp = max(dot(normal, halfwayVector), 0.0);
    specularIntensity = pow(specTmp, cShininess);
}
    
float finalIntensity = ambientIntensity + (diffuseIntensity + specularIntensity) * pointLightIntensity;


Spot Light
энэ төрлийн гэрэл нь өмнөх point light-тай ижилхэн гэхдээ конус дүрсний хүрээнд гэрлээ цацаргадаг. Иймээс энэ төрлийн гэрлийг ашигласнаар дурын чиглэлдээ гэрэл цацаргах бололцоо бүрддэг. Хамгийн ойрын жишээ гэвэл гар чийдэн байна. Объектийн гадаргуу дээр туссан гэрлийн intensity-г дараах томъёогоор тооцож олдог.
энд r бол spot light-ийн гэрэл тусгаж байгаа чиглэл, l бол объектийн гадаргуу дээрхи цэгээс гэрлийн эх үүсвэр тийш чиглэсэн вектор, p бол spot light-ийн гэрэл хэр хэмжээний орцтойгоор гэрлийн тооцоололд оролцохыг илтгэсэн зэрэгт дэвшүүлэгч утга, бусад утгууд нь point light дээр хэрэглэж байсантай ижилхэн.

энэ дунд Майкл Жексон ах шиг саран алхаагаар
алхмаар санагдчихлаа :D


vec3 pointToLightVector = light.position - vec3(modelViewPos);

vec3 lightDirection = normalize(pointToLightVector);
float lightDist = length(pointToLightVector);

float diffuseIntensity = max(dot(normal, lightDirection), 0.0);

float specularIntensity = 0.0;
float pointLightIntensity = 0.0;

if(diffuseIntensity > 0.0)
{
    // spot light intensity
    // spotlight гэрлийн чиглэлийн эсрэг чиглэл болон гадаргуугаас гэрлийн байрлал хүртэл чиглэсэн
    // вектор хоёрын хоорондох өнцөгийг авах
    float spotValue = dot(normalize(-light.spotDirection), normalize(lightDirection));
    
    // хэрэв өнцөг нь хангалттай хэмжээнд байвал гэрлийг харуулна
    if (spotValue > light.spotCutoffAngle)
    {
        // spotlight-ийн орцыг тохируулах
        spotValue = pow(spotValue, light.spotExponent);
            
        // энэ хэсэг нь point light дээр хийгдэж байсантай ижилхэн
        pointLightIntensity = 1.0 / (light.attenuationFactors.x + light.attenuationFactors.y * distanceToLight 
                                      + light.attenuationFactors.z * distanceToLight * distanceToLight);
        pointLightIntensity *= spotValue;
    }
        
    // Blinn-Phong ийн томъёо хэрэглэн specular intensity утгыг тооцож олох
    vec3 eyeDir = normalize(varEyeDir);
    vec3 halfwayVector = normalize(lightDirection + eyeDir);
    float specTmp = max(dot(normal, halfwayVector), 0.0);
    specularIntensity = pow(specTmp, cShininess);
}
    
float finalIntensity = ambientIntensity + (diffuseIntensity + specularIntensity) * pointLightIntensity;

Popular posts from this blog

Apache Spark + Cassandra. Hello World