Unity shader - 纹理采样

这篇具有很好参考价值的文章主要介绍了Unity shader - 纹理采样。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.什么是UV  

2.凹凸纹理

3.渐变纹理映射

4.遮罩纹理


1.什么是UV  

对于三维模型,有两个最重要的坐标系统,一是顶点的位置(X,Y,Z)坐标,另一个就是UV坐标。什么是UV?简单的说,就是贴图影射到模型表面的依据。 完整的说,其实应该是UVW(因为XYZ已经用过了,所以另选三个字母表示)。U和V分别是图片在显示器水平、垂直方向上的坐标,取值一般都是0~1,也 就是(水平方向的第U个像素/图片宽度,垂直方向的第V个像素/图片高度)。那W呢?贴图是二维的,何来三个坐标?嗯嗯,W的方向垂直于显示器表面,一般 用于程序贴图或者某些3D贴图技术(记住,确实有三维贴图这种概念!),对于游戏而言不常用到,所以一般我们就简称UV了。

定义纹理:

Properties
{
    // 主纹理
    _MaxTex ("_MaxTex",2d) = "white" {}
}

sampler2D _MaxTex;
float4 _MaxTex_ST;

unity 纹理采样,Shader,unity,贴图,游戏引擎

_MainTex_ST:表示该纹理的偏移缩放属性,在属性面板上表现出tilling 和 offset ,float4 类型xy 存的是缩放  zw 存的是偏移

通过 _MainTex_ST 重新计算uv  texcord *_MainTex_ST.xy+_MainTex_ST.zw

 或者使用内置方法 TRANSFORM_TEX(uv,_MainTex)

tex2D(_MainTex,uv) 对_MainTex采样,得到该uv 坐标下的颜色

上完整代码:这里加了漫反射和高光的代码有不懂的可以看:漫反射,高光反射

Shader "Unlit/005"
{
    Properties
    {
        // 漫反射颜色
        _Diffuse ("Diffuse",Color) = (1,1,1,1)
        // 高光反射颜色值
        _Specular ("Specular",Color) = (1,1,1,1)
        // 高光反射值
        _Gloss ("_Gloss",range(1,100)) = 5
        // 主纹理
        _MaxTex ("_MaxTex",2d) = "white" {}
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            
            sampler2D _MaxTex;
            float4 _MaxTex_ST;
            float4 _Specular;
            float4 _Diffuse;
            float _Gloss;
            
            struct v2f
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD1;
                float3 worldNormal : TEXCOORD0;
                float3 viewDir : TEXCOORD2;
            };

            v2f vert (appdata_base v)
            {
                v2f o;
                // 将对象空间中的点变换到齐次坐标中的摄像机裁剪空间
                o.vertex = UnityObjectToClipPos(v.vertex);
                // 计算uv坐标
                o.uv = TRANSFORM_TEX(v.texcoord,_MaxTex);
                // o.uv = v.texcoord.xy * _MaxTex_ST.xy + _MaxTex_ST.zw;
                o.worldNormal = UnityObjectToWorldNormal(v.normal);
                o.viewDir = normalize(WorldSpaceViewDir(o.vertex));
                return o;   
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // 纹理采样
                float3 texColor = tex2D(_MaxTex,i.uv);

                // 计算漫反射
                float3 diffuse = texColor * _LightColor0.rgb * _Diffuse.rgb * (dot(_WorldSpaceLightPos0.xyz,i.worldNormal) * 0.5 + 0.5);
                // 计算高光
                float3 halfVector = normalize(normalize(_WorldSpaceLightPos0.xyz) + i.viewDir);
                // 计算高光
                float3 specular = texColor * _LightColor0.rgb * _Specular.rgb * pow(max(0,dot(halfVector,i.worldNormal)),_Gloss);
                
                return float4(diffuse + specular,1);
            }
            ENDCG
        }
    }
}

unity 纹理采样,Shader,unity,贴图,游戏引擎

2.凹凸纹理

凹凸纹理的本质是通过一张存储了顶点法线坐标的图片,营造出一种凹凸的效果,模型本身并没有改变

为什么改变了法线就能营造出凹凸的结果,因为法线的作用就是就算光照,现实生活中,你看到的物体觉得很立体,就是因为光照到物体上产生了阴影,有明暗区分,所以觉得很立体,凹凸贴图通过改变法线,间接改变了光照的方向,和阴影产生的结果,让你看起来有种立体的感觉。

unity 纹理采样,Shader,unity,贴图,游戏引擎

凹凸纹理 分为两种:
  • 高度贴图:高度贴图,存储的并不是顶点的法线,而是强度值,表示该像素的海拔高度,颜色越深,表示越往里凹,因为越凹越看不见,如上高度映射图,越白的地方高度越高,越黑的地方高度越低,需要根据灰度值,转到表面法线计算比较复杂,也不利于美术制作。

  • 法线贴图: 存储的就是顶点的法线坐标.

法线纹理中存储的是表面的法线方向。由于法线方向的各个分量范围在[ − 1 , 1 ] 之间,而像素的分量范围在[ 0 , 1 ] 之间,所以需要进行映射

pixel=normal∗0.5+0.5

所以,我们在Shader中对法线纹理进行纹理采样后,还要对结果进行一次逆映射,即

normal=pixel∗2−1

为什么法线贴图大部分都是浅蓝色呢?

浅蓝色表示改法线贴图存储的是切线空间下的法线,顶点的原始法线是(0,0,1),映射到像素上RGB(0.5,0.5,1),浅蓝色.

法线贴图有两种形式:

  • 模型空间下的法线坐标
  • 切线空间下的法线坐标

模型空间法线:

优点: 直接就能获取到模型的法线,不需要空间转换,因为所有的法线都是在同一坐标空间下,所以边角处通过线性插值得到的效果更加平滑.

缺点:因为 模型空间存储的是绝对法线,只适用于创建该法线的的模型,如果换个模型就得不到正确的结果,且无法进行uv偏移,

切线空间下法线

  • 自由度更高。
  • 切线空间下的法线纹理是相对的法线纹理,即使在不同网格上也可以得到合理的结果。
  • 可以进行uv 动画,可以通过移动一个纹理的uv坐标来实现凹凸移动的效果。
  • 可以重用法线纹理。
  • 可以压缩,切线空间下,z轴总是正方向的,可以同过xy推导出 z坐标 = sqrt(1-max(0,dot(xy,xy)))。

如何实现?

要计算光照,就要统一坐标空间,要么在切线空间,要么在世界空间。

切线空间: 在顶点中将 光源方向 和 视角方向 转换到切线空间然后在片元中计算光照模型

世界空间:法线转换到世界空间下,因为有时候我们需要用到世界空间下的法线坐标和光照方向比如对cubemap 进行环境采样,因为纹理坐标是逐像素的,所以要在片元着色器中进行采样然后进行一个矩阵变换,比上面多了一次矩阵运算。

我们先来实现以下 切线空间的纹理映射:

接下来需要将光源方向和视角方向变换到切线空间,要完成这步操作需要求出变换所需的旋转矩阵。我们已知的是变换后的三个向量:

  • b = (0,1,0)
  • t = (1,0,0)
  • n = (0,0,1)

假设变换前的三个向量为:

  • b′ = ( xb,yb,zb) 
  • t′ = (xt,yt, zt)
  • n′ = ( xn,yn,zn)

变换矩阵为 :

unity 纹理采样,Shader,unity,贴图,游戏引擎

 可以求得 c1  = t′ , c2 = b′ , c3 = n′ 。

shader 代码:

// 求副切线向量 float3 biNormal = cross(normalize(v.normal),normalize(v.tangent.xyz))*v.tangent.w; // 求出旋转矩阵 float3x3 rotation = float3x3(v.tangent.xyz,biNormal,v.normal);

可以使用unity内置的自定义写法

TANGENT_SPACE_ROTATION

在 UnityCG.cginc中 实际上就是帮我们写了上面求出的切线空间旋转变换矩阵

unity 纹理采样,Shader,unity,贴图,游戏引擎

unity 纹理采样,Shader,unity,贴图,游戏引擎

Shader "Unlit/006"
{
    Properties
    {
        // 漫反射颜色
        _Diffuse ("Diffuse",Color) = (1,1,1,1)
        // 高光反射颜色值
        _Specular ("Specular",Color) = (1,1,1,1)
        // 高光反射值
        _Gloss ("_Gloss",range(1,100)) = 5
        // 主纹理
        _MaxTex ("MaxTex",2d) = "white" {}
        // 法线纹理
        _BumpMap ("Bump Map",2d) = "white" {}
        // 控制凹凸程度
        _BumpScale ("Bump Scale",float) = 1
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM 
            #pragma vertex vert
            #pragma fragment frag
            
            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            
            sampler2D _MaxTex;
            float4 _MaxTex_ST;
            float4 _Specular;
            float4 _Diffuse;
            float _Gloss;
            
            sampler2D _BumpMap; 
            float4 _BumpMap_ST;
            float _BumpScale;
            
            struct v2f
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float2 normalUv : TEXCOORD1;
                float3 lightDir : TEXCOORD2;
                float3 viewDir : TEXCOORD3;
            };

            v2f vert (appdata_tan v)
            {
                v2f o;
                // 将对象空间中的点变换到齐次坐标中的摄像机裁剪空间
                o.vertex = UnityObjectToClipPos(v.vertex);
                // 计算uv坐标
                o.uv = TRANSFORM_TEX(v.texcoord,_MaxTex);
                o.normalUv = v.texcoord.xy * _BumpMap_ST.xy + _BumpMap_ST.zw;
                
                // TANGENT_SPACE_ROTATION
                // 求副切线向量
	            float3 biNormal = cross(normalize(v.normal),normalize(v.tangent.xyz))*v.tangent.w;
	            // 求出旋转矩阵
            	float3x3 rotation = float3x3(v.tangent.xyz,biNormal,v.normal);
            	
            	// 求切线空间的光源方向
            	o.lightDir = normalize(mul(rotation,UnityWorldToObjectDir(_WorldSpaceLightPos0.xyz)));
            	// 切线空间视角方向
            	o.viewDir = normalize(mul(rotation,ObjSpaceLightDir(v.vertex)));
            	
                return o;   
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // 主纹理采样
                fixed4 texColor = tex2D(_MaxTex,i.uv);
                // 法线贴图采样
                fixed4 packedNormal = tex2D(_BumpMap,i.normalUv);
                fixed3 tangentNormal;
                tangentNormal.xy = (packedNormal.xy * 2 - 1 ) * _BumpScale;
                tangentNormal.z = sqrt(1 - max(0,dot(tangentNormal.xy,tangentNormal.xy)));
                
                // 用内置方法 UnpackNormal 图片类型为NormalMap  
                //fixed3 tangentNormal = UnpackNormal(packedNormal);  
                // tangentNormal.xy *= _BumpScale;

                // 计算漫反射
                float3 diffuse = texColor.rgb * _LightColor0.rgb * _Diffuse.rgb * (dot(i.lightDir,tangentNormal) * 0.5 + 0.5);
                // 计算高光
                float3 halfVector = normalize(i.lightDir + i.viewDir);
                // 计算高光
                float3 specular = texColor.rgb * _LightColor0.rgb * _Specular.rgb * pow(max(0,dot(halfVector,tangentNormal)),_Gloss);
                
                return float4(diffuse + specular,1);
            }
            ENDCG
        }
    }
}

给上主纹理贴图,和法线贴图,法线贴图可以用主纹理在PhotoShop中,滤镜->3D->生成法线贴图就制作好了,不过下项目中通常是美术给的

unity 纹理采样,Shader,unity,贴图,游戏引擎unity 纹理采样,Shader,unity,贴图,游戏引擎

shader效果如下:左边是没用法线的,右边是加了法线纹理的可以看出加了法线纹理更有凹凸感

unity 纹理采样,Shader,unity,贴图,游戏引擎

我们在用 世界空间纹理映射实现以下:

我们需要在顶点着色器中计算出从切线空间转换到世界空间的变换矩阵,但一个插值寄存器最多只能存储float4大小的变量,所以对于矩阵这种变量,我们需要定义三个float3类型的变量拆开存储。但为了充分利用插值寄存器的空间,我们将其定义为float4类型,多出来的一个维度可以用来存储世界空间下的顶点位置。uv变量也可以定义成float4类型,其中xy分量用来存储贴图纹理坐标,zw分量用来存储法线纹理坐标。

直接上代码了,都在代码里详细备注:

Shader "Unlit/007"
{
    Properties
    {
        // 漫反射颜色
        _Diffuse ("Diffuse",Color) = (1,1,1,1)
        // 高光反射颜色值
        _Specular ("Specular",Color) = (1,1,1,1)
        // 高光反射值
        _Gloss ("_Gloss",range(1,100)) = 5
        // 主纹理
        _MaxTex ("MaxTex",2d) = "white" {}
        // 法线纹理
        _BumpMap ("Bump Map",2d) = "white" {}
        // 控制凹凸程度
        _BumpScale ("Bump Scale",float) = 1
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM 
            #pragma vertex vert
            #pragma fragment frag
            
            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            
            sampler2D _MaxTex;
            float4 _MaxTex_ST;
            float4 _Specular;
            float4 _Diffuse;
            float _Gloss;
            
            sampler2D _BumpMap; 
            float4 _BumpMap_ST;
            float _BumpScale;
            
            struct v2f
            {
                float4 vertex : POSITION;
                float4 uv : TEXCOORD0;
                float4 T2w0 : TEXCOORD1;
                float4 T2w1 : TEXCOORD2;
                float4 T2w2 : TEXCOORD3;
            };

            v2f vert (appdata_tan v)
            {
                v2f o;
                // 将对象空间中的点变换到齐次坐标中的摄像机裁剪空间
                o.vertex = UnityObjectToClipPos(v.vertex);
                // 计算uv坐标
                o.uv.xy = TRANSFORM_TEX(v.texcoord,_MaxTex);
                o.uv.zw = TRANSFORM_TEX(v.texcoord,_BumpMap);
                float2 normalUv = v.texcoord.xy * _BumpMap_ST.xy + _BumpMap_ST.zw;
               
                fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
                fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
                fixed3 worldBiTangent = cross(worldTangent,worldNormal) * v.tangent.w;
            	fixed3 worldPos = UnityObjectToWorldDir(v.vertex.xyz);
            	
            	o.T2w0 = float4(worldTangent.x,worldBiTangent.x,worldNormal.x,worldPos.x); 
            	o.T2w1 = float4(worldTangent.y,worldBiTangent.y,worldNormal.y,worldPos.y); 
            	o.T2w2 = float4(worldTangent.z,worldBiTangent.z,worldNormal.z,worldPos.z); 
            	
                return o;   
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // 主纹理采样
                fixed4 texColor = tex2D(_MaxTex,i.uv.xy);
                // 法线贴图采样
                fixed4 packedNormal = tex2D(_BumpMap,i.uv.zw);
                
                
                //fixed3 tangentNormal;
                //tangentNormal.xy = (packedNormal.xy * 2 - 1 ) * _BumpScale;
                //tangentNormal.z = sqrt(1 - max(0,dot(tangentNormal.xy,tangentNormal.xy)));
                
                // 用内置方法 UnpackNormal 图片类型为NormalMap  
                fixed3 tangentNormal = UnpackNormal(packedNormal);  
                tangentNormal.xy *= _BumpScale;
                
                // 将切线空间法线变换到世界空间
                fixed3 worldNormal = normalize(fixed3(dot(i.T2w0.xyz,tangentNormal),dot(i.T2w1.xyz,tangentNormal),dot(i.T2w2.xyz,tangentNormal)));

                // 计算漫反射
                float3 diffuse = texColor.rgb * _LightColor0.rgb * _Diffuse.rgb * (dot(_WorldSpaceLightPos0.xyz,worldNormal) * 0.5 + 0.5);
                // 计算高光
                float3 viewDir = _WorldSpaceCameraPos.xyz - float3(i.T2w0.z,i.T2w1.z,i.T2w2.z);
                float3 halfVector = normalize(_WorldSpaceLightPos0.xyz + viewDir);
                // 计算高光
                float3 specular = texColor.rgb * _LightColor0.rgb * _Specular.rgb * pow(max(0,dot(halfVector,worldNormal)),_Gloss);
                
                return float4(diffuse + specular,1);
            }
            ENDCG
        }
    }
}

效果如下:分别为 无法线贴图,切线空间纹理映射,世界空间纹理映射

unity 纹理采样,Shader,unity,贴图,游戏引擎

3.渐变纹理映射

纹理不止能用来定义一个物体的颜色,也可以用来存储任何表面的属性。一种常见的用法就是使用渐变纹理来控制漫反射光照的结果。使用一张从冷到暖的渐变图片用于纹理采样,并将采样结果用于计算漫反射模型。就可以得到一种插画风格的渲染效果,物体的轮廓线相比于传统的漫反射更加明显。很多卡通风格的渲染中都使用了这种技术。

Shader "Unlit/008"
{
    Properties
    {
        // 漫反射颜色
        _Diffuse ("Diffuse",Color) = (1,1,1,1)
        // 高光反射颜色值
        _Specular ("Specular",Color) = (1,1,1,1)
        // 高光反射值
        _Gloss ("_Gloss",range(1,100)) = 5
        // 主纹理
        _MaxTex ("_MaxTex",2d) = "white" {}
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM 
            #pragma vertex vert
            #pragma fragment frag
            
            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            
            sampler2D _MaxTex;
            float4 _MaxTex_ST;
            float4 _Specular;
            float4 _Diffuse;
            float _Gloss;
            
            struct v2f
            {
                float4 vertex : POSITION;
                float3 worldNormal : TEXCOORD0;
                float3 viewDir : TEXCOORD2;
            };

            v2f vert (appdata_base v)
            {
                v2f o;
                // 将对象空间中的点变换到齐次坐标中的摄像机裁剪空间
                o.vertex = UnityObjectToClipPos(v.vertex);
                // 计算uv坐标
                //o.uv = TRANSFORM_TEX(v.texcoord,_MaxTex);
                // o.uv = v.texcoord.xy * _MaxTex_ST.xy + _MaxTex_ST.zw;
                o.worldNormal = UnityObjectToWorldNormal(v.normal);
                o.viewDir = normalize(WorldSpaceViewDir(o.vertex));
                return o;   
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // 半兰伯特漫反射
                float halfLambert = (dot(_WorldSpaceLightPos0.xyz,i.worldNormal) * 0.5 + 0.5);
                // 采样渐变纹理 使用半兰伯特做uv坐标
                float3 texColor = tex2D(_MaxTex,float2(halfLambert,halfLambert));
                float3 diffuse = texColor * _LightColor0.rgb * _Diffuse.rgb * texColor;
                // 计算高光
                float3 halfVector = normalize(normalize(_WorldSpaceLightPos0.xyz) + i.viewDir);
                // 计算高光
                float3 specular = texColor * _LightColor0.rgb * _Specular.rgb * pow(max(0,dot(halfVector,i.worldNormal)),_Gloss);
                
                return float4(diffuse + specular,1);
            }
            ENDCG
        }
    }
}

效果:

unity 纹理采样,Shader,unity,贴图,游戏引擎

4.遮罩纹理

在游戏中地形场景中,假设有草地和沙漠的接壤处,为了保护各自区域的反射值,我们就会用到了遮罩纹理,假设草地需要高光,沙漠不需要高光。

实现非常简单,就是增加一张遮罩纹理,需要高光的为白色,不需要的地方为黑色,因为白色的rgb值为 255/255 = 1。同常只需要一个通道就可以实现了,然后在计算高光的地方 乘上遮罩的采样值。

Shader "Unlit/009"
{
    Properties
    {
        // 漫反射颜色
        _Diffuse ("Diffuse",Color) = (1,1,1,1)
        // 高光反射颜色值
        _Specular ("Specular",Color) = (1,1,1,1)    
        // 高光反射值
        _Gloss ("_Gloss",range(1,100)) = 5
        // 主纹理
        _MaxTex ("_MaxTex",2d) = "white" {}
        // 高光遮罩纹理
        _SpecularMask ("Specular Mask",2d) =  "white" {}
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM 
            #pragma vertex vert
            #pragma fragment frag
            
            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            
            sampler2D _MaxTex;
            float4 _MaxTex_ST;
            sampler2D _SpecularMask;
            float4 _SpecularMask_ST;
            float4 _Specular;
            float4 _Diffuse;
            float _Gloss;
            
            struct v2f
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float2 maskUv : TEXCOORD1;
                float3 worldNormal : TEXCOORD2;
                float3 viewDir : TEXCOORD3;
            };

            v2f vert (appdata_base v)
            {
                v2f o;
                // 将对象空间中的点变换到齐次坐标中的摄像机裁剪空间
                o.vertex = UnityObjectToClipPos(v.vertex);
                // 计算uv坐标
                o.uv = TRANSFORM_TEX(v.texcoord,_MaxTex);
                o.maskUv = TRANSFORM_TEX(v.texcoord,_SpecularMask);
                // o.uv = v.texcoord.xy * _MaxTex_ST.xy + _MaxTex_ST.zw;
                o.worldNormal = UnityObjectToWorldNormal(v.normal);
                o.viewDir = normalize(WorldSpaceViewDir(o.vertex));
                return o;   
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float3 texColor = tex2D(_MaxTex,i.uv);
                // 半兰伯特漫反射
                float halfLambert = (dot(_WorldSpaceLightPos0.xyz,i.worldNormal) * 0.5 + 0.5);
                // 采样渐变纹理 使用半兰伯特做uv坐标
                float3 diffuse = texColor * _LightColor0.rgb * _Diffuse.rgb * halfLambert;
                // 计算高光
                float3 halfVector = normalize(normalize(_WorldSpaceLightPos0.xyz) + i.viewDir);
                // 采样遮罩纹理
                float3 maskColor = tex2D(_SpecularMask,i.maskUv);
                // 计算高光
                float3 specular = texColor * _LightColor0.rgb * _Specular.rgb * pow(max(0,dot(halfVector,i.worldNormal)),_Gloss) * maskColor;
                
                return float4(diffuse + specular,1);
            }
            ENDCG
        }
    }
}

地形图:unity 纹理采样,Shader,unity,贴图,游戏引擎      遮罩图:unity 纹理采样,Shader,unity,贴图,游戏引擎 

 效果如下:左边是不加遮罩纹理,右边是加了遮罩纹理。

可以看出,不加遮罩纹理两边都有高光。

unity 纹理采样,Shader,unity,贴图,游戏引擎文章来源地址https://www.toymoban.com/news/detail-721987.html

到了这里,关于Unity shader - 纹理采样的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 自制游戏引擎之shader预编译

    shader预编译为二进制,在程序运行时候加载,可以提升性能,节省启动时间. third_party文件里需要放依赖的第三方 因为电脑访问google的问题,无法通过 shaderc-2023.4utilsgit-sync-deps 脚本自动下载第三方,手动下载 https://codeload.github.com/KhronosGroup/SPIRV-Tools/zip/refs/tags/v2023.3.rc1 https://codeloa

    2024年02月13日
    浏览(41)
  • 第二十四章 Unity 纹理贴图

    通常情况下,3D网格模型只能展示游戏对象的几何形状,而表面的细节则纹理贴图提供。纹理贴图通过UV坐标“贴附”在模型的表面。当然,这个过程不需要我们在Unity中完成,而是在建模软件中完成的。通常情况下,我们通过3ds max或者maya制作完网格模型后,需要进行一个“

    2024年02月05日
    浏览(40)
  • 【Overload游戏引擎细节分析】standard材质Shader

    提示:Shader属于GPU编程,难写难调试,阅读本文需有一定的OpenGL基础,可以写简单的Shader,不适合不会OpenGL的朋友 一、Blinn-Phong光照模型 Blinn-Phong光照模型,又称为Blinn-phong反射模型(Blinn–Phong reflection model)或者 phong 修正模型(modified Phong reflection model),是由 Jim Blinn于

    2024年02月08日
    浏览(38)
  • 【Overload游戏引擎细节分析】Lambert材质Shader分析

    一、经典光照模型:Phong模型 现实世界的光照是极其复杂的,而且会受到诸多因素的影响,这是以目前我们所拥有的处理能力无法模拟的。经典光照模型冯氏光照模型(Phong Lighting Model)通过单独计算光源成分得到综合光照效果,然后添加到材质表面特定的点。冯光照模型的主要

    2024年02月08日
    浏览(39)
  • 【Overload游戏引擎细节分析】PBR材质Shader---完结篇

    PBR基于物理的渲染可以实现更加真实的效果,其Shader值得分析一下。但PBR需要较多的基础知识,不适合不会OpenGL的朋友。 一、PBR理论 PBR指基于物理的渲染,其理论较多,需要的基础知识也较多,我在这就不再写一遍了,具体可以参看: LearnOpenGL PBR理论-英文 或者 LearnOpenGL

    2024年02月08日
    浏览(42)
  • 【Overload游戏引擎细节分析】画场景栅格的Shader分析

    Overload引擎地址: GitHub - adriengivry/Overload: 3D Game engine with editor 一、栅格绘制基本原理 Overload Editor启动之后,场景视图中有栅格线,这个在很多软件中都有。刚开始我猜测它应该是通过绘制线实现的。阅读代码发现,这个栅格的几何网格只有两个三角形面片组成的正方形,使

    2024年02月07日
    浏览(40)
  • 【Unity Shader】Shader Graph

    shader graph 入门: (对基础内容进行详细介绍) Shader Graph入门-CSDN博客 unity-shader(入门)_unity3d shader-CSDN博客 各种效果的节点配置: 【unity造轮子】Unity ShaderGraph使用教程与各种特效案例(2023/12/1更新)_unity特效-CSDN博客 大佬文章里所用的PBR Master更新后已经没有了,所以参考

    2024年02月01日
    浏览(57)
  • Unity Shader variants (shader 变体)

    官方地址 https://docs.unity3d.com/cn/2022.2/Manual/SL-MultipleProgramVariants.html 教程可以看这里 https://www.jianshu.com/p/48ad75f0b4b9 https://www.jianshu.com/p/3e6b84317097 变种用我自己的理解就是 能用程序控制的shader 举个例子 这里声明了 a b c d 四个变量(其实是开关 下面会说) 记住 #pragma multi_compil

    2024年02月12日
    浏览(35)
  • Unity | Shader基础知识(第一集:unity中最简单的shader)

    目录 一、unity的shader 二、创建一个shader(在创建时,选前三种都可以) 三、内容解读 1.shader一直都在 2.我们写shader在写什么 四、没有被干预的shader(最简单的shader) 相关阅读 编写着色器概述 - Unity 手册 一、unity的shader unity写的shader并不是真正意义上的shader。 官方解释:

    2024年02月04日
    浏览(51)
  • 【Unity Shader】Unity阴影

    记录下在unity中如果想实现阴影,有哪些路子可以选择,目前看有两种 1.经典的shadowmap 2.planar projection 如果开启renderer组件的cast shadows为on,开启平行光的light组件的shadow type,那么就会在物体shader中寻找LightMode=ShadowCaster的Pass进行渲染 场景有两个物体,平面和球体,使用unity内

    2024年02月09日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包