|
|
最近由于gl默认光源总是出现莫名其妙的闪烁现象
我又死活解决不了
无奈只能使用其它办法
这段Cg脚本我费了很大劲才搞定……因为我完全不懂
不过无论如何,至少这个直接用就会有效果……当然需要显卡支持shader
当然不管再怎么适合初学者,有些参数还得使用者自己设置,例如
float shininess=20.0f;
float globalAmbient[]={0.1f, 0.1f, 0.1f};
float lightColor[]={0.9f, 0.9f, 0.9f};
float lightPosition[3];
float eyePosition[3];
这5个参数以及pixel_t.cg最后2行
相信大家都能看懂……
参考:http://www.azure.com.cn/article.asp?id=88
首先请去NV官方主页下载Cg toolkit,里面有需要的h和lib以及dll文件
申请全局变量,这一段放在程序开头:
CGprofile g_CGprofile_vertex;
CGprofile g_CGprofile_pixel;
CGcontext g_CGcontext;
CGprogram g_CGvertex_t;
CGprogram g_CGpixel_t;
//CGparameter g_CGparam_testTexture;
CGparameter cg_globalAmbient;
CGparameter cg_lightColor;
CGparameter cg_lightPosition;
CGparameter cg_eyePosition;
CGparameter cg_Ke;
CGparameter cg_Ka;
CGparameter cg_Kd;
CGparameter cg_Ks;
CGparameter cg_shininess;
float Ke[]={0.0f, 0.0f, 0.0f};
float Ka[]={1.0f, 1.0f, 1.0f};
float Kd[]={1.0f, 1.0f, 1.0f};
float Ks[]={1.0f, 1.0f, 1.0f};
float shininess=20.0f;
float globalAmbient[]={0.1f, 0.1f, 0.1f};
float lightColor[]={0.9f, 0.9f, 0.9f};
float lightPosition[3];
float eyePosition[3];
初始化Cg,如果是用nehe源代码来改的话,这一段放在Initialize或者InitGL里
if( cgGLIsProfileSupported(CG_PROFILE_ARBVP1) )
g_CGprofile_vertex = CG_PROFILE_ARBVP1;
else if( cgGLIsProfileSupported(CG_PROFILE_VP40) )
g_CGprofile_vertex = CG_PROFILE_VP40;
else
{
MessageBox( NULL,"Failed to initialize vertex shader! Hardware doesn't "
"support any of the required vertex shading extensions!",
"ERROR",MB_OK|MB_ICONEXCLAMATION );
return;
}
//
// Search for a valid pixel shader profile in this order:
//
// CG_PROFILE_ARBFP1 - GL_ARB_fragment_program
// CG_PROFILE_FP30 - GL_NV_fragment_program
// CG_PROFILE_FP20 - NV_texture_shader & NV_register_combiners
//
if( cgGLIsProfileSupported(CG_PROFILE_ARBFP1) )
g_CGprofile_pixel = CG_PROFILE_ARBFP1;
else if( cgGLIsProfileSupported(CG_PROFILE_FP30) )
g_CGprofile_pixel = CG_PROFILE_FP30;
else if( cgGLIsProfileSupported(CG_PROFILE_FP20) )
g_CGprofile_pixel = CG_PROFILE_FP20;
else
{
MessageBox( NULL,"Failed to initialize pixel shader! Hardware doesn't "
"support any of the required pixel shading extensions!",
"ERROR",MB_OK|MB_ICONEXCLAMATION );
return;
}
// Create the context...
g_CGcontext = cgCreateContext();
//
// Create the vertex and pixel shader...
//
g_CGvertex_t = cgCreateProgramFromFile( g_CGcontext,
CG_SOURCE,
"vertex_t.cg",
g_CGprofile_vertex,
NULL,
NULL );
g_CGpixel_t = cgCreateProgramFromFile( g_CGcontext,
CG_SOURCE,
"pixel_t.cg",
g_CGprofile_pixel,
NULL,
NULL );
//
// Load the programs using Cg's expanded interface...
//
cgGLLoadProgram( g_CGvertex_t );
cgGLLoadProgram( g_CGpixel_t );
下面这一段相当于开启光照
cgSetParameter3fv(cgGetNamedParameter( g_CGpixel_t, "globalAmbient" ), globalAmbient);
cgSetParameter3fv(cgGetNamedParameter( g_CGpixel_t, "lightColor" ), lightColor);
cgSetParameter3fv(cgGetNamedParameter( g_CGpixel_t, "lightPosition" ), lightPosition);
cgSetParameter3fv(cgGetNamedParameter( g_CGpixel_t, "eyePosition"), eyePosition);
cgSetParameter3fv(cgGetNamedParameter( g_CGpixel_t, "Ke" ), Ke);
cgSetParameter3fv(cgGetNamedParameter( g_CGpixel_t, "Ka" ), Ka);
cgSetParameter3fv(cgGetNamedParameter( g_CGpixel_t, "Kd" ), Kd);
cgSetParameter3fv(cgGetNamedParameter( g_CGpixel_t, "Ks" ), Ks);
cgSetParameter1f(cgGetNamedParameter( g_CGpixel_t, "shininess" ), shininess);
cgGLBindProgram( g_CGvertex_t );
cgGLEnableProfile( g_CGprofile_vertex );
cgGLBindProgram( g_CGpixel_t );
cgGLEnableProfile( g_CGprofile_pixel );
下面这一段相当于关闭光照
cgGLDisableProfile( g_CGprofile_pixel );
cgGLDisableProfile( g_CGprofile_vertex );
下面这一段保存为文件vertex_t.cg
//Vertex Shader
struct vertex
{
float4 position : POSITION;
float3 normal : NORMAL;
float4 color0 : COLOR0;
float2 texcoord0 : TEXCOORD0;
};
struct fragment
{
float4 position : POSITION;
float3 oNormal : TEXCOORD1;
float4 color0 : COLOR0;
float2 texcoord0 : TEXCOORD0;
float3 objectPos : TEXCOORD2;
};
// This binding semantic requires CG_PROFILE_ARBVP1 or higher.
uniform float4x4 modelViewProj : state.matrix.mvp;
fragment main( vertex IN )
{
fragment OUT;
OUT.position = mul( modelViewProj, IN.position );
OUT.color0 = IN.color0;
OUT.texcoord0 = IN.texcoord0;
OUT.oNormal = IN.normal;
OUT.objectPos = IN.position.xyz;
return OUT;
}
下面一段保存为文件pixel_t.cg
//Fragment Shader
// Note how the fragment struct was simply copied from our vertex shader code.
// This is necessary if we want to use a vertex and pixel shader together.
struct fragment
{
float4 position : POSITION;
float4 color0 : COLOR0;
float2 texcoord0 : TEXCOORD0;
float3 normal : TEXCOORD1;
float4 objectPos : TEXCOORD2;
};
struct pixel
{
float4 color : COLOR;
};
pixel main(
fragment IN,
uniform float3 globalAmbient,
uniform float3 lightColor,
uniform float3 lightPosition,
uniform float3 eyePosition,
uniform float3 Ke,
uniform float3 Ka,
uniform float3 Kd,
uniform float3 Ks,
uniform float shininess,
uniform sampler2D testTexture
)
{
float3 P = IN.position.xyz;
float3 N = normalize(IN.normal);
// Compute the emissive term
float3 emissive = Ke;
//Compute the ambient term
float3 ambient = Ka * globalAmbient;
//Compute the diffuse term
float3 L = normalize(lightPosition - P);
float diffuseLight = max(dot(N, L), 0);
float3 diffuse = Kd * lightColor * diffuseLight;
// Compute the specular term
float3 V = normalize(eyePosition - P);
float3 H = normalize(L + V);
float specularLight = pow(max(dot(N, H), 0), shininess);
if(diffuseLight<=0) specularLight=0;
float3 specular = Ks * lightColor * specularLight;
float4 Ocolor;
Ocolor.xyz = emissive + ambient + diffuse + specular;
Ocolor.w = 1;
pixel OUT;
OUT.color = tex2D( testTexture, IN.texcoord0 )+Ocolor*Ocolor-0.5;
return OUT;
}
默认效果并不好,不过修改起来也很简单
pixel_t.cg中的最后2行
OUT.color = tex2D( testTexture, IN.texcoord0 )+Ocolor*Ocolor-0.5;
在这行文本中
tex2D( testTexture, IN.texcoord0 )相当于原颜色
Ocolor相当于光线颜色
可以直接和小数加减乘除来配合比例
|
|