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 系列教程2 - Vertex Lighting

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

openGL CG 系列教程06 – Normal Mapping (法线贴图)

*原创文章,转载请注明出处* openGL CG 系列教程06 – Normal Mapping (法线贴图) Normal Mapping(法线贴图),不论是在游戏开发还是其他计算机图形开发中都是使...

Cg per-vertex lighting with texture

Shader "Custom/Cg per-vertex lighting with texture" {Properties { _MainTex ("Texture For Diffu...

罗大柚OpenGL ES教程系列LessonFour(Part X):rendering multiple objects with different texture

本文在GLKit框架下, 实现在一个OpenGL 场景中渲染多个对象,并为各个对象贴上不同的纹理。 这是许多OpenGL ES 新手感觉比较棘手的问题,大柚曾在stack overflow上多次看到有...

LIBGDX版NEHE OPENGL- 7. Texture Filters, Lighting & Keyboard Control

Libgdx的TextureFilter:   首先废话说一说“纹理映射的方式”,一个128*128的图片,在渲染的时候,很可能会被放到一个256*256的方形区域显示,也有可能放到64*64的方形...

OpenGL&CG技术之Render To Texture

使用OpenGL+CG语言,详细讲解了Render To Texture的过程

【OpenGL ES系列教程四】着色语言 Shading Language(二)

流程控制 OpenGL ES 着色语言提供了3种流程控制的方式,分别是if-else、while(do-while)循环、与for循环。这些控制语句的语法基本与Java一样,所以接受起来很简单。...

【OpenGL ES系列教程三】着色语言 Shading Language(一)

由于Android平台下的可编程图形硬件支持是 OpenGL ES 2.0标准,因此本教程向巴友们介绍 OpenGL ES着色语言。 OpenGL ES 着色语言是一种高级的图形编程语言。其源自于应用...

【OpenGL ES系列教程三】着色语言 Shading Language(一)

http://www.apkbus.com/blog-99192-39584.html 写在前面:(建议大家务必读完) 说实话,很不愿意写这两篇教程,很多人会觉得我的教程是教Ope...
  • jeffasd
  • jeffasd
  • 2016年08月31日 14:22
  • 653

MAC Cocoa Opengl入门系列教程一(基本图元绘制)

一.Opengl简单的介绍 1.opengl是什么东西?用它来干什么?也不是一两句话就能说的清楚,建议读者们先去百度搞清楚这些问题。 2.学opengl你要掌握什么知识? 答:首先你要对OpenGL感...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:openGL CG 系列教程4 - Lighting + Texture
举报原因:
原因补充:

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