|
本帖最后由 xuhaiyan8825 于 2014-10-24 16:34 编辑
此代码来源于oe,查看了es2.0 的shader规范,内置变量、变量个数等都符合要求,咋没效果,烦请知道的朋友解答一下。
效果如下,感觉是被剪裁了,先检查大气,再排查其他问题。
代码如下:
osg::StateSet* set = geode->getOrCreateStateSet();
// configure the state set:
set->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
set->setMode( GL_CULL_FACE, osg::StateAttribute::ON );
set->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
//set->setBinNumber( 65 ); // todo, what?
set->setBinNumber( BIN_ATMOSPHERE );
//set->setAttributeAndModes( new osg::CullFace(osg::CullFace::BACK), osg::StateAttribute::ON );
set->setAttributeAndModes( new osg:epth( osg::Depth:ESS, 0, 1, false ) ); // no depth write
set->setAttributeAndModes( new osg::BlendFunc( GL_ONE, GL_ONE ), osg::StateAttribute::ON );
set->setAttributeAndModes( new osg::FrontFace( osg::FrontFace::CLOCKWISE ), osg::StateAttribute::ON );
// next, create and add the shaders:
osg:rogram* program = new osg::Program();
osg::Shader* vs = new osg::Shader( osg::Shader::VERTEX, s_atmosphereVertexSource );
program->addShader( vs );
osg::Shader* fs = new osg::Shader( osg::Shader::FRAGMENT, s_atmosphereFragmentSource );
program->addShader( fs );
set->setAttributeAndModes( program, osg::StateAttribute::ON );
set->getOrCreateUniform( "atmos_v3LightDir", osg::Uniform::FLOAT_VEC3 )->set( _defaultPerViewData._lightPos / _defaultPerViewData._lightPos.length() );
set->getOrCreateUniform( "oe_mode_GL_LIGHTING", osg::Uniform::BOOL )->set( true );
set->getOrCreateUniform( "atmos_v3InvWavelength", osg::Uniform::FLOAT_VEC3 )->set( RGB_wl );
set->getOrCreateUniform( "atmos_fInnerRadius", osg::Uniform::FLOAT )->set( _innerRadius );
set->getOrCreateUniform( "atmos_fInnerRadius2", osg::Uniform::FLOAT )->set( _innerRadius * _innerRadius );
set->getOrCreateUniform( "atmos_fOuterRadius", osg::Uniform::FLOAT )->set( _outerRadius );
set->getOrCreateUniform( "atmos_fOuterRadius2", osg::Uniform::FLOAT )->set( _outerRadius * _outerRadius );
set->getOrCreateUniform( "atmos_fKrESun", osg::Uniform::FLOAT )->set( Kr * ESun );
set->getOrCreateUniform( "atmos_fKmESun", osg::Uniform::FLOAT )->set( Km * ESun );
set->getOrCreateUniform( "atmos_fKr4PI", osg::Uniform::FLOAT )->set( Kr4PI );
set->getOrCreateUniform( "atmos_fKm4PI", osg::Uniform::FLOAT )->set( Km4PI );
set->getOrCreateUniform( "atmos_fScale", osg::Uniform::FLOAT )->set( Scale );
set->getOrCreateUniform( "atmos_fScaleDepth", osg::Uniform::FLOAT )->set( RayleighScaleDepth );
set->getOrCreateUniform( "atmos_fScaleOverScaleDepth", osg::Uniform::FLOAT )->set( Scale / RayleighScaleDepth );
set->getOrCreateUniform( "atmos_g", osg::Uniform::FLOAT )->set( MPhase );
set->getOrCreateUniform( "atmos_g2", osg::Uniform::FLOAT )->set( MPhase * MPhase );
set->getOrCreateUniform( "atmos_nSamples", osg::Uniform::INT )->set( Samples );
set->getOrCreateUniform( "atmos_fSamples", osg::Uniform::FLOAT )->set( (float)Samples );
set->getOrCreateUniform( "atmos_fWeather", osg::Uniform::FLOAT )->set( Weather );
# define GLSL_VERSION_STR "100"
# define GLSL_DEFAULT_PRECISION_FLOAT "precision mediump float;"
static char s_atmosphereVertexSource[] =
"#version " GLSL_VERSION_STR "\n"
GLSL_DEFAULT_PRECISION_FLOAT "\n"
"uniform mat4 osg_ViewMatrixInverse; // camera position in [3].xyz\n"
"uniform vec3 atmos_v3LightDir; // The direction vector to the light source \n"
"uniform vec3 atmos_v3InvWavelength; // 1 / pow(wavelength,4) for the rgb channels \n"
"uniform float atmos_fOuterRadius; // Outer atmosphere radius \n"
"uniform float atmos_fOuterRadius2; // fOuterRadius^2 \n"
"uniform float atmos_fInnerRadius; // Inner planetary radius \n"
"uniform float atmos_fInnerRadius2; // fInnerRadius^2 \n"
"uniform float atmos_fKrESun; // Kr * ESun \n"
"uniform float atmos_fKmESun; // Km * ESun \n"
"uniform float atmos_fKr4PI; // Kr * 4 * PI \n"
"uniform float atmos_fKm4PI; // Km * 4 * PI \n"
"uniform float atmos_fScale; // 1 / (fOuterRadius - fInnerRadius) \n"
"uniform float atmos_fScaleDepth; // The scale depth \n"
"uniform float atmos_fScaleOverScaleDepth; // fScale / fScaleDepth \n"
"uniform int atmos_nSamples; \n"
"uniform float atmos_fSamples; \n"
"varying vec3 atmos_v3Direction; \n"
"varying vec3 atmos_mieColor; \n"
"varying vec3 atmos_rayleighColor; \n"
"vec3 vVec; \n"
"float atmos_fCameraHeight; // The camera's current height \n"
"float atmos_fCameraHeight2; // fCameraHeight^2 \n"
"float atmos_fastpow(in float x, in float y) \n"
"{ \n"
" return x/(x+y-y*x); \n"
"} \n"
"float atmos_scale(float fCos) \n"
"{ \n"
" float x = 1.0 - fCos; \n"
" return atmos_fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25)))); \n"
"} \n"
"void atmos_SkyFromSpace(void) \n"
"{ \n"
" // Get the ray from the camera to the vertex and its length (which is the far point of the ray passing through the atmosphere) \n"
" vec3 v3Pos = gl_Vertex.xyz; \n"
" vec3 v3Ray = v3Pos - vVec; \n"
" float fFar = length(v3Ray); \n"
" v3Ray /= fFar; \n"
" // Calculate the closest intersection of the ray with the outer atmosphere \n"
" // (which is the near point of the ray passing through the atmosphere) \n"
" float B = 2.0 * dot(vVec, v3Ray); \n"
" float C = atmos_fCameraHeight2 - atmos_fOuterRadius2; \n"
" float fDet = max(0.0, B*B - 4.0 * C); \n"
" float fNear = 0.5 * (-B - sqrt(fDet)); \n"
" // Calculate the ray's starting position, then calculate its scattering offset \n"
" vec3 v3Start = vVec + v3Ray * fNear; \n"
" fFar -= fNear; \n"
" float fStartAngle = dot(v3Ray, v3Start) / atmos_fOuterRadius; \n"
" float fStartDepth = exp(-1.0 / atmos_fScaleDepth); \n"
" float fStartOffset = fStartDepth*atmos_scale(fStartAngle); \n"
" // Initialize the atmos_ing loop variables \n"
" float fSampleLength = fFar / atmos_fSamples; \n"
" float fScaledLength = fSampleLength * atmos_fScale; \n"
" vec3 v3SampleRay = v3Ray * fSampleLength; \n"
" vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5; \n"
" // Now loop through the sample rays \n"
" vec3 v3FrontColor = vec3(0.0, 0.0, 0.0); \n"
" vec3 v3Attenuate; \n"
" for(int i=0; i<atmos_nSamples; i++) \n"
" { \n"
" float fHeight = length(v3SamplePoint); \n"
" float fDepth = exp(atmos_fScaleOverScaleDepth * (atmos_fInnerRadius - fHeight)); \n"
" float fLightAngle = dot(atmos_v3LightDir, v3SamplePoint) / fHeight; \n"
" float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight; \n"
" float fscatter = (fStartOffset + fDepth*(atmos_scale(fLightAngle) - atmos_scale(fCameraAngle))); \n"
" v3Attenuate = exp(-fscatter * (atmos_v3InvWavelength * atmos_fKr4PI + atmos_fKm4PI)); \n"
" v3FrontColor += v3Attenuate * (fDepth * fScaledLength); \n"
" v3SamplePoint += v3SampleRay; \n"
" } \n"
" // Finally, scale the Mie and Rayleigh colors and set up the varying \n"
" // variables for the pixel shader \n"
" atmos_mieColor = v3FrontColor * atmos_fKmESun; \n"
" atmos_rayleighColor = v3FrontColor * (atmos_v3InvWavelength * atmos_fKrESun); \n"
" atmos_v3Direction = vVec - v3Pos; \n"
"} \n"
"void atmos_SkyFromAtmosphere(void) \n"
"{ \n"
" // Get the ray from the camera to the vertex, and its length (which is the far \n"
" // point of the ray passing through the atmosphere) \n"
" vec3 v3Pos = gl_Vertex.xyz; \n"
" vec3 v3Ray = v3Pos - vVec; \n"
" float fFar = length(v3Ray); \n"
" v3Ray /= fFar; \n"
" // Calculate the ray's starting position, then calculate its atmos_ing offset \n"
" vec3 v3Start = vVec; \n"
" float fHeight = length(v3Start); \n"
" float fDepth = exp(atmos_fScaleOverScaleDepth * (atmos_fInnerRadius - atmos_fCameraHeight)); \n"
" float fStartAngle = dot(v3Ray, v3Start) / fHeight; \n"
" float fStartOffset = fDepth*atmos_scale(fStartAngle); \n"
" // Initialize the atmos_ing loop variables \n"
" float fSampleLength = fFar / atmos_fSamples; \n"
" float fScaledLength = fSampleLength * atmos_fScale; \n"
" vec3 v3SampleRay = v3Ray * fSampleLength; \n"
" vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5; \n"
" // Now loop through the sample rays \n"
" vec3 v3FrontColor = vec3(0.0, 0.0, 0.0); \n"
" vec3 v3Attenuate; \n"
" for(int i=0; i<atmos_nSamples; i++) \n"
" { \n"
" float fHeight = length(v3SamplePoint); \n"
" float fDepth = exp(atmos_fScaleOverScaleDepth * (atmos_fInnerRadius - fHeight)); \n"
" float fLightAngle = dot(atmos_v3LightDir, v3SamplePoint) / fHeight; \n"
" float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight; \n"
" float fscatter = (fStartOffset + fDepth*(atmos_scale(fLightAngle) - atmos_scale(fCameraAngle))); \n"
" v3Attenuate = exp(-fscatter * (atmos_v3InvWavelength * atmos_fKr4PI + atmos_fKm4PI)); \n"
" v3FrontColor += v3Attenuate * (fDepth * fScaledLength); \n"
" v3SamplePoint += v3SampleRay; \n"
" } \n"
" // Finally, scale the Mie and Rayleigh colors and set up the varying \n"
" // variables for the pixel shader \n"
" atmos_mieColor = v3FrontColor * atmos_fKmESun; \n"
" atmos_rayleighColor = v3FrontColor * (atmos_v3InvWavelength * atmos_fKrESun); \n"
" atmos_v3Direction = vVec - v3Pos; \n"
"} \n"
"void main(void) \n"
"{ \n"
" // Get camera position and height \n"
" vVec = osg_ViewMatrixInverse[3].xyz; \n"
" atmos_fCameraHeight = length(vVec); \n"
" atmos_fCameraHeight2 = atmos_fCameraHeight*atmos_fCameraHeight; \n"
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; \n"
" if(atmos_fCameraHeight >= atmos_fOuterRadius) \n"
" { \n"
" atmos_SkyFromSpace(); \n"
" } \n"
" else { \n"
" atmos_SkyFromAtmosphere(); \n"
" } \n"
"} \n";
static char s_atmosphereFragmentSource[] =
"#version " GLSL_VERSION_STR "\n"
GLSL_DEFAULT_PRECISION_FLOAT "\n"
"uniform vec3 atmos_v3LightDir; \n"
"uniform float atmos_g; \n"
"uniform float atmos_g2; \n"
"uniform float atmos_fWeather; \n"
"varying vec3 atmos_v3Direction; \n"
"varying vec3 atmos_mieColor; \n"
"varying vec3 atmos_rayleighColor; \n"
"const float fExposure = 4.0; \n"
"float atmos_fastpow(in float x, in float y) \n"
"{ \n"
" return x/(x+y-y*x); \n"
"} \n"
"void main(void) \n"
"{ \n"
" float fCos = dot(atmos_v3LightDir, atmos_v3Direction) / length(atmos_v3Direction); \n"
" float fRayleighPhase = 1.0; \n" // 0.75 * (1.0 + fCos*fCos); \n"
" float fMiePhase = 1.5 * ((1.0 - atmos_g2) / (2.0 + atmos_g2)) * (1.0 + fCos*fCos) / atmos_fastpow(1.0 + atmos_g2 - 2.0*atmos_g*fCos, 1.5); \n"
" vec3 f4Color = fRayleighPhase * atmos_rayleighColor + fMiePhase * atmos_mieColor; \n"
" vec3 skyColor = 1.0 - exp(f4Color * -fExposure); \n"
" gl_FragColor.rgb = skyColor.rgb*atmos_fWeather; \n"
" gl_FragColor.a = (skyColor.r+skyColor.g+skyColor.b) * 2.0; \n"
"} \n";
|
|