阴影线:Shader 分析的 - Hatching(阴影线)



原文出处:
格式问题观看不清楚请点这里看原文:
http://www.azure.com.cn/article.asp?id=283



如有转载请注明:
http://www.azure.com.cn

效果图如下:
screen.width-333) {this.width=screen.width-333;this.title=\'open window\';}\" _disibledevent=>
screen.width-333) {this.width=screen.width-333;this.title=\'open window\';}\" _disibledevent=>

此例子作为NPR渲染经典例子对理解实现NPR渲染思路方法很有指导作用
实现此效果需要两个pass
[list]
[*]PASS1:绘制内部阴影线
[*]PASS2:绘制外部轮廓线
[/list]

首先来说PASS1,
PASS1中需要个vertexshader和pixelshader,代码如下:

vertexshader:


unormvec4lightDir;

varyingvec2vTexCoord;
varyingvec3vHatchWeights0;
varyingvec3vHatchWeights1;

void(void)
{
gl_Position=gl_ModelViewProjectionMatrix*gl_Vertex;
vTexCoord=vec2(gl_MultiTexCoord0);

vec3posW=gl_NormalMatrix*gl_Vertex.xyz;
vec3normalW=normalize(gl_NormalMatrix*gl_Normal);

floatdfuse=min(1.0,max(0.0,dot(lightDir.xyz,normalW)));
dfuse=dfuse*dfuse;
dfuse=dfuse*dfuse;

floathatchFactor=dfuse*6.0;
vec3weight0=vec3(0.0);
vec3weight1=vec3(0.0);

(hatchFactor>5.0)
{
weight0.x=1.0;
}//End

(hatchFactor>4.0)
{
weight0.x=1.0-(5.0-hatchFactor);
weight0.y=1.0-weight0.x;
}//End

(hatchFactor>3.0)
{
weight0.y=1.0-(4.0-hatchFactor);
weight0.z=1.0-weight0.y;
}//End

(hatchFactor>2.0)
{
weight0.z=1.0-(3.0-hatchFactor);
weight1.x=1.0-weight0.z;
}//End

(hatchFactor>1.0)
{
weight1.x=1.0-(2.0-hatchFactor);
weight1.y=1.0-weight1.x;
}//End

(hatchFactor>0.0)
{
weight1.y=1.0-(1.0-hatchFactor);
weight1.z=1.0-weight1.y;
}//End

vHatchWeights0=weight0;
vHatchWeights1=weight1;


}
[/code]

pixelshader:
[code]
unormsampler2DHatch0;
unormsampler2DHatch1;
unormsampler2DHatch2;
unormsampler2DHatch3;
unormsampler2DHatch4;
unormsampler2DHatch5;
varyingvec2vTexCoord;
varyingvec3vHatchWeights0;
varyingvec3vHatchWeights1;

void(void)
{
vec4hatchTex0=texture2D(Hatch0,vTexCoord)*vHatchWeights0.x;
vec4hatchTex1=texture2D(Hatch1,vTexCoord)*vHatchWeights0.y;
vec4hatchTex2=texture2D(Hatch2,vTexCoord)*vHatchWeights0.z;
vec4hatchTex3=texture2D(Hatch3,vTexCoord)*vHatchWeights1.x;
vec4hatchTex4=texture2D(Hatch4,vTexCoord)*vHatchWeights1.y;
vec4hatchTex5=texture2D(Hatch5,vTexCoord)*vHatchWeights1.z;


vec4hatchColor=hatchTex0+
hatchTex1+
hatchTex2+
hatchTex3+
hatchTex4+
hatchTex5;

gl_FragColor=hatchColor;

}


[/code]

我们实现hatching需要多张hatching纹理
这些hatching是系列又淡到浓素描纹理如下:
screen.width-333) {this.width=screen.width-333;this.title=\'open window\';}\" _disibledevent=>

在VS中我们通过NdotL算出了此顶点受光亮度如下
[code]
floatdfuse=min(1.0,max(0.0,dot(lightDir.xyz,normalW)));
dfuse=dfuse*dfuse;
dfuse=dfuse*dfuse;
[/code]
后面把dfuse平方两次是为了把亮度降低点把整体亮度向暗方向偏移
这里只是为了更好视觉效果

现在最关键就是要通过这个亮度值决定使用哪些hatch纹理权重(hatch0,hatch1,hatch2,hatch3,hatch4,hatch5)
在这里为了减少vs向ps插值变量个数巧妙使用了两个vec3来记录每个hatch图所绘制权重
见以下代码:
[code]
floathatchFactor=dfuse*6.0;
vec3weight0=vec3(0.0);
vec3weight1=vec3(0.0);

(hatchFactor>5.0)
{
weight0.x=1.0;
}//End

(hatchFactor>4.0)
{
weight0.x=1.0-(5.0-hatchFactor);
weight0.y=1.0-weight0.x;
}//End

(hatchFactor>3.0)
{
weight0.y=1.0-(4.0-hatchFactor);
weight0.z=1.0-weight0.y;
}//End

(hatchFactor>2.0)
{
weight0.z=1.0-(3.0-hatchFactor);
weight1.x=1.0-weight0.z;
}//End

(hatchFactor>1.0)
{
weight1.x=1.0-(2.0-hatchFactor);
weight1.y=1.0-weight1.x;
}//End

(hatchFactor>0.0)
{
weight1.y=1.0-(1.0-hatchFactor);
weight1.z=1.0-weight1.y;
}//End

vHatchWeights0=weight0;
vHatchWeights1=weight1;
[/code]
首先dfuse值被乘以6是为了好方便区分区段
下面系列判断就是判断dfuse值到底在哪个区段里面
以决定相应权重
vHatchWeights0.x对应hatch0权重
vHatchWeights0.y对应hatch1权重
vHatchWeights0.z对应hatch2权重
vHatchWeights1.x对应hatch3权重
vHatchWeights1.y对应hatch4权重
vHatchWeights1.z对应hatch5权重

接下来vHatchWeights0,vHatchWeight1被插值到了ps
后面就很简单了根据相应权重取得相应纹理颜色再合成起来
代码如下:
[code]vec4hatchTex0=texture2D(Hatch0,vTexCoord)*vHatchWeights0.x;
vec4hatchTex1=texture2D(Hatch1,vTexCoord)*vHatchWeights0.y;
vec4hatchTex2=texture2D(Hatch2,vTexCoord)*vHatchWeights0.z;
vec4hatchTex3=texture2D(Hatch3,vTexCoord)*vHatchWeights1.x;
vec4hatchTex4=texture2D(Hatch4,vTexCoord)*vHatchWeights1.y;
vec4hatchTex5=texture2D(Hatch5,vTexCoord)*vHatchWeights1.z;


vec4hatchColor=hatchTex0+
hatchTex1+
hatchTex2+
hatchTex3+
hatchTex4+
hatchTex5;








此时pass1完成了

PASS2绘制外部轮廓线:
其实很简单就是将原来模型以背面剔除方式线框模式再绘制
你可以设置适当线宽

最后效果就出来了

www.azure.com.cn


Tags:  shadermodel3.0 shader hatching 阴影线

延伸阅读

最新评论

发表评论