精华内容
下载资源
问答
  • shaderforge 法线
    千次阅读
    2019-04-08 13:06:20

     

    总结起来有两个,一个是基本的转换,单纯的模型空间转换到世界空间,第二个是需要法线贴图时(Bump Textrue)的时候就转换到切线空间下进行计算。

    1.从“模型空间”到“世界空间”(Object To World):

    (1)方法1,使用和“顶点”到“世界”变换矩阵的“逆转置矩阵“对法线进行相同的变换,因此先得到顶点的模型到世界的变换矩阵的“逆矩阵”(Unity_WorldToObject),然后通过调换它在mul函数中的位置,得到和转置矩阵相同的矩阵乘法,由于法线是一个三维矢量,因此我们只需要街截取unity_WorldToObject的前三行前三列:

    worldNormal = normalize(mul(v.normal,(float3x3)unity_WorldToObject))
    

    最外侧的运算“normalize(x)”表示归一化。

    (2)使用Unity内置的语法“UnityObjectToWorldNormal()”。
    这是Unity5.x在中,可以通过“内置着色器”中的“Unity.cginc”中找到相关的用法,截一小段代码:

    // Transforms normal from object to world space
    inline float3 UnityObjectToWorldNormal( in float3 norm )
    {
    #ifdef UNITY_ASSUME_UNIFORM_SCALING
        return UnityObjectToWorldDir(norm);
    #else
        // mul(IT_M, norm) => mul(norm, I_M) => {dot(norm, I_M.col0), dot(norm, I_M.col1), dot(norm, I_M.col2)}
        return normalize(mul(norm, (float3x3)unity_WorldToObject));
    #endif
    }
    

    注释已经写的很清楚了“把法线从模型空间变换到世界空间”,里面做了个判断。如果是“统一缩放”那么这个方法用的是“UnityObjectToWorldDir()”,如果是非统一缩放,则用“normalize(mul(norm, (float3x3)unity_WorldToObject)”,这个就是和“方法1”是一模一样的。之所以这种写法,就是为了保证模型“非统一缩放”也不会得到错误的法线。
    而Unity封装的这个方法,就解决了,不管模型是不是统一缩放,用这个肯定没有错。在Unity4.x和之前,是不用管是不是统一缩放的,因为当模型缩放后,unity会在背后重新生成一个模型,和缩放后的一样大,从而法线肯定不会错。但是unity5.x及以后,就必须要注意这个问题。
    下面看一下在shader中,怎么使用这个方法:

    normalDir = UnityObjectToWorldNormal(v.normal)

    具体的推导公式可以参考冯乐乐的书p86。

    1.先得到一个“从切线空间到世界空间”的矩阵。
    为什么要这个矩阵?我们平时看到的法线贴图记录的都是切线空间下的法线信息(实质上是坐标信息),我们想要用这张图参与接下来的光照计算,其它的如“顶点坐标”““灯光位置”等等都是在世界空间的,自然的这张图也需要在世界空间才能参与计算。因此需要这个“从切线空间到世界空间”的矩阵,来对这张法线图进行变换。一般的用的矩阵是:

    float3x3 tangentTransform = float3x3(i.tangentDir,i.bitangentDir,i.normalDir);
    

    矩阵的三个参数:切线、副切线、法线,注意三个参数要进行归一化!

    2.对纹理进行采样
    既然是使用纹理,项diffusecolor(basecolor)一样,需要对纹理进行采样,用到两个函数:

    TRANSFORM_TEX() //计算贴图的UV
    tex2D()//对纹理进行采样
    

    当然也可以在一步完成如:

    packedNormal = tex2D(_BumpMap,TRANSFORM_TEX(i.uv0,_BumpMap))
    

    3.对“法线贴图”进行解包(Unpack)操作。
    (1)上面说到法线贴图记录的是切线空间下的法线信息。而“法线贴图”本身从名字来看,它本身是张图,既然是图,也就是意味着它记录的是颜色信息(RGB)。所以法线贴图本身是有一个映射关系的。
    法线本身分量是在[-1,1],而法线贴图(RGB)是以像素为单位的,像素的范围是[0,1],法线变成法线图,必然有个映射关系,那就是“pixel = (normal + 1) / 2”。
    (2)另外这个公式还可以解释为什么法线贴图是浅蓝色的,因为法线图是切线空间下的,而切线空间下的法线基本上都在“顶点的切线空间的Z轴方向”扰动,也就是基本上都是(0,0,1)。带入公式,像素值=(0.5,0.5,1)
    这个值正是浅蓝色。
    (3)既然法线贴图要参与下面的计算,就要映射回去,由上面的公式逆推一下,法线=pixel * 2 - 1,带入公式计算:

    //接着上面的代码:
    float3 tangentNormal
    tangentNormal.xy = (packedNormal.xy * 2 - 1) * _BumpScale;
    tangentNormal.z = sqrt(1.0 - saturate(dot(tangentNormal.xy, tangentNormal.xy)));
    

    ①上面第一句的意思是首先把“法线贴图”的xy分量按公式映射回法线方向,然后乘以_MumpScale(控制法线强度的值)来得到切线空间下法线的 x y分量。
    ②第二句意思是:由x y分量,计算Z分量。这是由于法线是单位矢量,所以Z分量可以这么计算。由于我们使用的是切线空间下的法线贴图,因此可以保证法线的Z分量为正(可以参考下面的图)

     

    image.png

     

    (4)理论上这么做是可以的。但是Unity为了优化贴图,在进行“反映射”的同时对纹理进行了压缩优化。具体操作就是把导入的法线贴图,在其属性面板中,把选项标记成“NormalMap”这个操作(即使你不标记,Unity也会提醒你的),在shader中的体现就是“UnpackNormal()”函数。这个函数把压缩贴图和“反映射”同步进行了,具体的可以参考“UnityCG.cginc”下面的定义:

    inline fixed3 UnpackNormalDXT5nm (fixed4 packednormal)
    {
        fixed3 normal;
        normal.xy = packednormal.wy * 2 - 1;
        normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));
        return normal;
    }
    
    inline fixed3 UnpackNormal(fixed4 packednormal)
    {
    #if defined(UNITY_NO_DXT5nm)
        return packednormal.xyz * 2 - 1;
    #else
        return UnpackNormalDXT5nm(packednormal);
    #endif
    }
    

    ①可以看到“UnpackNormal()”函数包含了“UnpackNormalDXT5nm()函数”,“UnpackNormal()”函数里面只是做了一个简单的判断(判断是否进行纹理压缩),而真正进行计算的是“UnpackNormalDXT5nm()函数” 其中“DXT5”应该看着很眼熟,它正是压缩方法的其中一种。
    ②“具体的细节是:把“w”分量(纹理的a通道)对应法线的 x 分量。g通道对应了法线的y分量,而纹理的r和b通道则会被舍弃,法线的Z分量可以由x y 推导得出。更具体的细节以后再看吧。可以看到“UnpackNormalDXT5nm()函数”的输入参数是“packednormal”,(采样后的法线贴图),但是“packednormal”的参数只有RGB,没有w y 所以可以推断这个压缩过程是在外部进行的。而“UnpackNormalDXT5nm()函数”只是对压缩后的“packednormal”新的RGB进行反映射。

    (5)反映射后,如果还想要调节法线的强度,同样的还需要乘上调节强度的参数(_BumpScale)具体可以这样写:

    fixed3 tangentNormal;
    tangentNormal = UnpackNormal(packedNormal);
    tangentNormal.xy *= _BumpScale;
    tangentNormal.z = sqrt(1.0 - saturate(dot(tangentNormal.xy, tangentNormal.xy)));
    

    可以看到只是把(3)手动映射的计算,换成UnpackNormal()操计算。这样才能保证得到的正确法的法线。
    这里还要提一句:不能把得到的“tangentNormal”直接带入“反映射公式”去计算,如:
    tangentNormal = tangentNormal.xyz * 2-1,因为Z分量是由 x y 分量推导出来的。

    4.得到反映射的法线后,就可以 用“1”得到的变换矩阵去变换了:

    float3 normalDirection = normalize(mul(tangentNormal,tangentTransform));
    //用矩阵变换后,执行归一化
    

    5.到这里,需要用法线贴图的基本shader的法线变换就讲完了。


    转载链接:https://www.jianshu.com/p/c6a94d3b64bc
     

    更多相关内容
  • 首先是根据ShaderForge,作出最简Shader模板,然后在最简模板的基础上去添加计算。来达到想要的效果。 Shader "Shader Forge/EasiestShader" {//路径名 Properties {//材质面板参数 } SubShader { Tags ...

     编辑器使用的是VSCODE,unity自带的vs2019写shader太tm痛苦了,简直能从入门到放弃。

    这是我跟着大佬们装的插件,可能有些用不上。但是目前来说没什么毛病。 

    首先是根据ShaderForge,作出最简Shader模板,然后在最简模板的基础上去添加计算。来达到想要的效果。 

    Shader "Shader Forge/EasiestShader" {//路径名
        Properties {//材质面板参数
        }
        SubShader {
            Tags {
                "RenderType"="Opaque"
            }
            Pass {
                Name "FORWARD"
                Tags {
                    "LightMode"="ForwardBase"
                }
                
                
                CGPROGRAM
                //顶点变量
                #pragma vertex vert
                //像素变量
                #pragma fragment frag
                //目前阶段个人理解,shader就是给上方两个变量赋值。用结构体VertexInput描述物体在本身层面的一些属性信息,再用VertexOutput vert (VertexInput v)方法根据输入结构计算出输出结构。
    
    
                #include "UnityCG.cginc"
                #pragma multi_compile_fwdbase_fullshadows
                #pragma target 3.0
                struct VertexInput {//输入结构
                    float4 vertex : POSITION;//将模型顶点信息输入进来
    
                };
                struct VertexOutput {//输出结构
                    float4 pos : SV_POSITION;//由模型顶点信息换算而来的顶点屏幕位置
                };
                VertexOutput vert (VertexInput v) {//顶点shader
                    VertexOutput o = (VertexOutput)0;//新建一个输出结构
                    o.pos = UnityObjectToClipPos( v.vertex );//变换顶点信息,并将其赋值给输出结构
    
                    return o;//将输出结构输出
                }
                float4 frag(VertexOutput i) : COLOR {//像素shader
                    return fixed4(1.0,0.0,0.0,1.0);//RGBA  输出为红色
                }
                ENDCG
            }
        }
        FallBack "Diffuse"
    }

     

    最简模板输出一颗红桔子 ,然后加入一点计算的代码,制作一个兰伯特光照模型

    
    Shader "Shader Forge/EasiestShader" {//路径名
        Properties {//材质面板参数
        }
        SubShader {
            Tags {
                "RenderType"="Opaque"
            }
            Pass {
                Name "FORWARD"
                Tags {
                    "LightMode"="ForwardBase"
                }
                
                
                CGPROGRAM
                //顶点变量
                #pragma vertex vert
                //像素变量
                #pragma fragment frag
                //目前阶段个人理解,shader就是给上方两个变量赋值。用结构体VertexInput描述物体在本身层面的一些属性信息,再用VertexOutput vert (VertexInput v)方法根据输入结构计算出输出结构。
    
    
                #include "UnityCG.cginc"
                #pragma multi_compile_fwdbase_fullshadows
                #pragma target 3.0
                struct VertexInput {//输入结构
                    float4 vertex : POSITION;//将模型顶点信息输入进来
                    float3 normal: NORMAL;//将法线信息输入进来
    
                };
                struct VertexOutput {//输出结构
                    float4 pos : SV_POSITION;//由模型顶点信息换算而来的顶点屏幕位置
                    float3 nDirWS:TEXCOORD0;//由模型法线信息换算而来的世界空间法线信息
                };
                VertexOutput vert (VertexInput v) {//顶点shader
                    VertexOutput o = (VertexOutput)0;//新建一个输出结构
                    o.pos = UnityObjectToClipPos( v.vertex );//变换顶点信息,并将其赋值给输出结构
                    o.nDirWS=UnityObjectToWorldNormal(v.normal);//变换法线信息,并将其赋值给输出结构
                    return o;//将输出结构输出
                }
                float4 frag(VertexOutput i) : COLOR {//像素shader
                float3 nDir=i.nDirWS;
                float3 lDir=_WorldSpaceLightPos0.xyz;//光方向
                float nDot1=dot(i.nDirWS,lDir);//点乘算出兰伯特
                float lambert=max(0.0,nDot1);//兰伯特明暗钳制
                    return fixed4(lambert,lambert,lambert,1.0);
                    //return lambert;这样也不会报错,但是安全期间还是输出四维向量
                }
                ENDCG
            }
        }
        FallBack "Diffuse"
    }

    兰伯特桔子完成!

    (PS:我是跟着B站大佬,庄懂的视屏学习的。感谢大佬的视屏) 

    展开全文
  • 法线贴图可以让低模看起来像是高模一样,具体的实现原理,是改变了光照,呈现出凹凸度: 下图中为法线贴图 根据光照模型来进行更改: 首先我们需要声明法线贴图纹理和法线的凹凸度: _BumpMap("bumpMap",2D) = ...

    法线贴图可以让低模看起来像是高模一样,具体的实现原理,是改变了光照,呈现出凹凸度:
    下图中为法线贴图
    在这里插入图片描述
    根据光照模型来进行更改:
    首先我们需要声明法线贴图纹理和法线的凹凸度:

    _BumpMap("bumpMap",2D) = "bump"{}
    _BumpScale("BumpScale",Float) = 1.0
    
    sampler2D _BumpMap;
    float4 _BumpMap_ST;
    float _BumpScale;
    

    输入我们需要添加一个切线和法线:

    struct Input
    {
    	float4 Position : POSITION0;
    	float2 Texcoord : TEXCOORD0;
    	float3 Normal   : NORMAL;
    	float4 tangent  : TANGENT;
    };
    

    在顶点着色器中:我们需要将uv坐标存一下,传到片元阶段:

    ......
    //uv用的float4类型的
    float4 uv : TEXCOORD0;
    ......
    //xy通道存储主纹理,zw通道存储法线贴图
    o.uv.xy = TRANSFORM_TEX(i.Texcoord, _MainTex);
    o.uv.zw = TRANSFORM_TEX(i.Texcoord, _BumpMap);
    

    还有一个问题:
    法线是需要转换到TBN坐标系(切线空间)进行计算的(其实将其全部转换到世界坐标是一样的,只要在同一坐标系下,没试过)。
    TBN坐标系是:切线,副法线,法线,我们有了法线和副法线,那么切线就可以利用叉乘简单算出来了:worldToTangent :切线空间转换矩阵

    //求出世界空间下的法线向量
    fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
    //求出世界空间下的切线向量  
    fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);  
    //副法线向量由法线和切线的叉乘得到,切线的w分量决定副法线的方向性
    fixed3 worldBinormal = cross(worldNormal, worldTangent) * (v.tangent.w*unity_WorldTransformParams.w);
    // 切线空间转换矩阵
    float3x3 worldToTangent = float3x3(worldTangent, worldBinormal, worldNormal);
    
    //调用
    //将其转换到切线空间
    o.LightDir = mul(worldToTangent, o.LightDir);
    o.ViewDir = mul(worldToTangent, o.ViewDir);
    

    但unity给了我们一个宏定义:,需要: #include “UnityCG.cginc”

    TANGENT_SPACE_ROTATION;
    

    该宏定义之后,会有一个rotation值,利用这个rotation值进行与光线和视线进行相乘就可以得到切线空间下的光线方向和视线方向了:

    o.lightDir = mul(rotation, ObjSpaceLightDir(i.Position)).xyz;
    o.viewDir = mul(rotation, ObjSpaceViewDir(i.Position)).xyz;
    

    不过有一个问题:
    下面是这个宏定义的等价代码:
    也就是说,我们输入的定义对象必须是v,而且在Input结构体里面的对象也必须是normal和tangent,否则报错,我们可以直接复制下面代码,根据需求进行修改:

    float3 binormal = cross( v.normal, v.tangent.xyz ) * v.tangent.w;
    float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal );
    

    然后就是像素(片元)阶段:
    我们需要做的是对法线贴图进行采样:法线uv存储的是zw通道

     fixed4 packedNormal = tex2D(_BumpMap, i.uv.zw);
    

    然后我们根据UnpackNormal方法,将其对应的法线纹理需要设置为Normal map的格式。
    ==UnpackNormal()==函数在UnityCG.cginc中,它是对法线纹理的采样结果的一个反映射操作,其对应的法线纹理需要设置为Normal map的格式
    _BumpMap法线贴图,tangentNormal转换为了Normal Map格式
    法线是一个单位向量,也就是它的长度是1,所以只需要知道x,y的数值,是可以计算得到z的数值的,z=1-(x+y)的平方

    为什么需要转换成NormalMap模式呢?
    这样做可以让unity根据不同平台纹理进行压缩,再通过UnpackNormal函数针对不同的压缩格式对法线纹理进行正确的采样

    fixed3 tangentNormal;
    
    tangentNormal = UnpackNormal(packedNormal);
    tangentNormal.xy *= _BumpScale;
    //z=1-(x+y)的平方
    tangentNormal.z = sqrt(1 - tangentNormal.x*tangentNormal.x - tangentNormal.y * tangentNormal.y);
    

    然后将tangentNormal 替换掉光照模型里面的法线,将自发光+镜面反射+漫反射+环境光得到的就是添加了法线贴图的模型了:

    纹理遮罩
    对于图形编程来说,大部分信息都是图片纹理获取的,而纹理遮罩使用也是如此,
    如下代码:遮罩纹理当前像素信息里面r存的是对高光的遮罩
    在实际应用中,我们会充分利用遮罩纹理中的每一个颜色通道进行存储不同的表面属性
    需要在原先法线的shader上面添加相对应的遮罩代码,下面代码只是遮罩了高光部分的

    ....
    _SpecularMask("SpecularMask",2D) = "white"{}
    _SpecularScale("SpecularScale",Float) = 1.0
    ....
    //声明:
    //遮罩纹理
    sampler2D _SpecularMask;
    //遮罩影响的系数大小
    float _SpecularScale;
    ....
    //使用就直接对纹理进行采样*系数
    fixed3 spmask = tex2D(_SpecularMask, i.uv.xy).r*_SpecularScale;
    ....
    //比如说,我的遮罩纹理当前像素信息里面r存的是对高光的遮罩:
    float3 Specul = _LightColor0.xyz* _Specular.xyz* pow(saturate(dot(tangentNormal, halfdiff)), _Gloss);
    Specul = Specul * spmask;
    ....
    

    完整的shader代码:
    可以对比一下光照模型有什么改动和区别:效果一样

    Properties
    	{
    	   _Color("Color Tint",Color) = (1,1,1,1)
    	   _MainTex("MainTex",2D) = "white"{}
    	   _BumpMap("bumpMap",2D) = "bump"{}
    	   _BumpScale("BumpScale",Float) = 1.0
    	   _Specular("Specular",Color) = (1,1,1,1)
    	   _Gloss("Gloss",Range(8.0,256)) = 20
    	   _SpecularMask("SpecularMask",2D) = "white"{}
    	   _SpecularScale("SpecularScale",Float) = 1.0
    	}
    		SubShader
    	   {
    		   Tags{ "RenderType" = "Opaque" "LightMode" = "ForwardBase"}
    		   LOD 100
    
    		   pass {
    		   //cg语言开始编写
    		   CGPROGRAM
    
    			   //在逻辑中申明顶点和片段://编译申明函数
    			   //顶点程序
    			   #pragma vertex vert
    			   //片段程序
    			   #pragma fragment frag
    
    			   #include "UnityCG.cginc"
    			   #include "Lighting.cginc"
    			   sampler2D _MainTex;
    			   float4 _MainTex_ST;
    			   sampler2D _BumpMap;
    			   float4 _BumpMap_ST;
    			   sampler2D _SpecularMask;
    			   float _SpecularScale;
    
    
    			   float4 _Color;
    			   float _BumpScale;
    			   float4 _Specular;
    			   float _Gloss;
    
    			   struct v2f {
    				   float4 pos : POSITION0;
    				   float4 uv : TEXCOORD0;
    				   float3 lightDir: TEXCOORD1;
    				   float3 viewDir:TEXCOORD4;
    			   };
    			   struct Input
    			   {
    				   float4 Position : POSITION0;
    				   float2 Texcoord : TEXCOORD0;
    				   float3 Normal   : NORMAL;
    				   float4 tangent  : TANGENT;
    			   };
    			   v2f vert(Input i)
    			   {
    				   v2f o;
    				   o.pos = UnityObjectToClipPos(i.Position);
    				   o.uv.xy = TRANSFORM_TEX(i.Texcoord, _MainTex);
    				   o.uv.zw = TRANSFORM_TEX(i.Texcoord, _BumpMap);
    
    				   float3 binormal = cross(i.Normal, i.tangent.xyz) * i.tangent.w;
    				   float3x3 rotation = float3x3(i.tangent.xyz, binormal, i.Normal);
    
    				   o.lightDir = mul(rotation, ObjSpaceLightDir(i.Position)).xyz;
    				   o.viewDir = mul(rotation, ObjSpaceViewDir(i.Position)).xyz;
    				   return o;
    			   }
    			   float4 frag(v2f i) :COLOR
    			   {
    				   float3 L = normalize(i.lightDir);
    				   //float3 N = normalize(i.Normal);
    				   float3 viewdir = normalize(i.viewDir); //视线
    
    				   fixed4 packedNormal = tex2D(_BumpMap, i.uv.zw);
    				   fixed3 tangentNormal;
    
    				   tangentNormal = UnpackNormal(packedNormal);
    				   tangentNormal.xy *= _BumpScale;
    				   tangentNormal.z = sqrt(1 - tangentNormal.x*tangentNormal.x - tangentNormal.y * tangentNormal.y);
    
    				   fixed3 albedo = tex2D(_MainTex, i.uv.xy).xyz*_Color.xyz;
    
    				   fixed3 spmask = tex2D(_SpecularMask, i.uv.xy).r*_SpecularScale;
    
    
    				   //漫反射=漫反射颜色 * 漫反射系数 * max(N,L);   saturate:这样是为了约束平滑到0-1之间
    				   float3 diff = _LightColor0.xyz* saturate(dot(L, tangentNormal))*albedo;
    				   //计算光线和法线相加得到的向量,单位化,再与法线夹角进行对比,入射光线离法线越近,夹角越大
    				   float3 halfdiff = normalize(L + tangentNormal);
    				   //环境光=环境光颜色 * 环境光系数
    				   float3 Ambiel = UNITY_LIGHTMODEL_AMBIENT.rgb*albedo;
    				   //反射光线计算=两倍的水平投影减去入射光线
    				   //float3 refl = normalize(reflect(-L,tangentNormal));
    				   //高光
    				   float3 Specul = _LightColor0.xyz* _Specular.xyz* pow(saturate(dot(tangentNormal, halfdiff)), _Gloss);
    				   Specul = Specul * spmask;
    				   //光照模型:自发光+镜面反射+漫反射+环境光
    				   fixed4 col = fixed4(Ambiel + diff + Specul,1);
    				 
    				   return col;
    			   }
    			   ENDCG
    		   }
    
    	   }
    

    计算高光时,将反射光线refl改成了halfdiff,可以试一下改回来有什么区别。也可以去掉spmask看看有什么区别@.@
    效果:
    在这里插入图片描述
    就酱,如果有错误,请提出来,我也是刚学没多久,233
    最后求一波三连QAQ

    展开全文
  • ShaderForge全翻译

    2018-10-11 17:17:59
    shader forge全翻译,学习shaderforge的必备良品,你懂我的意思,哈哈哈哈,大家看看,走过路过不要错过
  • ShaderForge 入门

    2018-08-15 14:12:49
    1,我们知道在Unity中修改物体颜色可以通过Material修改材质 至于如何通过数据控制不同效果,是由Shader实现的 2,ShaderForge的使用 一.安装说明 ~下载 ... 其他渠道下载ShaderForge Pack...

    1,我们知道在Unity中修改物体颜色可以通过Material修改材质

    至于如何通过数据控制不同效果,是由Shader实现的

    2,ShaderForge的使用

    一.安装说明

    ~下载

    1. Unity Asset Store购买并下载https://www.assetstore.unity3d.com/en/#!/content/14147
    2. 其他渠道下载ShaderForge Package。

    ~安装

    1. 将Package导入到Unity。
    2. Unity引擎菜单栏:Windows标签->Shader Forge打开插件使用界面

    二.界面说明

    ~打开插件后的界面

     

    New Shader:新建一个Shader文件

    Load Shader:导入已有的Shader文件

    PolyCount thread:PolyCount页面

    Unity:Unity Forum的页面,在Unity Asset Store上架的资源在Unity Forum均有页面,有问题可以去里面提问。

    Node Documentation:Shader Forge中的节点说明文档(重要)

    Wiki:Shader Forge的维基文档

     

    ~选择New Shader后的界面

     

    Unlit:无光照的Shader模板,选择此模板,使用该Shader的材质将不受光照影响。

    Lit(PBR):符合Unity PBR的Shader模板,采用基于物理的光照模型。

    Lit(Basic):使用Blinn-Phong光照模型的Shader模板。

    Custom Lighting:自定义光照Shader,在此Shader模板中实现自己的光照模型。

    Sprite:2D精灵Shader模板,基于2D。

    Particle(Additive):主要应用在发光效果的粒子Shader。

    Particle(Alpha-Blended):主要应用在细碎效果的粒子Shader,如风沙。

    Particle(Multiplicative):主要应用在昏暗效果的粒子Shader,如黑烟。

    Sky:天空。

    Post-Effect:屏幕空间后期处理Shader

     

    ~以选择Unlit模板进入的界面来说明

     

    红框区域为Shader的通道,黑色的通道为该Shader模板激活的通道,灰色通道为该Shader模板冻结的通道。只有激活的通道可以连接节点。

    红框区域常用通道:

    Diffuse:漫反射通道

    Specular:镜面反射通道

    Normal:法线通道

    Emission:自发光通道

    Opacity:不透明度通道

    橙色区域为节点,图中的节点是新建Shader后默认连接的Color节点。

    黄色区域为预览窗口,用来观察Shader效果。

    黄色区域上方属性:

    Return to menu:返回界面1。

    Settings:Shader Forge界面的一些设置,讲解见后文。

    Compile shader:编译为.shader文件,编译成功按钮为绿色,编译不成功or改动后按钮为红色。

    Auto:是否自动编译shader,建议选中。

    黄色区域内属性:

    属性1:选择预览的模型。

    属性2:预览窗口的背景色。

    Skybox:选择天空盒,在不受天空影响的模板中被冻结。

    Rotate:选中后模型自动旋转。

    紫色区域为相关属性选择列表,讲解见后文。

    三.简单案例

    根据目前移动平台的依旧广泛使用Blinn-Phong光照模型的特点,我们选择Lit(Basic)模板,来制作一个移动平台的Shader。通过简单的制作流程,来了解Shader Forge的基本使用。

     

    以上效果可以分解为漫反射通道制作,法线通道制作,高光通道制作,描边制作。

    具体步骤:

    1. 选择New Shader,在新界面中选择Lit(Basic)模板,修改你的文件名并选择文件路径确定。
    2. 预览窗口中的预览模型使用默认的球体,背景色改为白色,选中Rotate。
    3. 在节点编辑窗口中,鼠标左键拖动视图,将节点以及通道调整的合适的位置。
    4. 鼠标右键菜单中Properties->Texture2D,选中并在节点视窗生成一个Texture2D节点。(在Settings中,选中show node browser panel可以在屏幕右侧面板快速选中。)鼠标左键拖动到Color节点附近。
    5. 选中Texture2D节点,点击节点上出现的Select按钮,在出现的窗口中选择一张漫反射纹理贴图。
    6. 选中Color节点,点击节点上出现的颜色选择按钮,在出现的色盘中选择颜色。
    7. Arithemtic->Multiply生成一个Multiply(乘)节点,将Color和Texture2D的RGB输出引脚分别拖动连接到Multiply的A,B两个输入引脚上。(节点的右侧引脚为输出引脚,左侧引脚为输入引脚。连接方式为:节点1输出引脚——节点2输入引脚or通道)
    8. 调整三个节点的位置,Alt+鼠标左键框选三个节点并移动到通道附近,将Multiply的输出引脚连接到Diffuse通道上。
    9. 点击Compile Shader,建议Auto。这时可以看到预览窗口中已经有了纹理叠加颜色后的效果了。(color1*color2,等同于Photoshop中的正片叠底效果。)
    10. 重复步骤4生成一个Texture2D节点,重复步骤5选择一张法线贴图。
    11. 勾选Texture2D节点上的Normal map,并将上方的White改为Bump。(Normal map使用法线贴图必勾选,White修改为Bump使得在材质编辑器中选择一张Texture Type为Default类型的纹理时,会提醒你是否修复为Normal map。)
    12. 将法线纹理节点的RGB引脚连接到Normal通道上。预览窗口中的模型将表现出法线的凹凸效果,可以鼠标右键移动光源观察。
    13. 重复步骤4生成一个Texture2D节点,重复步骤5选择一张高光贴图。
    14. 将法线纹理节点的RGB/R/G/B/A引脚连接到Specular通道上。(高光贴图如果只占用一个通道,那就只选择相应的通道引脚连接。)
    15. Constant Vectors->Value,生成一个Value节点,输入0.05并连接到Outline Width通道,此时预览窗口可以看到黑色的轮廓边缘。
    16. Properties->Color,生成一个Color节点并修改颜色,连接到Outline Color通道,此时预览窗口可以看到相应颜色的轮廓边缘。
    17. 在左下角的属性选择列表区域,点开Properties标签,修改节点的名称(英文)。(或者在节点上方的label里修改。)里面每个属性标签都将暴露在材质编辑器界面供美术进行参数调节,修改的名称则是你在材质编辑器中看到属性名称。
    18. 上下拖动标签可以改变属性的顺序。

    但是调节边缘宽度的属性并没有暴露出去

    1. 将Value节点连接到Outline Width的线断开(Alt+鼠标右键),使用Properties->Value替换该节点。(Constant Vectors->Value生成的Value节点是常量,不可修改,也就不会暴露给编辑器。)
    2. 回到Unity,选择.shader文件并create material。

     

    基础操作和讲解见官方入门指南http://www.neatcorporation.com/Projects/ShaderForge/Media/ShaderForge_QuickStart-sc.pdf

    更多案例详见官方教程文档

    http://acegikmo.com/shaderforge/tutorials/

     

    四.节点

     

    节点在Shader Forge里面分为以上几个大类。

    1. Arithmetic:包含各种数学计算公式。常用abs(绝对值),Max/Min(最大/最小值),OneMinus(1-),Lerp(线性插值),Floor(向下取整),Multiply(乘)。
    2. Constant Vectors:常数变量,一维到四维以及4*4矩阵,不会暴露给材质编辑器。
    3. Properties:包含暴露给材质编辑器的各种属性。常用Color,Texture2D。
    4. UV Operations:针对UV的相关操作。
    5. Geometry Data:包括了几何体的输入数据,包括模型的UV,法线方向,世界坐标等等。
    6. Lighting:光照的相关数据,主要用于Custom Lighting Shader模板中。
    7. External Data:其他数据,包括视点位置,屏幕参数,时间等。
    8. Scene Data:场景数据,包括fog颜色,场景深度等信息。
    9. Math Constants:数学常量,如π。
    10. Trigonometry:三角函数。
    11. Code:代码块,函数块。
    12. Utility:略。

    节点详述请参考节点文档:http://acegikmo.com/shaderforge/nodes/?lang=zh_cn

    五.属性列表

    Shader Settings标签

    Path:文件路径,可修改。

    Fallback:在运行平台硬件不支持该shader的情况下,选择替代shader。

    Allow using atlased sprites:2D开发使用,3D默认即可。

    Draw call batching:批处理绘制调用,默认Enable。

    Inspector preview mode:3D/2D/sky,制作的什么类型选什么。

    Target renderers:目标渲染器,如无特殊需求,默认。

     

    Properties标签

     

    在此标签修改暴露给材质编辑器的属性名称(英文),顺序以及默认值。Texture2D没有默认值。
     

    Lighting标签

    Render Path:渲染路径,正向渲染或延迟渲染,移动平台选择正向渲染即可。

    Light Mode:光照模型,对应不同的Shader模板。分别是无光照(UnLit模板)、Blinn-Phong光照模型,Phong光照模型,PBL(基于物理光照,Lit(PBR)模板)。

    Gloss Mode:使用光泽度还是粗糙度模型,根据自己需要。

    Transparent Mode:透明度模式,淡出or反射。

    Remap gloss from [0,1] to [1,2048]:重映射光泽度从[0,1]到[1,2048]。

    Enery Conversing:能量守恒,PBR需要勾选。

    Lighting Count:光源数量,单一定向光(太阳光)or多重光源

    Lightmap & light probes:灯光贴图&灯光探针。

    Per-pixel light probe sampling:逐像素光照探针采样。

    Reflection probe support:支持反射探针。

    Receive Ambient Light:是否接受环境光。

    Mask directional light specular by shadows:定向光高光是否被阴影遮挡。

     

    Geometry标签

     

    Face Culling:面剔除,默认是剔除背面,可选剔除正面,也选择双面渲染。

    Normal Quality:法线质量,插值或归一化,默认使用归一化。

    Vertex Positioning:顶点位置,世界空间or裁剪空间or广告牌(法线面向摄像机)。

    Normal Space:法线空间选择,切线or建模or世界,默认切线空间。

    Vertex offset mode:顶点偏移模式,相对偏移or绝对偏移。基于模型空间的顶点偏移叫做相对偏移,世界空间的顶点偏移叫做绝对偏移。

    Tessellation Mode:曲面细分模式,一般不需要用到曲面细分。

    Outline Extrude Direction:描边挤出方向,一般都是沿着顶点法线方向。

    Per-pixel screen coodinates:逐像素屏幕坐标。

    Show 2D sprite pixel snap option in material:在材质中显示2D精灵像素单元设置,3D开发忽略。

     

    Blending标签

    Blend Mode:混合模式,如果是不透明的就选择Opaque,其余根据需要选择。

    Source*_+Destination*_:源*_+目标*_,决定了源图像与目标图像以哪种方式混合。

    Color Mask:颜色遮罩,需要过滤的通道取消选择。

    Dithered alpha clip:抖动透明裁剪,开or关。

    Offset Factor:偏移因子。

    Offset Units:偏移单位。

    Per-object refraction/scene color (expensive):

    Receive Fog:应用雾。

    Auto Sort:自动排序,如需手动改变排序,在Order中改变数值。数值越小,在渲染队列越靠前。

    Depth Test:深度测试。

    Ignore Projectors:忽略投影器。

    Write to Depth buffer:是否写入深度缓存。

    Stencil Buffer:是否开启模板缓存。

     

    Settings内容

    Real-time node rendering:实时节点渲染,是否开启看需求。

    Using scroll in the quickpicker:在快速拾取中使用滚动。

    Show variable name & precision:显示变量名和精度,看需求开启。

    Show node browser panel:显示节点浏览面板,是否开启看个人习惯。

    Hierarchal Node Move:层次节点移动。

    六.优化

    1. 节点尽量精简。
    2. 浮点精度降低,开启Show variable name & precision后,每个节点会显示变量名称和精度。针对移动平台,需要降低浮点精度以符合GPU的需求。Float/Half/Fixed精度分别为32/16/11位。常规颜色使用fixed,包括纹理数据;短向量,方向,模型空间坐标以及高动态范围颜色用half;世界空间坐标,纹理坐标,以及需要复杂计算的三角函数,指数幂函数计算使用float。
    3. 计算过程中,尽量避免数据类型转换。

     

     

    展开全文
  • // Shader Forge (c) Neat Corporation / Joachim Holmer - http://www.acegikmo.com/shaderforge/ //对Shader Forge 内置折射节点的研究 //使用了一个名为Test的Color属性来确定SF如何使用节点的输入数据,此...
  • Shaderforge Normal通道 一、官方介绍 normal通道输入切线空间中的法线方向,你可以连接法线贴图或者法向量到该通道。 用于使用光照的明暗模拟凹凸效果。 二、通道的输入 Normal通道输入的数据为存储着...
  • ShaderForge插件介绍详解

    万次阅读 多人点赞 2017-12-19 21:41:47
    ShaderForge简介ShaderForge是适用于Unity,基于节点的着色器编辑器 。它可让您更轻松地创建自己的着色器 ,而不需要使用代码。开始以之前我想你已经下载好了插件,如果没有的话可以从下方的链接获取。前言1.官网...
  • shaderforge外描边 节点说明 shaderforge描边通道的原理 限制 UnityShader实现OutLine通道功能 ...shaderforge描边通道的原理其实是将模型店沿法线方向向外挤出outline width的大小(相当于模型大小变为
  • Shader Forge插件使用指南

    千次阅读 2018-03-02 13:58:26
    【Unity】Shader Forge插件入门教程一.安装说明~下载Unity .../content/14147其他渠道下载ShaderForge Package。~安装将Package导入到Unity。Unity引擎菜单栏:Windows标签->Shader Forge打开插件使用界...
  • shader主要实现效果: (1)法线贴图使用; (2)利用法线贴图影响表面发射计算Specular; 主要代码: //切线空间和世界空间计算 法线 贴图的使用; //制作人:嘿皮土豆; //参考:《Unity Shader入门精要》 ...
  • 法线方向:物体表面网格的法线方向 点积:也叫点乘,两个向量进行点乘计算,可以计算出a向量和b向量的位置关系,a·b>0,说明a点在b点的后方,当a·b<0,则反之a点在b点的前方 创建Shader资产 打开S
  • 环境 系统:Windows 10 引擎:Unity 2017.2.1f1 插件:Shader Forge 1.38 工具:Photoshop ...Shader Forge使用噪声纹理制作...(1-2)法线纹理,使用Shader Forge自带。 (1-3)噪声纹理,使用Shader Forge自...
  • Shader Forge中文帮助手册

    万次阅读 2016-11-12 16:58:20
    Shader Forge中文帮助手册 这是您的所有其他节点最终将链接到的节点。它拥有为不同目的服务的多个输入。 以下动画图像显示所有输入及其随时间变化的行为。大部分输入会在 0 和 1(黑色和白色)之间来回绘制...
  • ShaderForge-数据

    千次阅读 2017-12-20 21:39:57
    ShaderForge-数据在进行ShaderForge的学习之前,我们先来了解下Shader中的数据。 什么是数据,一切信息都是数据。数值,颜色,贴图,法线信息,UV信息,都是数据。 ShaderForge的节点连接,就是对数据的加工处理...
  • Shader Forge教程二版

    千次阅读 2017-04-25 16:24:58
    Shader Forge 第一讲:制作一个简单的Shader Shader Forge是当今Asset Store上最火热的Shader可视化编辑工具,并获得了Unity3D 2014技术奖。本系列主要介绍如何使用该插件。本系列教程中Shader Forge简称SF。 第...
  • Unity3D引擎之Shader Forge应用

    千次阅读 2017-04-04 17:52:42
    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀...CSDN视频网址:http://edu.csdn.net/lecturer/144 本篇博客给读者介绍一个材质渲染的组件-Shader Forge,在材质渲染中可以起到事半功倍的效果
  • Shader Forge 参数详解

    千次阅读 2017-09-04 14:38:28
    http://acegikmo.com/shaderforge/nodes/?lang=zh_cn Main (主要) 这是您的所有其他节点最终将链接到的节点。它拥有为不同目的服务的多个输入。 以下动画图像显示所有输入及其随时间变化...
  • shader forge制作兰伯特模型与代码的对比。
  • Shader Forge的节点分类

    千次阅读 2016-05-29 09:00:45
    比如法线信息、深度信息(Depth)、物体的位置(Screen Position)、缩放信息(Object Scale)、模型的顶点信息(World Position)。 UV坐标( UV Coordinate) 7、Lighting 光照节点 获取 灯光信息。 ...
  • 在加入了漫反射与高光后,再给材质添加菲涅尔(Fresnel)反射,并让环境光对它产生影响。(3)菲涅尔(Fresnel)反射当光入射到折射率不同的两个媒质分界面时,一...ShaderForge直接封装菲涅尔反射方法 提供Nrm(...
  • ShaderForge-河流效果

    千次阅读 2017-12-22 19:47:58
    ShaderForge-河流效果本系列开始进行ShaderForge实战案例分析,案例的参考来源自朧老师的ShaderForge教程。 附带教程链接地址:http://www.aboutcg.org/?s=shaderForge&post_type=course。 文末我会提供相关使用的...
  • 使用shader forge完成一个控制法线贴图深度的效果。
  • Shaderforge Diffuse通道 一、官方介绍 漫反射通道的数据是你的着色器的主要颜色。漫反射颜色会接收到光照,光照强度会沿着灯光方向衰弱,并形成阴影。 二、通道的输入 1. Diffuse 可以是颜色也可以是...
  • 【Unity】Shader Forge插件入门教程 说明:现在Unity2018都提供了官方的ShaderGraph,建议学新不学旧,学官方不学第三方。——2018.6.21 一.安装说明 ~下载 Unity Asset Store购买...其他渠道下载ShaderForge...
  • shaderforge物理信息 Bitangent Dir 切线坐标系转换到世界坐标系 参考 Depth Face Sign 参考 Fresnel Normal Direction Object Position Object Scale Screen Position Tangent Direction UV Coordinate Vertex ...
  • 【Unity】ShaderForge插件入门教程 一.安装说明 ~下载 Unity Asset Store购买并下载https://www.assetstore.unity3d.com/en/#!/content/14147其他渠道下载ShaderForge Package。 ~安装 将Package导入到Unity。...
  • shader forge笔记

    2018-04-09 21:36:48
    Unlit:不会受到光照影响lit:有光照(高光阴影),基于物理的材质,比较消耗性能Custom lighting:自定义光照shadersprite:基于2D;partical(additive):主要应用在发光效果的粒子shader;partical(alpha-blended):主要...
  • ShaderForge 之外发光

    2019-08-26 15:55:38
    连线 菲涅尔实现原理就是法线和视角法线的点积运算,并且只截取正数部分 效果

空空如也

空空如也

1 2 3 4 5 ... 11
收藏数 220
精华内容 88
关键字:

shaderforge 法线