2012-10-13 50 views
5

enter image description here大氣散射的OpenGL 3.3

即時通訊目前試圖通過肖恩·奧尼爾的着色器轉換爲330版本,所以我可以嘗試一下在應用我寫。我有一些問題與棄用的功能,所以我取代了他們,但即時通訊幾乎全新的glsl,所以我可能做了一個錯誤的地方。

原始着色器可以在這裏找到: http://www.gamedev.net/topic/592043-solved-trying-to-use-atmospheric-scattering-oneill-2004-but-get-black-sphere/

我在將他們可怕的嘗試:

頂點着色器:

#version 330 core 

// Input vertex data, different for all executions of this shader. 
layout(location = 0) in vec3 vertexPosition_modelspace; 
layout(location = 2) in vec3 vertexNormal_modelspace; 



uniform vec3 v3CameraPos;  // The camera's current position 
uniform vec3 v3LightPos;  // The direction vector to the light source 
uniform vec3 v3InvWavelength; // 1/pow(wavelength, 4) for the red, green, and blue channels 
uniform float fCameraHeight; // The camera's current height 
uniform float fCameraHeight2; // fCameraHeight^2 
uniform float fOuterRadius;  // The outer (atmosphere) radius 
uniform float fOuterRadius2; // fOuterRadius^2 
uniform float fInnerRadius;  // The inner (planetary) radius 
uniform float fInnerRadius2; // fInnerRadius^2 
uniform float fKrESun;   // Kr * ESun 
uniform float fKmESun;   // Km * ESun 
uniform float fKr4PI;   // Kr * 4 * PI 
uniform float fKm4PI;   // Km * 4 * PI 
uniform float fScale;   // 1/(fOuterRadius - fInnerRadius) 
uniform float fScaleDepth;  // The scale depth (i.e. the altitude at which the atmosphere's average density is found) 
uniform float fScaleOverScaleDepth; // fScale/fScaleDepth 

const int nSamples = 2; 
const float fSamples = 2.0; 

invariant out vec3 v3Direction; 

// Values that stay constant for the whole mesh. 
uniform mat4 MVP; 
uniform mat4 V; 
uniform mat4 M; 
uniform vec3 LightPosition_worldspace; 



out vec4 dgl_SecondaryColor; 
out vec4 dgl_Color; 


float scale(float fCos) 
{ 
float x = 1.0 - fCos; 
return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25)))); 
} 


void main(void) 
{ 

    //gg_FrontColor = vec3(1.0, 0.0, 0.0); 
     //gg_FrontSecondaryColor = vec3(0.0, 1.0, 0.0); 

// Get the ray from the camera to the vertex, and its length (which is the far point of the ray passing through the atmosphere) 
vec3 v3Pos = vertexPosition_modelspace; 
vec3 v3Ray = v3Pos - v3CameraPos; 
float fFar = length(v3Ray); 
v3Ray /= fFar; 

// Calculate the ray's starting position, then calculate its scattering offset 
vec3 v3Start = v3CameraPos; 
float fHeight = length(v3Start); 
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fCameraHeight)); 
float fStartAngle = dot(v3Ray, v3Start)/fHeight; 
float fStartOffset = fDepth*scale(fStartAngle); 

// Initialize the scattering loop variables 
gl_FrontColor = vec4(0.0, 0.0, 0.0, 0.0); 
gl_FrontSecondaryColor = vec4(0.0, 0.0, 0.0, 0.0); 

float fSampleLength = fFar/fSamples; 
float fScaledLength = fSampleLength * fScale; 
vec3 v3SampleRay = v3Ray * fSampleLength; 
vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5; 

// Now loop through the sample rays 
vec3 v3FrontColor = vec3(0.2, 0.1, 0.0); 
for(int i=0; i<nSamples; i++) 
{ 
    float fHeight = length(v3SamplePoint); 
    float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight)); 
    float fLightAngle = dot(v3LightPos, v3SamplePoint)/fHeight; 
    float fCameraAngle = dot(v3Ray, v3SamplePoint)/fHeight; 
    float fScatter = (fStartOffset + fDepth*(scale(fLightAngle) - scale(fCameraAngle))); 
    vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI)); 
    v3FrontColor += v3Attenuate * (fDepth * fScaledLength); 
    v3SamplePoint += v3SampleRay; 
} 

// Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader 
gl_FrontSecondaryColor.rgb = v3FrontColor * fKmESun; 
gl_FrontColor.rgb = v3FrontColor * (v3InvWavelength * fKrESun); 
gl_Position = MVP * vec4(vertexPosition_modelspace,1); 
v3Direction = v3CameraPos - v3Pos; 

dgl_SecondaryColor = gl_FrontSecondaryColor; 
dgl_Color = gl_FrontColor; 


} 

片段着色器:

#version 330 core 

out vec4 dgl_FragColor; 

uniform vec3 v3LightPos; 
uniform float g; 
uniform float g2; 

invariant in vec3 v3Direction; 

in vec4 dgl_SecondaryColor; 
in vec4 dgl_Color; 


uniform mat4 MV; 

void main (void) 
{ 

float fCos = dot(v3LightPos, v3Direction)/length(v3Direction); 
float fMiePhase = 1.5 * ((1.0 - g2)/(2.0 + g2)) * (1.0 + fCos*fCos)/pow(1.0 + g2 - 2.0*g*fCos, 1.5); 
dgl_FragColor = dgl_Color + fMiePhase * dgl_SecondaryColor; 
dgl_FragColor.a = dgl_FragColor.b; 



} 

我寫的渲染球體的函數,以及即時通訊設法渲染這個着色器到它的反轉版本,球體運作完全正常,所有法線。我的問題是球體呈現全黑,所以着色器不工作。 編輯:得到太陽畫,但天空仍然全黑。

這就是我想如何渲染主渲染循環內的氣氛。

glUseProgram(programAtmosphere); 
    glBindTexture(GL_TEXTURE_2D, 0); 
    //###################### 


glUniform3f(v3CameraPos, getPlayerPos().x, getPlayerPos().y, getPlayerPos().z); 

glm::vec3 lightDirection = lightPos/length(lightPos); 

glUniform3f(v3LightPos, lightDirection.x , lightDirection.y, lightDirection.z); 

glUniform3f(v3InvWavelength, 1.0f/pow(0.650f, 4.0f), 1.0f/pow(0.570f, 4.0f), 1.0f/pow(0.475f, 4.0f)); 

glUniform1fARB(fCameraHeight, 10.0f+length(getPlayerPos())); 

glUniform1fARB(fCameraHeight2, (10.0f+length(getPlayerPos()))*(10.0f+length(getPlayerPos()))); 

glUniform1fARB(fInnerRadius, 10.0f); 

glUniform1fARB(fInnerRadius2, 100.0f); 

glUniform1fARB(fOuterRadius, 10.25f); 

glUniform1fARB(fOuterRadius2, 10.25f*10.25f); 

glUniform1fARB(fKrESun, 0.0025f * 20.0f); 

glUniform1fARB(fKmESun, 0.0015f * 20.0f); 

glUniform1fARB(fKr4PI, 0.0025f * 4.0f * 3.141592653f); 

glUniform1fARB(fKm4PI, 0.0015f * 4.0f * 3.141592653f); 

glUniform1fARB(fScale, 1.0f/0.25f); 


glUniform1fARB(fScaleDepth, 0.25f); 


glUniform1fARB(fScaleOverScaleDepth, 4.0f/0.25f); 


glUniform1fARB(g, -0.990f); 


glUniform1f(g2, -0.990f * -0.990f); 

任何想法?

編輯:更新了代碼,並添加了一張圖片。

+0

您可以初始化着色器源代碼中的制服。當你有gl 3.3,那麼你不需要任何arb呼叫制服 – Arne

回答

2

我認爲存在的問題是,您寫入'FragColor',它可能是片段着色器中的'死角'輸出變量,因爲在鏈接程序之前必須將其明確綁定到顏色編號:

glBindFragDataLocation(programAtmosphere,0,"FragColor");

或着色器使用此:

layout(location = 0) out vec4 FragColor

您可以嘗試使用內置了瓦爾代替:gl_FragColor,這是0別名因此與上面的綁定相同。

編輯:忘了說了,使用過時的內建命令時,你必須有一個兼容性聲明:

#version 330 compatibility

編輯2:爲了測試綁定,我會寫一個恆定的顏色給它禁用可能的計算錯誤,因爲這些錯誤或零輸入可能不會產生預期的結果。

+0

謝謝,即時我會去試試這個,當我到達電腦,我會盡快回復,一旦我測試出來! – user1419305

+0

更新了問題! – user1419305

+0

好的,我解決了它! 'GLuint v3InvWavelength = glGetUniformLocation(programAtmosphere,「vInvWavelength」);'應該是'GLuint v3InvWavelength = glGetUniformLocation(programAtmosphere,「v3InvWavelength」);' – user1419305