查看: 1310|回复: 1

一个opengl es2.0 大气着色器的问题

[复制链接]

该用户从未签到

发表于 2014-10-24 16:32:23 | 显示全部楼层 |阅读模式
本帖最后由 xuhaiyan8825 于 2014-10-24 16:34 编辑

此代码来源于oe,查看了es2.0 的shader规范,内置变量、变量个数等都符合要求,咋没效果,烦请知道的朋友解答一下。
效果如下,感觉是被剪裁了,先检查大气,再排查其他问题。
无标题.png


代码如下:
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";




该用户从未签到

 楼主| 发表于 2014-10-24 17:25:54 | 显示全部楼层
QQ截图20141024172348.png
相同代码在pc上执行是这样的。
在pc上,除了shader里面指定gl版本,还需要在外面强制使用es2.0吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表