unity 高光法线shadershader 顶点变化之后法线怎么办

Unity Shader-法线贴图(Normal)及其原理-GAD腾讯游戏开发者平台关于shader描边顶点处理的问题【unity3d吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:77,865贴子:
关于shader描边顶点处理的问题收藏
v2f vert (appdata_full v) {
float3 dir=normalize(v.vertex.xyz);
float3 dir2=v.
float D=dot(dir,dir2);
dir=dir*sign(D);
dir=dir*_Factor+dir2*(1-_Factor);
v.vertex.xyz+=dir*_O
o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
}第五行float D=dot(dir,dir2);为什么两个模型空间向量直接点乘了,顶点坐标又没减去视点坐标,难道不应该是先转到视空间再点乘么float D=dot(mul(UNITY_MATRIX_MV,v.vertex),mul(UNITY_MATRIX_MV,v.normal));
百强板材_别墅豪宅健康板_中国板材十大品牌!板材十大品牌
因为D的计算是在物体自身坐标下计算,并且采用沿法线向外扩张的方式生成一个包围原模型的外壳,然后再走MVP矩阵,这样就看起来任何角度下都是很均匀的描边(如果法线过渡均匀的话)。如果选择在MV矩阵(摄像机坐标)下计算,透视投影下的摄像机会导致z坐标变化,进而引起厚度很奇怪的问题。
登录百度帐号推荐应用Unity3d中Shader的一些常用方法_Android开发_动态网站制作指南
Unity3d中Shader的一些常用方法
来源:人气:692
float4 tex2D(sampler2D samp, float2 s)
2D纹理采样,CG内置函数。
内部实现分为以下几步:
1. 用图片的宽高度乘以uv数值,得到像素坐标。widthPixel=samp.x*s.x;heightPixel=samp.y*s.y;
2. 因为取到的数值基本上都是带有小数点的,也就是说不是一个整数,这个时候,需要看图片的过滤设置了。也就是Unity3d的图片设置中的Filter Mode。
3. Filter Mode是Point,不过滤,就会取像素点最靠近的整数,也就是四舍五入,得到像素点的坐标,然后出去图片中,这个坐标的颜色。
4. 双线性过滤,会取目标像素的附近4个像素,然后进行插值计算,得到平均颜色值,作为最终颜色。适合纹理由小放大过程中,出现的“马赛克”。
5. 三线性过滤,在双线性过滤的基础上考虑到了深度LOD,会进行两次双线性过滤,来使不同的LOD等级纹理中,更加平滑的过渡。
TRANSFORM_TEX(tex,name)
这个方法的定义在UnityCG.cginc中,它有两个参数,tex.xy是顶点的uv值,name##_ST则是在这个shader所在的材质球中,纹理图片的缩放和偏移,S指Scale,T指Transform,它是一个float4类型,其值分别为(Tiling.x,Tiling.y,Offset.x,Offset.y)。这个方法运算后,得到的是经过偏移和缩放的uv。它的运算公式是TextureCoordinate =
tex.xy * name##_ST.xy + name##_ST.zw。如果偏移为0,缩放为默认1,则可以不用经过这个过程。
UnpackNormal(fixed4 packednormal)
这个方法是对法线纹理进行采样。它的定义同样在UnityCG.cginc里。
inline fixed3 UnpackNormal(fixed4 packednormal)
#if defined(UNITY_NO_DXT5nm)
return packednormal.xyz * 2 - 1;
return UnpackNormalDXT5nm(packednormal);
inline fixed3 UnpackNormalDXT5nm (fixed4 packednormal)
normal.xy = packednormal.wy * 2 - 1;
normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));
这里有两个方法,以UnpackNormal方法来说,它最主要的也就是
packednormal.xyz * 2 - 1;
要解释这个,就必须讲到法线纹理的生成。法线纹理是把模型的法线信息存到图片中去,每条法线的x,y,z对应的存到每个像素的r,g,b中。每条法线里的每个数值都是一个[-1,1]的闭合区间里,像素的每个数值则都是在[0,255]中,(n + vec3(1.0,1.0,1.0)) * (255.0 / 2.0),每个法线向量,经过加上 vec3(1.0,1.0,1.0)。变成[0,2]的闭合区间里,然后除以2,再乘以255,发现向量,就会转换成了[0,255]里的数值。这也是上述那条公式的由来。
至于法线纹理如何生成,有兴趣的可以详细了解一下这个算法,各个软件的生成算法不一样,最终得到的法线纹理也不一样。但是纹理里的数据,肯定是符合规范的法线纹理数据,可以在shader中使用。
另外一个方法UnpackNormalDXT5nm ,则是一个压缩法线纹理后的方法。大家都知道,法线是一个单位向量,也就是它的长度是1,所以只需要知道x,y的数值,是可以计算得到z的数值的,z=1-(x+y)的平方。这样就可以减少贴图的大小,减少GPU的数据传输量。
inline float3 UnityObjectToWorldNormal( in float3 norm )
从模型空间到世界空间转换法线。它的定义同样在UnityCG.cginc里
inline float3 UnityObjectToWorldNormal( in float3 norm )
// Multly by transposed inverse matrix, actually using transpose() generates badly optimized code
return normalize(_World2Object[0].xyz * norm.x + _World2Object[1].xyz * norm.y + _World2Object[2].xyz * norm.z);
其实也相当于
normalize(mul((float3x3)_World2Object),norm);
_World2Object在上一篇
Unity3d中Shader的一些关于矩阵变换的基本信息中说过它是当前世界矩阵的逆矩阵。
inline float3 UnityObjectToWorldDir( in float3 dir )
inline float3 UnityObjectToWorldDir( in float3 dir )
return normalize(mul((float3x3)_Object2World, dir));
光照的计算
拿”Mobile/Bumped Diffuse”这个shader来说,它的代码很短,是一个中间代码,需要点击右方的Show generated code,出现详细的代码,其中的顶点函数
v2f_surf vert_surf (appdata_full v) {
UNITY_INITIALIZE_OUTPUT(v2f_surf,o);
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.pack0.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
//这里是计算顶点的世界坐标
float3 worldPos = mul(_Object2World, v.vertex).
//得到顶点法线转换到世界空间的法线,得到切线空间的N
fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
//得到顶点的切线转换到世界空间的切线,得到切线空间的T
fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
//计算方向,后面用到
fixed tangentSign = v.tangent.w * unity_WorldTransformParams.w;
//通过T和N的向量积,得到垂直这两个向量的向量,但是它的方向有两个,所以乘以上面得到的方向参数,得到最终的向量,得到切线空间的B
fixed3 worldBinormal = cross(worldNormal, worldTangent) * tangentS
//所以下面是得到模型的顶点的切线空间到世界空间的矩阵,分行显示,没看明白的可以看一下矩阵的基本知识
o.tSpace0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x);
o.tSpace1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y);
o.tSpace2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z);
#ifndef DYNAMICLIGHTMAP_OFF
o.lmap.zw = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.
#ifndef LIGHTMAP_OFF
o.lmap.xy = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.
// SH/ambient and vertex lights
#ifdef LIGHTMAP_OFF
#if UNITY_SHOULD_SAMPLE_SH
// Apoximated illumination from non-important point lights
#ifdef VERTEXLIGHT_ON
o.sh += Shade4PointLights (
unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb,
unity_4LightAtten0, worldPos, worldNormal);
o.sh = ShadeSHPerVertex (worldNormal, o.sh);
#endif // LIGHTMAP_OFF
TRANSFER_SHADOW(o); // pass shadow coordinates to pixel shader
UNITY_TRANSFER_FOG(o,o.pos); // pass fog coordinates to pixel shader
像素片段函数
// fragment shader
fixed4 frag_surf (v2f_surf IN) : SV_Target {
// prepare and unpack data
Input surfIN;
UNITY_INITIALIZE_OUTPUT(Input,surfIN);
surfIN.uv_MainTex.x = 1.0;
surfIN.uv_MainTex = IN.pack0.
//把顶点函数取得的世界顶点坐标取出来&
float3 worldPos = float3(IN.tSpace0.w, IN.tSpace1.w, IN.tSpace2.w);
#ifndef USING_DIRECTIONAL_LIGHT
//如果用的是直线光,就把顶点的位置转换成向量,成为光照向量
fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos));
//否者直接用世界光照的方向
fixed3 lightDir = _WorldSpaceLightPos0.
#ifdef UNITY_COMPILER_HLSL
SurfaceOutput o = (SurfaceOutput)0;
o.Albedo = 0.0;
o.Emission = 0.0;
o.Specular = 0.0;
o.Alpha = 0.0;
o.Gloss = 0.0;
fixed3 normalWorldVertex = fixed3(0,0,1);
// call surface function
surf (surfIN, o);
// compute lighting & shadowing factor
UNITY_LIGHT_ATTENUATION(atten, IN, worldPos)
fixed4 c = 0;
fixed3 worldN;
/*通过向量计算,得到世界法线的方向,这里Surf方法里o.Normal =
UnpackNormal(tex2D(_BumpMap, IN.uv_MainTex));
得到的是该顶点的切空间的法线方向,实际上,下面这个方法也等于
worldN= normalize(mul( float3x3(IN.tSpace0.xyz, IN.tSpace1.xyz, IN.tSpace2.xyz),o.Normal));
worldN.x = dot(IN.tSpace0.xyz, o.Normal);
worldN.y = dot(IN.tSpace1.xyz, o.Normal);
worldN.z = dot(IN.tSpace2.xyz, o.Normal);
o.Normal = worldN;
// Setup lighting environment
UNITY_INITIALIZE_OUTPUT(UnityGI, gi);
gi.indirect.diffuse = 0;
gi.indirect.specular = 0;
#if !defined(LIGHTMAP_ON)
gi.light.color = _LightColor0.
gi.light.dir = lightD
//进行光照计算,获得夹角
gi.light.ndotl = LambertTerm (o.Normal, gi.light.dir);
// Call GI (lightmaps/SH/reflections) lighting function
UnityGIInput giI
UNITY_INITIALIZE_OUTPUT(UnityGIInput, giInput);
giInput.light = gi.
giInput.worldPos = worldP
giInput.atten =
#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
giInput.lightmapUV = IN.
giInput.lightmapUV = 0.0;
#if UNITY_SHOULD_SAMPLE_SH
giInput.ambient = IN.
giInput.ambient.rgb = 0.0;
giInput.probeHDR[0] = unity_SpecCube0_HDR;
giInput.probeHDR[1] = unity_SpecCube1_HDR;
#if UNITY_SPECCUBE_BLENDING || UNITY_SPECCUBE_BOX_PROJECTION
giInput.boxMin[0] = unity_SpecCube0_BoxM // .w holds lerp value for blending
#if UNITY_SPECCUBE_BOX_PROJECTION
giInput.boxMax[0] = unity_SpecCube0_BoxM
giInput.probePosition[0] = unity_SpecCube0_ProbeP
giInput.boxMax[1] = unity_SpecCube1_BoxM
giInput.boxMin[1] = unity_SpecCube1_BoxM
giInput.probePosition[1] = unity_SpecCube1_ProbeP
LightingLambert_GI(o, giInput, gi);
// realtime lighting: call lighting function
c += LightingLambert (o, gi);
UNITY_APPLY_FOG(IN.fogCoord, c); // apply fog
UNITY_OPAQUE_ALPHA(c.a);
以上就是主要的光照和法线贴图的使用。其实还可以把光照转换到切空间中进行计算,得到计算结果后,再转换回世界空间,都是可行的。
优质网站模板&>&空气扭曲shader (热扰动)基于法线计算
空气扭曲shader (热扰动)基于法线计算
上传大小:534KB
空气扭曲shader (热扰动)基于法线计算
综合评分:3.5(2位用户评分)
所需积分/C币:
下载个数:51
{%username%}回复{%com_username%}{%time%}\
/*点击出现回复框*/
$(".respond_btn").on("click", function (e) {
$(this).parents(".rightLi").children(".respond_box").show();
e.stopPropagation();
$(".cancel_res").on("click", function (e) {
$(this).parents(".res_b").siblings(".res_area").val("");
$(this).parents(".respond_box").hide();
e.stopPropagation();
/*删除评论*/
$(".del_comment_c").on("click", function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_invalid/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parents(".conLi").remove();
alert(data.msg);
$(".res_btn").click(function (e) {
var q = $("#form1").serializeArray();
console.log(q);
var res_area_r = $.trim($(".res_area_r").val());
if (res_area_r == '') {
$(".res_text").css({color: "red"});
$.post("/index.php/comment/do_comment_reply/", q,
function (data) {
if (data.succ == 1) {
var $target,
evt = e || window.
$target = $(evt.target || evt.srcElement);
var $dd = $target.parents('dd');
var $wrapReply = $dd.find('.respond_box');
console.log($wrapReply);
var mess = $(".res_area_r").val();
var str = str.replace(/{%header%}/g, data.header)
.replace(/{%href%}/g, 'http://' + window.location.host + '/user/' + data.username)
.replace(/{%username%}/g, data.username)
.replace(/{%com_username%}/g, _username)
.replace(/{%time%}/g, data.time)
.replace(/{%id%}/g, data.id)
.replace(/{%mess%}/g, mess);
$dd.after(str);
$(".respond_box").hide();
$(".res_area_r").val("");
$(".res_area").val("");
$wrapReply.hide();
alert(data.msg);
}, "json");
/*删除回复*/
$(".rightLi").on("click",'.del_comment_r', function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_comment_del/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parent().parent().parent().parent().parent().remove();
$(e.target).parents('.res_list').remove()
alert(data.msg);
//填充回复
function KeyP(v) {
$(".res_area_r").val($.trim($(".res_area").val()));
评论共有2条
下错了,本来找流体的,不过可以留着以后看看了
对我来说没有太大的作用
审核通过送C币
Ray Wenderlich 书籍
创建者:fengqingli
iOS开发学习电子书
iOS电子图书大全
创建者:qq_
上传者其他资源上传者专辑
移动开发热门标签
VIP会员动态
下载频道积分规则调整V1710.18
CSDN下载频道积分调整公告V1710.17
开通VIP,海量IT资源任性下载
spring mvc+mybatis+mysql+maven+bootstrap 整合实现增删查改简单实例.zip
CSDN&VIP年卡&4000万程序员的必选
为了良好体验,不建议使用迅雷下载
空气扭曲shader (热扰动)基于法线计算
会员到期时间:
剩余下载个数:
剩余C币:593
剩余积分:0
为了良好体验,不建议使用迅雷下载
积分不足!
资源所需积分/C币
当前拥有积分
您可以选择
程序员的必选
绿色安全资源
资源所需积分/C币
当前拥有积分
当前拥有C币
(仅够下载10个资源)
全站600个资源免积分下载
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
全站600个资源免积分下载
资源所需积分/C币
当前拥有积分
当前拥有C币
您的积分不足,将扣除 10 C币
全站600个资源免积分下载
为了良好体验,不建议使用迅雷下载
你当前的下载分为234。
你还不是VIP会员
开通VIP会员权限,免积分下载
你下载资源过于频繁,请输入验证码
你下载资源过于频繁,请输入验证码
您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:!
若举报审核通过,可奖励20下载分
被举报人:
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:
空气扭曲shader (热扰动)基于法线计算

我要回帖

更多关于 unity shader 法线 的文章

 

随机推荐