參考資料:https://www.cnblogs.com/brainworld/p/7445290.html
https://blog.csdn.net/panda1234lee/article/details/51970893
1.首先,我們需要打開osg的渲染狀态節點osg::StateSet中對應的着色器模式。
osg::ref_ptr<osg::Program> program = new osg::Program;
mStateSet->setAttributeAndModes(program.get(),osg::StateAttribute::ON);
2.根據需要建立對應的osg着色器osg::Shader,并添加到osg::Program中。
osg::ref_ptr<osg::Shader> vertShader = new osg::Shader(osg::Shader::VERTEX, vertSource); //頂點着色器
osg::ref_ptr<osg::Shader> fragShader = new osg::Shader(osg::Shader::FRAGMENT, fragSource);//片元着色器
program->addShader(vertShader.get());
program->addShader(fragShader.get());
3.在對應的着色器中需要以字元的形式傳入着色器源碼char* vertSource,char* fragSource。
下面為實作Blinn-Phong光照模型例子。
//頂點着色器
static const char* vertSource = {
//"uniform vec3 LightPosition;\n"
"uniform vec3 EyePosition; \n"
//varying vec2 Texcoord;
"varying vec3 ViewDirection; \n"
//"varying vec3 LightDirection; \n"
"varying vec3 Normal; \n"
"void main(void)\n"
"{\n"
" gl_Position = ftransform(); \n"
//Texcoord = gl_MultiTexCoord0.xy;
" vec4 OPosition = gl_ModelViewMatrix * gl_Vertex; \n"
" ViewDirection = EyePosition - OPosition.xyz; \n"
//" LightDirection = LightPosition - OPosition.xyz; \n"
" Normal = gl_NormalMatrix * gl_Normal; \n"
"}\n"
};
//片元着色器
static const char* fragSource = {
"uniform vec4 LA;\n"
"uniform vec4 LD;\n"
"uniform vec4 LS;\n"
"uniform vec4 MA;\n"
"uniform vec4 MD;\n"
"uniform vec4 MS;\n"
"uniform float MfSpecularPower;\n"
"uniform vec3 LightDirection;\n"
//uniform sampler2D baseMap;
//varying vec2 Texcoord;
"varying vec3 ViewDirection;\n"
//"varying vec3 LightDirection;\n"
"varying vec3 Normal;\n"
"void main(void)\n"
"{\n"
" vec3 LightDir = normalize(LightDirection);\n"
" vec3 NormalDir = normalize(Normal);\n"
" vec3 ViewDir = normalize(ViewDirection);\n"
" vec3 HalfDir = normalize(LightDir + ViewDir);\n"
//vec3 ReDir = normalize(((2.0 * NormalDir) * fNDotL) - LightDir);
//vec4 fvBaseColor = texture2D(baseMap, Texcoord);
//
" vec4 TotalAmbient = LA * MA;\n"
//
" float fNDotL = dot(NormalDir, LightDir);\n"
" vec4 TotalDiffuse = LD * MD * fNDotL;\n"
//
" float fNDotH = max(0.0, dot(NormalDir, HalfDir));\n"
" vec4 TotalSpecular = LS * MS * (pow(fNDotH, MfSpecularPower));\n"
//
" gl_FragColor = (TotalAmbient + TotalDiffuse + TotalSpecular);\n"
"}\n"
};
4.在着色器源碼中定義了許多傳入參數,通過osg中osg::Uniform節點構造對應參數值并将其加入到osg::StateSet中。
// //光照參數
// osg::ref_ptr<osg::Uniform> LA = new osg::Uniform("LA", osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
// osg::ref_ptr<osg::Uniform> LD = new osg::Uniform("LD", osg::Vec4(0.6f, 0.6f, 0.6f, 1.0f));
// osg::ref_ptr<osg::Uniform> LS = new osg::Uniform("LS", osg::Vec4(0.6f, 0.6f, 0.6f, 1.0f));
//
// //材質參數。
// osg::ref_ptr<osg::Uniform> MA = new osg::Uniform("MA", mOsgcolor);
// osg::ref_ptr<osg::Uniform> MD = new osg::Uniform("MD", mOsgcolor);
// osg::ref_ptr<osg::Uniform> MS = new osg::Uniform("MS", osg::Vec4(0.8f, 0.8f, 0.8f, 1.0f));
// osg::ref_ptr<osg::Uniform> MfSpecularPower = new osg::Uniform("MfSpecularPower", 90.0f);
// mStateSet->addUniform(LA.get());
// mStateSet->addUniform(LD.get());
// mStateSet->addUniform(LS.get());
// mStateSet->addUniform(MA.get());
// mStateSet->addUniform(MD.get());
// mStateSet->addUniform(MS.get());
// mStateSet->addUniform(MfSpecularPower.get());