日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Spherical Harmonics Lighting的代码实现(基于OpenGL)

發布時間:2024/4/15 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spherical Harmonics Lighting的代码实现(基于OpenGL) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、二維空間的勒讓德多項式

勒讓德多項式定義在[-1,1]范圍內,其遞歸式是

下面這個函數的參數是給定的x,給定的l和m,其中l必須是正整數,而且m在[-l,l]范圍內。

//勒讓德多項式計算方法 double ALPStd(float x,int l,int m) {if(l==m)//doubleFactorial(x)計算x!!return (pow(-1,m)*doubleFactorial(2*m-1)*pow(sqrt(l-x*x),m));if(l==m+1)return (x*(2*m+1)*ALPStd(x,m,m));return ((x*(2*l-1)*ALPStd(x,l-1,m)-(l+m-1)*ALPStd(x,l-2,m))/(l-m)); } int doubleFactorial(int x) {int result;if(x==0 || x==-1)return 1;result=x;while((x-=2)>0)result*=x;return result; }

下面是利用勒讓德多項式進行繪制

void display() {glColor3f(r,v,b);glBegin(GL_LINE_STRIP);for(i=0;i<=samples,++i){glVertex2f(x,ALPStd(x,l,m));x+=step;}glEnd(); }

2、三維空間的Spherical Harmonics

在三維空間下繪制SH基函數,使用的是球坐標。

下面將會引進幾個函數

//計算整數的階乘,即x!=x*(x-1)*(x-2)*...*2*1 int factorial(int); //給定帶寬l和m,計算階乘因子K double evaluateK(int,int); //給定帶寬l和m,以及球坐標的兩個角度,計算SH基函數的值 double evaluateSH(int,int,double,double); int factorial(int x) {int result;if(x==0 || x==-1)return 1;result=x;while((x-=1)>0)result*=x;return result; }double evaluateK(int l,int m) {double result;result=(2.0*l+1.1)*factorial(l-m)/(4*PI*factorial(l+m));result=sqrt(result);return result; }double evaluateSH(int l,int m,double theta,double phi) {double SH=0.0;if(m==0)SH=evaluateK(l,0)*ALPStd(cos(theta),l,0);else if(m>0)SH=sqrt(2)*evaluateK(l,m)*cos(m*phi)*ALPStd(cos(theta),l,m);elseSH=sqrt(2)*evaluateK(l,-m)*sin(-m*phi)*ALPStd(cos(theta),l,-m);return SH; }

繪制SH的函數傳遞theta和phi值循環調用evaluateSH(),計算返回值,之后使用四邊形繪制網格。


3、使用SH基函數重構復合函數

我們已經創建了SH的基函數,現在要使用它們來重構一個給定的復合函數(也就是求出因子c),這個復合函數將會被用來描述光線在半球上的分布。

下面將會引進兩個函數。

//計算spherical stratified sampling sphericalStratifiedSampling(); //將輸入的函數投影到SH基上,即計算因子 SHProjectionSphericalFunction();

接下來還要定義一些數據結構。首先定義一個結構SHVector3d,容納向量或頂點的笛卡爾坐標;同樣定義一個結構,容納分層取樣(stratified sampling)的信息,即單位球坐標,樣品的三維坐標,和SH因子。

typedef struct {double x,y,z; }SHVector3d;typedef struct {SHVector3d sph;SHVector3d vec;double *coeff; }SHSample;void sphericalStratifiedSampling(SHSample* samples,int sqrtNumSamples, int nBands) {//Indexesint a,b,index,l,m;//Loop Indexint i=0;//Inverse of the number of samplesdouble invNumSamples=1.0/sqrtNumSamples;//Cartesian and spherical coordinatesdouble x,y,theta,phi;//Loop on width of gridfor(a=0;a<sqrtNumSamples,++a){//Loop on height of gridfor(b=0;b<sqrtNumSamples;++b){//jitter center of current cellx=(a+rnd())*invNumSamples;y=(b+rnd())*invNumSamples;//Calculate corresponding spherical anglestheta=2.0*acos(sqrt(1.0-x));phi=2.0*PI*y;//Sample spherical coordinatessamples[i].sph.x=theta;samples[i].shp.y=phi;samples[i].shp.z=1.0;//Sample normalsamples[i].vec.x=sin(theta)*cos(phi);samples[i].vec.y=sin(theta)*sin(phi);samples[i].vec.z=cos(theta);//Calculate SH coefficients of current samplefor(l=0;l<nBands;++l){for(m=-l;m<=l;++m){index=l*(l+1)+m;samples[i].coeff[index]=evaluateSH(l,m,theta,phi);}}++i;}} }//復合函數的定義 typedef double (*SphericalFunction)(double theta,double phi);void SHProjectSphericalFunction(SphericalFunction mySPFunc, SHSample* samples,double *result,int numSamples,int numCoeffs) {//Weighting factordouble dWeight=4.0*PI;double factor=dWeight/numSamples;//Spherical anglesdouble theta,phi;//Loop indexesint i,n;//Loop through all samplesfor(i=0;i<numSamples;++i){//Get current sample spherical coordinatestheta=samples[i].sph.x;phi=samples[i].sph.y;//Update SH coefficientsfor(n=0;n<numCoeffs;++n){result[n]+=mySPFunc(theta,phi)*samples[i].coeff[n];} }for(n=0;n<numCoeffs;++n)result[n]*=factor; }

轉載于:https://www.cnblogs.com/daniagger/archive/2012/05/31/2528754.html

總結

以上是生活随笔為你收集整理的Spherical Harmonics Lighting的代码实现(基于OpenGL)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。