Unity Shader学习笔记:渲染纹理
2017-08-29 19:00
806 查看
一个摄像机的渲染结果会输出到颜色缓冲中,并显示到我们的屏幕上。现代的GPU允许我们把整个三维场景渲染到一个中间缓冲中,即渲染目标纹理。
渲染纹理:Unity为渲染目标纹理定义的一种专门的纹理类型。在Unity中使用渲染纹理通常有两种方式:一种方式是在Project目录下创建一个渲染纹理,然后把某个摄像机的渲染目标设置成该渲染纹理,这样一来该摄像机的渲染结果就会实时更新到渲染纹理中,而不会显示在屏幕上。使用这种方法,我们可以选择渲染纹理的分辨率、滤波模式等纹理属性。另一种方式是在屏幕后处理时使用GrabPass命令或OnRenderImage函数来获取当前屏幕图像,Unity会把这个屏幕图像放到一张和屏幕分辨率等同的纹理中。
1.镜子效果
其中Texture需要拖拽到该摄像机的Target Texture下。
2.玻璃效果
渲染纹理:Unity为渲染目标纹理定义的一种专门的纹理类型。在Unity中使用渲染纹理通常有两种方式:一种方式是在Project目录下创建一个渲染纹理,然后把某个摄像机的渲染目标设置成该渲染纹理,这样一来该摄像机的渲染结果就会实时更新到渲染纹理中,而不会显示在屏幕上。使用这种方法,我们可以选择渲染纹理的分辨率、滤波模式等纹理属性。另一种方式是在屏幕后处理时使用GrabPass命令或OnRenderImage函数来获取当前屏幕图像,Unity会把这个屏幕图像放到一张和屏幕分辨率等同的纹理中。
1.镜子效果
Shader "Own/Chapter10-Mirror" { Properties { _MainTex ("Main Tex", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" "Queue" = "Geometry"} Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag sampler2D _MainTex; struct a2v{ float4 vertex : POSITION; float3 texcoord : TEXCOORD0; }; struct v2f{ float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; v2f vert(a2v v){ v2f o; o.pos = mul(UNITY_MATRIX_MVP,v.vertex); o.uv = v.texcoord; //由于镜子里显示的图像都是左右相反的,故翻转x分量 o.uv.x = 1 - o.uv.x; return o; } fixed4 frag(v2f i):SV_Target{ return tex2D(_MainTex,i.uv); } ENDCG } } FallBack Off }
其中Texture需要拖拽到该摄像机的Target Texture下。
2.玻璃效果
Shader "Own/Chapter10-GlassRefraction" { Properties { //该玻璃的材质,默认白色纹理 _MainTex("Main Tex",2D) = "white"{} //该玻璃的法线纹理 _BumpMap("Normal Map",2D) = "bump"{} //用于模拟反射的环境纹理 _Cubemap("Environment Cubemap",Cube) = "_Skybox"{} //用于控制模拟折射时图像的扭曲程度 _Distortion("Distortion",Range(0,100)) = 10 //用于控制折射程度,当值为0时,该玻璃只包含反射效果,当值为1时,该玻璃只包含折射效果。 _RefractAmount("Refract Amount",Range(0.0,1.0)) = 1.0 } SubShader { //Transparent:确保该物体渲染时,其他所有不透明物体都已经渲染到屏幕上了,否则就可能无法正确得到"透过玻璃看到的图像" //Opaque:为了在使用着色器替换(Shader Replacement)时,该物体可以在需要时被正确渲染。这通常发生在我们需要得到摄像机的 //的深度和法线纹理时。 Tags { "RenderType"="Opaque" "Queue" = "Transparent"} //定义一个抓取屏幕图像的Pass,其中_RefractionTex表示抓取得到的屏幕图像将会被存入哪个纹理中。 GrabPass{"_RefractionTex"} Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; float4 _MainTex_ST; sampler2D _BumpMap; float4 _BumpMap_ST; samplerCUBE _Cubemap; float _Distortion; fixed _RefractAmount; //抓取的屏幕图像 sampler2D _RefractionTex; //该屏幕图像的纹素大小 float4 _RefractionTex_TexelSize; struct a2v{ float4 vertex : POSITION; float3 normal : NORMAL; float4 tangent : TANGENT; float2 texcoord : TEXCOORD0; }; struct v2f{ float4 pos : SV_POSITION; float4 scrPos : TEXCOORD0; float4 uv : TEXCOORD1; float4 TtoW0 : TEXCOORD2; float4 TtoW1 : TEXCOORD3; float4 TtoW2 : TEXCOORD4; }; v2f vert(a2v v){ v2f o; o.pos = mul(UNITY_MATRIX_MVP,v.vertex); //通过调用内置的ComputeGrabScreenPos函数来得到对应被抓取的屏幕图像的采样坐标。 o.scrPos = ComputeGrabScreenPos(o.pos); o.uv.xy = TRANSFORM_TEX(v.texcoord,_MainTex); o.uv.zw = TRANSFORM_TEX(v.texcoord,_BumpMap); float3 worldPos = mul(unity_ObjectToWorld,v.vertex).xyz; fixed3 worldNormal = UnityObjectToWorldNormal(v.normal); fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz); fixed3 worldBinormal = cross(worldNormal,worldTangent) * v.tangent.w; o.TtoW0 = float4(worldTangent.x,worldBinormal.x,worldNormal.x,worldPos.x); o.TtoW1 = float4(worldTangent.y,worldBinormal.y,worldNormal.y,worldPos.y); o.TtoW2 = float4(worldTangent.z,worldBinormal.z,worldNormal.z,worldPos.z); return o; } fixed4 frag(v2f i):SV_Target{ float3 worldPos = float3(i.TtoW0.w,i.TtoW1.w,i.TtoW2.w); fixed3 worldViewDir = normalize(UnityWorldSpaceViewDir(worldPos)); fixed3 bump = UnpackNormal(tex2D(_BumpMap,i.uv.zw)); float2 offset = bump.xy * _Distortion * _RefractionTex_TexelSize.xy; i.scrPos.xy = offset * i.scrPos.z + i.scrPos.xy; fixed3 refrCol = tex2D(_RefractionTex,i.scrPos.xy/i.scrPos.w).rgb; bump = normalize(half3(dot(i.TtoW0.xyz,bump),dot(i.TtoW1.xyz,bump),dot(i.TtoW2.xyz,bump))); fixed3 reflDir = reflect(-worldViewDir,bump); fixed4 texColor = tex2D(_MainTex,i.uv.xy); fixed3 reflCol = texCUBE(_Cubemap,reflDir).rgb * texColor.rgb; fixed3 finalColor = reflCol * (1 - _RefractAmount) + refrCol * _RefractAmount; return fixed4(finalColor,1); } ENDCG } } }
相关文章推荐
- unityshader学习笔记之纹理渲染
- 【 4000 UnityShader】学习笔记 可编程渲染管线结构及语义
- Unity Shader 学习笔记(26) 边缘检测(深度和法线纹理)
- Unity Shader 学习笔记(8) 纹理映射、凹凸映射
- Unity Shader 学习笔记(27)渲染轮廓线(描边)方法、卡通风格渲染、素描风格渲染
- Unity Shader 学习笔记(10) 纹理(Texture)的属性
- 学习UnityShader入门精要笔记1——渲染流程概述
- Unity Shader 学习笔记(9) 渐变纹理、遮罩纹理
- Unity Shader 学习笔记(12) 渲染路径(Rendering Path)
- Unity Shader 学习笔记(十一) 混合纹理Shader实例
- Unity Shader学习笔记:遮罩纹理
- Unity Shader 学习笔记(28) 噪声纹理、消融效果、水波效果、噪声雾效
- UnityShader入门精要学习笔记(二十一):深度和法线纹理
- Unity Shader入门精要学习笔记 - 第13章 使用深度和法线纹理
- 【UnityShader】学习笔记 纹理寻址
- UnityShader入门精要学习笔记(十二):渲染路径与光源类型
- Unity Shader 学习笔记(24) 深度纹理、法线纹理
- Unity Shader 学习笔记(15) 立方体纹理、反射、折射、菲涅尔反射
- Unity Shader入门精要学习笔记 - 第2章 渲染流水线
- Unity Shader入门精要学习笔记 - 第16章 Unity中的渲染优化技术