[英]Light and shadow not working in opengl and c++
我正在創建太陽能系統,我一直遇到照明問題。 第一個問題是月球在地球上沒有投射陰影,地球上沒有投射陰影。 另一個問題是,照在地球和月球上的光不是來自我的太陽,而是來自軌道的中心點。 我在下面的圖片中添加了紅線以顯示我的意思。
下面的圖片應該說明我的兩個問題。
這是處理燈光和行星的代碼。
glDisable(GL_LIGHTING);
drawCircle(800, 720, 1, 50);
//SUN
//Picture location, major radius, minor radius, major orbit, minor orbit, angle
Planet Sun ("/home/rodrtu/Desktop/SolarSystem/images/Sun.png",
100, 99, 200.0, 0.0, 0.0);
double sunOrbS = 0;
double sunRotS = rotatSpeed/10;
cout << sunRotS << " Sun Rotation" << endl;
//orbit speed, rotation speed, moon reference coordinates (Parent planet's major and minor Axis)
Sun.displayPlanet(sunOrbS, sunRotS, 0.0, 0.0);
//Orbit path
//EARTH
GLfloat light_diffuse[] = { 1.5, 1.5, 1.5, 1.5 };
GLfloat pos[] = { 0.0, 0.0, 0.0, 200.0 };
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, pos);
Planet Earth ("/home/rodrtu/Desktop/SolarSystem/images/EarthTopography.png",
50, 49, 500.0, 450.0, 23.5);
double eaOrbS = orbitSpeed;
double eaRotS = rotatSpeed*3;
Earth.displayPlanet(eaOrbS, eaRotS, 0.0, 0.0);
//EARTH'S MOON
Planet Moon ("/home/rodrtu/Desktop/SolarSystem/images/moonTest.png",
25, 23, 100.0, 100.0, 15);
double moOrbS = rotatSpeed*4;
double moRotS = eaOrbS;
Moon.displayPlanet(moOrbS, moRotS, Earth.getMajorAxis(), Earth.getMinorAxis());
orbitSpeed+=.9;
if (orbitSpeed > 359.0)
orbitSpeed = 0.0;
rotatSpeed+=2.0;
if (rotatSpeed > 7190.0)
rotatSpeed = 0.0;
下一個函數用於確定每個行星的軌道坐標和位置
void Planet::setOrbit(double orbitSpeed, double rotationSpeed,
double moonOrbitX, double moonOrbitY)
{
majorAxis = orbitSemiMajor * cos(orbitSpeed / 180.0 * Math::Constants<double>::pi);
minorAxis = orbitSemiMinor * sin(orbitSpeed / 180.0 * Math::Constants<double>::pi);
glTranslate(majorAxis+moonOrbitX, minorAxis+moonOrbitY, 0.0);
glRotatef(orbitAngle, 0.0, 1.0, 1.0);
glRotatef(rotationSpeed, 0.0, 0.0, 1.0);
}
void Planet::displayPlanet(double orbitSpeed,double rotationSpeed,
double moonOrbitX, double moonOrbitY)
{
GLuint surf;
Images::RGBImage surfaceImage;
surfaceImage=Images::readImageFile(texture);
glEnable(GL_TEXTURE_2D);
glGenTextures(0, &surf);
glBindTexture(GL_TEXTURE_2D, surf);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
surfaceImage.glTexImage2D(GL_TEXTURE_2D,0,GL_RGB);
glPushMatrix();
setOrbit(orbitSpeed,rotationSpeed, moonOrbitX, moonOrbitY);
drawSolidPlanet(equatRadius, polarRadius, 1, 40, 40);
glPopMatrix();
}
我究竟做錯了什么? 我讀到了GL_POSITION的w分量,我將我的位置改為200(太陽位於中心),但光源仍然來自軌道中心。
如果OpenGL沒有“投影”功能,我怎么能這樣做呢?
您必須了解的是,OpenGL沒有“場景”的概念。 所有OpenGL都是在屏幕上繪制點,線或三角形,一次一個。 繪制后,它對以下繪圖操作沒有影響。
所以要做一些像陰影一樣的東西,你必須得到,好吧, 藝術 。 我的意思是,就像一個畫了一幅塑料畫面的藝術家,畫面的深度只有“畫筆”和顏色調色板,你必須以藝術的方式使用OpenGL來重新創造你想要的效果。 繪制陰影可以通過各種方式完成。 但最受歡迎的一個是陰影映射術語。
陰影映射是一個兩步過程。 在第一步中,場景被渲染成從光的視點“看到”的“灰度”圖像,其中距光的距離被繪制為“灰色”值。 這稱為陰影深度圖 。
在第二步中,場景像往常一樣被繪制,其中燈光的陰影深度圖被投射到場景中,就像燈光是幻燈片投影儀一樣(其中所有內容都接收到該圖像,因為OpenGL沒有陰影)。 在着色器中,將陰影深度圖中的深度值與每個處理過的片段與光源的實際距離進行比較; 如果到光的距離比陰影貼圖中的相應像素更遠,這意味着在渲染陰影貼圖時,某些東西位於當前處理的幾何體片段前面,因此它位於陰影中,因此它以陰影顏色繪制(通常是環境照明顏色); 您可能希望將其與環境光遮擋效果結合使用,以模擬柔和的自陰影環境照明。
為輕型位置問題做出正確的回復..
[X, Y, Z, W]
稱為同質坐標
均勻空間中的坐標[X, Y, Z, W]
[X/W, Y/W, Z/W]
在3D空間中將是[X/W, Y/W, Z/W]
。
現在,考慮以下W值:
W=1.0
: [1.0, 1.0, 1.0, 1.0]
[1.0, 1.0, 1.0]
在3D位置是[1.0, 1.0, 1.0]
。 W=0.1
: [1.0, 1.0, 1.0, 0.1]
[10.0, 10.0, 10.0]
在3D位置為[10.0, 10.0, 10.0]
。 W=0.001
: [1.0, 1.0, 1.0, 0.001]
[1000.0, 1000.0, 1000.0]
在3D位置為[1000.0, 1000.0, 1000.0]
。 當我們繼續向W=0
移動時, [X/W, Y/W, Z/W]
值接近無窮遠處的點。 它實際上不再是一個點,而是從[0,0,0]
到[X,Y,Z]
。
因此,在定義燈光位置時,我們需要確保正確。
W=0
定義方向光,因此x,y,z是方向矢量 W=1
定義了位置光,因此x,y,z是3D空間中的位置 一旦深入挖掘矩陣數學,你就可以玩這個。 例如,如果您嘗試使用平移矩陣變換方向(W=0)
,則不會產生任何影響。 這在此非常相關,因為燈光位置將受到模型視圖矩陣的影響。
這里有一些易於理解的信息可供進一步閱讀: http : //www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.