| void main() |
| { |
| |
| osg::ref_ptr<osg::ShapeDrawable> sphere =new osg::ShapeDrawable; |
| sphere->setShape(new osg::Sphere(osg::Vec3(0,0,0),radius)); |
| sphere->setColor(osg::Vec4(col)); |
| |
| osg::ref_ptr<osg::Geode> pbrGeode =new osg::Geode; |
| pbrGeode->addChild(sphere); |
| |
| QVector<QString> paths={ |
| "height.png", |
| "metakkic.png", |
| "normal.png", |
| "roughness.png", |
| "albedo.png", |
| "ao.png"}; |
| for(int i=0;i<paths.size();i++) |
| { |
| osg::ref_ptr<osg::Texture2D> texture =new osg::Texture2D; |
| osg::ref_ptr<osg::Image> img =nullptr; |
| texture->setImage(img ); |
| pbrGeode->getOrcreateStateSet()->setTextureAttributeAndModes(i,texture); |
| auto num=("tex"+QString::number(i)).toStdString(); |
| pbrGeode->getOrcreateStateSet()->addUniform(new osg::Uniform(num.data(),(int)i)); |
| } |
| |
| static const char* vertCode="#version 330\n" |
| "layout(location =0) in vec3 Position;\n" |
| "layout(location =2) in vec3 Normal;\n" |
| "layout(location =8) in vec3 TexCoord;\n" |
| |
| "uniform mat4 osg_ModelViewProjectionMatrix;\n" |
| "uniform mat4 osg_ModelViewMatrix;\n" |
| "uniform mat4 osg_NormalMatrix;\n" |
| |
| "out vec3 vNormal;\n" |
| "out vec3 vCameraPos;\n" |
| "out vec3 vWorldPos;\n" |
| "out vec2 texCoord;\n" |
| |
| "void main()\n" |
| "{" |
| " texCoord=TexCoord;\n" |
| " vNormal=normalize(osg_NormalMatrix*vec4(Position,1.0));\n" |
| " gl_position=osg_ModelViewProjectionMatrix*vec4(Position,1.0);\n" |
| |
| " vCameraPos=inverse(osg_ModelViewMatrix)*vec4(0.0,0.0,0.0,1.0);\n" |
| " vWorldPos=Position;\n" |
| "}" |
| |
| static const char* fragCode="#version 330\n" |
| "uniform sampler2D tex0;\n" |
| "uniform sampler2D tex1;\n" |
| "uniform sampler2D tex2;\n" |
| "uniform sampler2D tex3;\n" |
| "uniform sampler2D tex4;\n" |
| "uniform sampler2D tex5;\n" |
| "uniform vec3 lightPos=vec3(100.0,0.0,100.0);\n" |
| "uniform vec3 lightCol=vec3(150.0,150.0,150.0);\n" |
| "in vec3 vNormal;\n" |
| "in vec3 vCameraPos;\n" |
| "in vec3 vWorldPos;\n" |
| "in vec2 texCoord;\n" |
| "out vec4 fragColor;\n" |
| |
| "vec3 fresnelSchlick(float cosTheta, vec3 F0)\n" |
| "{\n" |
| " return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);\n" |
| "}\n" |
| |
| "float distributionGGX(float NdotV, float roughness)\n" |
| "{\n" |
| " float a4 = roughness*roughness*roughness*roughness;\n" |
| " float NdotH = max(dot(N, H), 0.0);\n" |
| " float NdotH2 = NdotH*NdotH;\n" |
| " float denom = (NdotH2 * (a4 - 1.0) + 1.0);\n" |
| " denom = 3.1415 * denom * denom;\n" |
| " return a4 / denom;\n" |
| "}\n" |
| |
| "float geometrySchlickGGX(float NdotV, float roughness)\n" |
| "{\n" |
| " float k = ((roughness + 1.0)*(roughness + 1.0)) / 8.0;\n" |
| " float denom = NdotV * (1.0 - k) + k;\n" |
| " return NdotV / denom;\n" |
| "}\n" |
| |
| "float geometrySmith(float NdotV,float NdotL, float roughness)\n" |
| "{\n" |
| " float ggx2 = GeometrySchlickGGX(NdotV, roughness);\n" |
| " float ggx1 = GeometrySchlickGGX(NdotL, roughness);\n" |
| " return ggx1 * ggx2;\n" |
| "}\n" |
| |
| "vec3 tangToWorldMat()\n" |
| "{\n" |
| " vec3 tangentNormal = texture(tex2, texCoord).xyz * 2.0 - 1.0;\n" |
| " vec3 Q1 = dFdx(WorldPos);\n" |
| " vec3 Q2 = dFdy(WorldPos);\n" |
| " vec2 st1 = dFdx(texCoord);\n" |
| " vec2 st2 = dFdy(texCoord);\n" |
| " vec3 N = normalize(Normal);\n" |
| " vec3 T = normalize(Q1*st2.t - Q2*st1.t);\n" |
| " vec3 B = -normalize(cross(N, T));\n" |
| " mat3 TBN = mat3(T, B, N);\n" |
| " return normalize(TBN * tangentNormal);\n" |
| "}\n" |
| "void main()\n" |
| "{" |
| |
| " vec3 albdo=texture(tex4,texCoord).rgb;\n" |
| " float metalic=texture(tex1,texCoord).r;\n" |
| " float rough=texture(tex3,texCoord).r;\n" |
| " float ao=texture(tex5,texCoord).r;\n" |
| |
| " vec3 N=tangToWorldMat();\n" |
| " V=normailze(vCameraPos-vWorldPos);\n" |
| |
| " vec3 F0=vec3(0.4);\n" |
| " F0=mix(F0,albdo,metallic);\n" |
| " vec3 L=normailze(lightPos-vWorldPos);\n" |
| " vec3 H=normailze(V+L);\n" |
| " float distan=length(lightPos-vWorldPos);\n" |
| " float atten=200.0/(distan*distan);\n" |
| " vec3 radiance=lightCol*atten;\n" |
| " float NdotV=max(dot(N,V),0.0);\n" |
| " float NdotL=max(dot(N,L),0.0);\n" |
| " float NdotH=max(dot(N,H),0.0);\n" |
| " float HdotV=max(dot(H,V),0.0);\n" |
| |
| " float D=distributionGGX(NdotH,rough);\n" |
| " float G=geometrySmith(NdotV,NdotL,rough);\n" |
| " vec3 F=fresnelSchlick(HdotV,F0);\n" |
| " vec3 spec=D*F*G/(4.0*NdotV*NdotL+0.00001);\n" |
| " kD=(vec3(1.0)-F)*(1.0-metalic);\n" |
| " Lo=(kD*albdo/3.1415+spec)*radiance*NdotL;\n" |
| " vec3 ambient=vec3(1.0)*albdo*ao;\n" |
| " vec3 color=ambient+Lo;\n" |
| " fragColor=vec4(color,1.0);\n" |
| "}"; |
| |
| osg::ref_ptr<osg::Shader> vertShader=new osg::Shader(osg::Shader::VERT,vertCode); |
| osg::ref_ptr<osg::Shader> fragShader=new osg::Shader(osg::Shader::FRAG,fragCode); |
| osg::ref_ptr<osg::Program> program=new osg::Program; |
| program->addShader(vertShader); |
| program->addShader(fragShader); |
| pbrGeode->getOrCreateStateSet()->setAttributeAndModes(program,OVERRIDE_ON); |
| return pbrGeode; |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具