openGL CG 系列教程4 - Lighting + Texture

原创 2010年05月05日 19:38:00

*原创文章,转载请注明出处*

openGL CG 系列教程04 – Lighting + Texture

 

前几个教程详细的讲解了使用可编程渲染管线实现如何实现光照。如果我们要渲染的模型是带有纹理,要想带有纹理的模型也应用于光照又该怎样实现呢?有的同学可能知道,在openGL的固定管线也可以设置TextureEnvMode模式为GL_MODULATE就可以实现光照和纹理颜色的混合。下面我们就用Cg来实现这个功能。

 

整个程序将在教程03的基础上加上贴图来实现。为了使用贴图,首先要向vertex shader传入贴图坐标,然后再由vertex shader将贴图坐标传到fragment shader中。在vertex shader的入口函数简单的添加一个传入参数

 

float2 oTexCoord: TEXCOORD0

 

即可。float2 代表我们使用的2D贴图,语义TEXCOORD0表示将贴图坐标保存在第0个贴图坐标中。传入纹理坐标后,只需要直接将它传个fragment shader,于是我们在vertex shader的输出结构体中也要添加贴图坐标。

 

struct output

{

float4 position  : POSITION;

float2 TexCoord  : TEXCOORD0;    

float3 objectPos : TEXCOORD1;   

float3 normal    : TEXCOORD2;

};

 

上面的代码段中添加贴图坐标,其它的数据都是为了计算光照而传入fragment shader的。除了向fragment shader传入贴图坐标,还要把纹理数据传入到fragment shader中。由于纹理数据是个外部数据,我们使用uniform标识符来标识要传入的fragment shader的纹理数据。

 

uniform sampler2D Texture

 

这样向fragment shader传入了纹理坐标和纹理数据后,就可以使用Cg的内置函数tex2D来对每个像素的颜色进行插值,该函数会根据像素的坐标值在纹理数据中查询正确的颜色,然后返回。使用tex2D返回一个纹理的颜色值Ct,然后用Ct和前面通过光照计算得到的颜色值Cl通过混合操作即可。要实现GL_MODULATE的效果,可以简单的通过下面的公式

 

C= Ct Cl

A= At Al

 

这里C表示混合后像素的颜色的RGB分量,A表示混合后像素颜色的alpha分量。CtCl表示查询得到了纹理颜色的RGB分量和光照计算后像素颜色的RGB分量,AtAl当然就是它们对应的alpha分量了。颜色之间的“•”表示RGB颜色对应的RBG分量分别相乘。下面的图显示了这种混合的效果。

Lighting

+

Texture

=

Lighting+Texture

 

 

从中间的图中可以看到带有纹理的茶壶没有任何阴影,看起来没有真实感。但是加上光照后,镜面反射和阴影部分都在贴图中反映出来了。

 

下面是完整的vertex shaderfragment shader代码。

 

04vs.cg

struct output

{

      float4 position : POSITION;    

      float3 objectPos: TEXCOORD1;   

      float3 normal   : TEXCOORD2;

      float2 TexCoord : TEXCOORD0;

};

 

output vs_main( float4 position : POSITION,

                  float3 normal   : NORMAL,

                  float2 oTexCoord: TEXCOORD0,

                  uniform float4x4 MV,

                  uniform float4x4 MVP

                 )

{

      output OUT;

 

      OUT.position = mul(MVP, position);

      OUT.objectPos = mul(MV, position).xyz;

      OUT.normal = mul(MV, float4(normal,0.0)).xyz;

      OUT.TexCoord = oTexCoord;

 

      return OUT;

}

 

04fs.cg

uniform float3 LightPosition;

uniform float3 eyePosition;

uniform float3 I;

uniform float3 Ka;

uniform float3 Kd;

uniform float3 Ks;

uniform float shininess;

 

struct input

{

      float3 objectPos: TEXCOORD1;   

      float3 normal   : TEXCOORD2;

      float2 texCoord : TEXCOORD0;

};

 

struct output

{

      float4 color     : COLOR;

};

 

output fs_main( in input IN,

                  uniform sampler2D Texture)

{

      output OUT;

 

      float3 N = normalize(IN.normal);

      float3 P = IN.objectPos;

 

      float3 L = normalize(LightPosition - P);

      float NdotL = max(dot(N,L),0);

 

      float3 ambient = Ka * I;

      float3 diffuse = Kd * I * NdotL;

 

      float3 V = normalize(eyePosition - P);

      float3 H = normalize(L+V);

      float NdotH = pow(max(dot(N,H), 0), shininess);

 

      if(NdotL<=0)

           NdotH = 0.0;

      float3 specular = Ks*I*NdotH;

 

      float3 tex = tex2D(Texture, IN.texCoord).xyz;

      float3 light = ambient + diffuse + specular;

      OUT.color.xyz= light * tex;

      OUT.color.w = 1.0;

 

      return OUT;

}

 

可以看到整个vertex shaderfragment shader跟教程03中的代码几乎一样,唯一的差别就是多了传入贴图坐标,纹理和混合颜色三个部分。可编程渲染管线相当灵活,在fragment shader里完全可以根据需要进行不同类型的颜色插值和混合操作来得到不同的效果。

 

 

 

*原创文章,转载请注明出处*

OpenGL CG 系列教程1 - Hello CG

这篇教程将介绍如果在openGL中使用CG(C for Graphic)语言。想在程序中使用CG,首先要下载并安装 NVIDIA的Cg Toolkit。( http://developer.nvida...
  • thenile
  • thenile
  • 2013年04月27日 12:24
  • 1111

OpenGL&CG技术之Render To Texture

使用OpenGL+CG语言,详细讲解了Render To Texture的过程
  • i_dovelemon
  • i_dovelemon
  • 2015年12月26日 14:21
  • 3524

openGL CG 系列教程2 - Vertex Lighting

*原创文章,转载请注明出处*openGL CG 系列教程2vertex lighting 之前的一篇教程HelloCG介绍了Cg的一些最基本的东西。这篇教程将介绍利用可编程渲染管线来实现光照。光照模型...
  • zhangci226
  • zhangci226
  • 2010年04月28日 22:54
  • 5736

openGL CG 系列教程07 – Toon Shader

*原创文章,转载请注明出处*      openGL CG 系列教程07 – Toon Shader 这篇教程将介绍一种卡通渲染(Toon Shader)的方法,卡通渲染属于non photoreal...
  • zhangci226
  • zhangci226
  • 2010年05月15日 22:04
  • 5765

openGL CG 系列教程3-Pixel Lighting

*原创文章,转载请注明出处* openGL CG 系列教程3-Pixel Lighting 在上一篇教程中介绍了phong model下的一般光照,并且用Cg着色语言实现了固定渲染管线中gouraud...
  • zhangci226
  • zhangci226
  • 2010年04月30日 18:36
  • 4169

Cg per-vertex lighting with texture

Shader "Custom/Cg per-vertex lighting with texture" {Properties { _MainTex ("Texture For Diffu...
  • u012871784
  • u012871784
  • 2015年10月16日 11:30
  • 193

Cg per-pixel lighting with texture

Shader "Custom/Cg per-pixel lighting with texture" { Properties { _MainTex ("RGBA Texture For ...
  • u012871784
  • u012871784
  • 2015年10月16日 19:43
  • 134

【转】OpenGL CG系列教程2,vertex lighting

之前的一篇教程HelloCG介绍了Cg的一些最基本的东西。这篇教程将介绍利用可编程渲染管线来实现光照。光照模型将采用广泛应用的phong模型,虽然这种模型在openGL的固定管线中已经实现了,但是学习...
  • Ralfkaka
  • Ralfkaka
  • 2013年08月26日 11:31
  • 344

openGL CG4 - Lighting + Texture

前几个教程详细的讲解了使用可编程渲染管线实现如何实现光照。如果我们要渲染的模型是带有纹理,要想带有纹理的模型也应用于光照又该怎样实现呢?有的同学可能知道,在openGL的固定管线也可以设置Textur...
  • thenile
  • thenile
  • 2013年04月27日 12:32
  • 724

openGL CG 系列教程1 - Hello CG

 *原创文章,转载请注明出处*OpenGL CG 系列教程1  -  Hello CG 这篇教程将介绍如果在openGL中使用CG(C for Graphic)语言。想在程序中使用CG,首先要下载并安...
  • zhangci226
  • zhangci226
  • 2010年04月28日 19:46
  • 8910
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:openGL CG 系列教程4 - Lighting + Texture
举报原因:
原因补充:

(最多只允许输入30个字)