2012-10-13 9 views
5

enter image description hereवायुमंडलीय बिखरने ओपन 3,3

इम वर्तमान संस्करण 330 के लिए शॉन ओ'नील द्वारा एक शेडर कन्वर्ट करने के लिए तो मैं यह एक आवेदन im लिखित रूप में की कोशिश कर सकते कोशिश कर रहा। मुझे बहिष्कृत कार्यों के साथ कुछ समस्याएं हैं, इसलिए मैंने उन्हें बदल दिया, लेकिन मैं लगभग पूरी तरह से glsl के लिए नया हूँ, इसलिए मैंने शायद कहीं गलती की थी।

मूल shaders यहां पाया जा सकता: 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

आप शेडर स्रोत कोड में वर्दी प्रारंभ कर सकते हैं। और जब आपके पास ग्लो 3.3 है तो आपको वर्दी – Arne

उत्तर

2

मुझे लगता है कि समस्या है, कि आप 'FragColor' को लिखते हैं, जो कि टुकड़े टुकड़े में 'मृत अंत' आउटपुट चर हो सकता है, क्योंकि प्रोग्राम को जोड़ने से पहले इसे स्पष्ट रूप से रंग संख्या में बांधना चाहिए:

glBindFragDataLocation(programAtmosphere,0,"FragColor");

या एक शेडर में इस का उपयोग करते हुए:

layout(location = 0) out vec4 FragColor

आप बाहर builtin उपयोग करने के लिए कोशिश कर सकते हैं वार्स बजाय: gl_FragColor, जो 0 के लिए एक उपनाम हैऔर इसलिए उपरोक्त बाध्यकारी जैसा ही है।

संपादित करें:

#version 330 compatibility

संपादित करें 2: भूल कहने के लिए, जब पदावनत builtins का उपयोग कर, आप एक अनुकूलता घोषणा होनी चाहिए बाध्यकारी परीक्षण करने के लिए, मैं करने के लिए यह करने के लिए एक निरंतर रंग लिखते हैं संभावित गणना त्रुटियों को अक्षम करें, क्योंकि इससे त्रुटियों या शून्य इनपुट की वजह से अपेक्षित परिणाम नहीं मिल सकते हैं।

+0

के लिए आर्ब कॉल की आवश्यकता नहीं है, धन्यवाद, जब मैं कंप्यूटर पर जाता हूं, तो मैं इसे करने की कोशिश करता हूं, जैसे ही मैंने इसका परीक्षण किया है, मैं जवाब दूंगा! – user1419305

+0

सवाल अपडेट किया गया! – user1419305

+0

ठीक है, मैंने इसे हल किया! 'ग्लूंट v3InvWavelength = glGetUniformLocation (प्रोग्राम वायुमंडल, "vInv तरंगदैर्ध्य");' 'ग्लूंट v3InvWavelength = glGetUniformLocation (प्रोग्राम वायुमंडल, "v3Inv तरंगदैर्ध्य") होना चाहिए;' – user1419305

संबंधित मुद्दे