游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2655|回复: 8

[求助]各位帮忙看一眼这个Shader

[复制链接]

12

主题

38

帖子

38

积分

注册会员

Rank: 2

积分
38
发表于 2005-5-11 10:22:00 | 显示全部楼层 |阅读模式
还是过程纹理

如下:
float4 Light_Glos( float2 UV : POSITION ) : COLOR
// UV.x = N dot toL, UV.y = N dot H;
{
        float4 col = (float4)0;
        col.r = saturate( UV.x );
        col.g = saturate( pow( UV.y, 24) );
       
        return col;
}
这是计算光照的过程纹理,其中入口参数UV是前面计算出来的 N*L 和 N*H,计算结果将Diffuse光照放到返回值的 r 分量,高光亮度放到 g 分量。

下面是在 PixelShader 中使用该纹理的过程,其中L和H都是在VertexShader中的计算结果
LH0.x = saturate( dot( nor, normalize( L ) ) ); //Normal * L( tangent space )
LH0.y = saturate( dot( nor, normalize( H ) ) ); //Normal * H
float2 glos = tex2D ( sGlosMap, LH0 ).rg;

问题在于:如果不使用过程纹理,直接在 PixelShader 中进行光照计算,如下:
float2 glos;
glos.r = LH0.x;
glos.g = pow( LH0.y, 24 );
二者效果相差甚远,而且明显感觉到后者的结果是正确的。



[em7]帮帮忙吧

20

主题

473

帖子

502

积分

高级会员

Rank: 4

积分
502
发表于 2005-5-11 20:30:00 | 显示全部楼层

Re:[求助]各位帮忙看一眼这个Shader

如果只是做高光lookup的话,可以不用在lookup贴图中保留和处理漫射部分
而且,LH0.y = saturate( dot( nor, normalize( H ) ) ); //Normal * H
这里的normalize是可以省略的
方法是在lookup function 里改为:

float speclevel = saturate(pow((UV.x / sqrt(UV.y)), 24));
col= float4(speclevel,speclevel ,speclevel ,speclevel );

然后再ps里采样的时候,U使用N.H, V使用H.H
这样采样出来的值就是归一化后的(N.H)^24了

因为你没有放图出来,所以不清楚你所谓的效果相差很远具体什么意思
上面我也只是说了我自己的做法,不知道有用否

2

主题

85

帖子

85

积分

注册会员

Rank: 2

积分
85
发表于 2005-5-11 22:39:00 | 显示全部楼层

Re:[求助]各位帮忙看一眼这个Shader

H必须normalize,楼主是正确的

我不太清楚pass0(计算纹理)的vs是什么样子的,但是让我奇怪的是UV的semantic怎么会是POSITION。按理说POSITION在完成转换后的坐标。x,y的范围是-1~1, 而只有x,y>0的时候才有光照。这样一来你生成的纹理就有三个象限是全黑的( 噢,还不是,负的specular被24次方了,变成了正数)。你可以直接观看生成的纹理。

如果非要这样做,那么在pass1的时候,(N,H)=(0.0,0.0)对应的纹理坐标应该是(0.5,0.5),(N,H)=(1.0,1.0)对应的纹理坐标是(1.0,0.0),自己再实验一下吧。


2

主题

50

帖子

58

积分

注册会员

Rank: 2

积分
58
发表于 2005-5-11 23:07:00 | 显示全部楼层

Re: [求助]各位帮忙看一眼这个Shader

是可以不用normalize H

只不过补充一下:

如果只是做高光lookup的话,可以不用在lookup贴图中保留和处理漫射部分
而且,LH0.y = saturate( dot( nor, normalize( H ) ) ); //Normal * H
这里的normalize是可以省略的
方法是在lookup function 里改为:

float speclevel = saturate(pow((UV.x / sqrt(UV.y)), 24));
col= float4(speclevel,speclevel ,speclevel ,speclevel );

然后再ps里采样的时候,U使用N.H, V使用H.H
这样采样出来的值就是归一化后的(N.H)^24了


这里他说的texture shader里面的
float speclevel = saturate(pow((UV.x / sqrt(UV.y)), 24));
uv.x为N dot H, uv.y为H dot H.

2

主题

85

帖子

85

积分

注册会员

Rank: 2

积分
85
发表于 2005-5-11 23:17:00 | 显示全部楼层

Re:[求助]各位帮忙看一眼这个Shader

H是经过线性插值的,所以必须单位化。这是很多人常犯的毛病。

两个H1(0,1,0),H2(1,0,0)是单位向量,可不能保证插值后是(如中点插值(0.5,0.5,0) )。

2

主题

50

帖子

58

积分

注册会员

Rank: 2

积分
58
发表于 2005-5-11 23:23:00 | 显示全部楼层

Re:[求助]各位帮忙看一眼这个Shader

。。。
仔细看看把

6

主题

444

帖子

457

积分

中级会员

Rank: 3Rank: 3

积分
457
发表于 2005-5-11 23:47:00 | 显示全部楼层

Re:[求助]各位帮忙看一眼这个Shader

zengjian老兄,请仔细看secondage的发言。他的方法是用2D lookup。横坐标是N dot H,纵坐标是H dot H,Texel(u,v) = pow(u/sqrt(v),24.0)
这样一来,H就不用归一化了嘛。
这种2D specular look up有多种不同应用,比如上面的免归一化,还有变量指数(指数*scale作为v),specular anti-aliasing(N dot N作为v)等

2

主题

85

帖子

85

积分

注册会员

Rank: 2

积分
85
发表于 2005-5-12 14:06:00 | 显示全部楼层

Re:[求助]各位帮忙看一眼这个Shader

谢谢纠正。不好意思。断章取义了。

而且我一般都是直接算,对用纹理来代替计算的技巧不是太在行。我再仔细看看。

22

主题

274

帖子

274

积分

中级会员

Rank: 3Rank: 3

积分
274
发表于 2005-5-13 10:38:00 | 显示全部楼层

Re:[求助]各位帮忙看一眼这个Shader

1是不是纹理坐标偏移的问题? 从[-1,1]到[0,1]这样?
2是不是纹理过滤采样问题,点采样到线性?

另外H,L什么其他量,单位化其实不一定需要的.
前提是模型的面跨越的像素不是很多,VS出来的单位化的H,L,插值进入PS时,虽然向量长度变化了,但误差不大,可以免去NORMALIZE操作.
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-25 15:19

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表