Unity 贴图叠加,添加水印
原创内容,转载请标明出处
Shader "Custom/AddWatermarkShader" { Properties { _MainTex("Main Texture", 2D) = "white" {} _WatermarkTex("Watermark Texture", 2D) = "white" {} _WatermarkPosition("Watermark Position", Vector) = (0, 0, 122, 34) } SubShader { Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_TexelSize; sampler2D _WatermarkTex; float4 _WatermarkTex_TexelSize; float4 _WatermarkPosition; v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } fixed4 frag(v2f i) : SV_Target { //计算水印贴图相对于底图的尺寸 float2 ratio = float2(_WatermarkTex_TexelSize.z / _MainTex_TexelSize.z, _WatermarkTex_TexelSize.w / _MainTex_TexelSize.w); if (i.uv.x >= _WatermarkPosition.x && i.uv.x <= _WatermarkPosition.x + ratio.x && i.uv.y >= _WatermarkPosition.y && i.uv.y <= _WatermarkPosition.y + ratio.y) { float2 watermarkUV = (i.uv - _WatermarkPosition.xy) / float2(ratio.x, ratio.y); fixed4 watermarkColor = tex2D(_WatermarkTex, watermarkUV); return watermarkColor; } else { fixed4 mainColor = tex2D(_MainTex, i.uv); return mainColor; } } ENDCG } } }
进阶:全景图上添加水印
Shader "Custom/MosaicSaveSample" { Properties { _MainTex("Main Texture", 2D) = "white" {} _SecondTex("Second Texture", 2D) = "white" {} _LeftBottom("LeftBottom(原点)",vector) = (0,0,0) _RightBottom("RightBottom(u方向)",vector) = (0,0,0) _LeftTop("LeftTop(v方向)",vector) = (0,0,0) } SubShader { Tags { "RenderType" = "Opaque" } //翻转曲面 //Cull front LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_TexelSize; sampler2D _SecondTex; float4 _SecondTex_TexelSize; float3 _LeftTop; float3 _LeftBottom; float3 _RightBottom; //uv对应的世界坐标 float3 FromUVCoords(float2 uv) { float3 dir_u = (_RightBottom - _LeftBottom) * uv.x; float3 dir_v = (_LeftTop - _LeftBottom) * uv.y; return _LeftBottom + (dir_u + dir_v); } //世界坐标对应的uv坐标 inline float2 ToUVCoords(float3 position) { float3 dir = position - _LeftBottom; float u = dot(dir, normalize(_RightBottom - _LeftBottom) / length(_RightBottom - _LeftBottom)); float v = dot(dir, normalize(_LeftTop - _LeftBottom) / length(_LeftTop - _LeftBottom)); return float2(u, v); } //世界坐标映射到全景图上的UV坐标 inline float2 ToRadialCoords(float3 coords) { float3 normalizedCoords = normalize(coords); float latitude = acos(normalizedCoords.y); float longitude = atan2(normalizedCoords.z, normalizedCoords.x); float2 sphereCoords = float2(longitude, latitude) * float2(0.5 / UNITY_PI, 1.0 / UNITY_PI); return float2(0.5,1.0) - sphereCoords; } //全景图上的UV坐标映射到三维坐标 inline float3 FromRadialCoords(float2 uv) { float2 sphereCoords = float2(0.5, 1.0) - uv; float longitude = sphereCoords.x / (0.5 / UNITY_PI); float latitude = sphereCoords.y / (1.0 / UNITY_PI); float sinLatitude = sin(latitude); float3 coords; coords.x = sinLatitude * cos(longitude); coords.y = cos(latitude); coords.z = sinLatitude * sin(longitude); return coords; } //射线是否和AABB包围盒相交,可以求交点 float3 RayIntersectAABB(float3 rayOrigin, float3 rayDirection, float3 boxMin, float3 boxMax) { float3 center = (boxMin + boxMax) * 0.5; float3 centerDir = normalize(center - rayOrigin); if (dot(rayDirection, centerDir) < 0) { return float3(0, 0, 0);//方向不同说明在背面 } float3 tMin = (boxMin - rayOrigin) / rayDirection; float3 tMax = (boxMax - rayOrigin) / rayDirection; float3 realMin = min(tMin, tMax); float3 realMax = max(tMin, tMax); float tNear = max(max(realMin.x, realMin.y), realMin.z); float tFar = min(min(realMax.x, realMax.y), realMax.z); if (tNear <= tFar) { return rayOrigin + rayDirection * tNear;//交点 } else { return float3(0, 0, 0); } } v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } fixed4 frag(v2f i) : SV_Target { float3 worldPos = FromRadialCoords(i.uv.xy); float3 rayOrigin = float3(0,0,0); float3 rayDirection = normalize(worldPos - rayOrigin); float3 boxMin = min(_LeftTop, min(_LeftBottom, _RightBottom)); float3 boxMax = max(_LeftTop, max(_LeftBottom, _RightBottom)); float3 intersectPoint = RayIntersectAABB(rayOrigin, rayDirection, boxMin, boxMax); if (intersectPoint.x==0&& intersectPoint.y == 0&& intersectPoint.z == 0) { return tex2D(_MainTex, i.uv); } else { float2 uv = ToUVCoords(intersectPoint); return tex2D(_SecondTex, uv); } } ENDCG } } }
博客园Jason_c微信打赏码
如果本篇文档对你有帮助,打赏Jason_c根华子吧,他的私房钱被老婆没收了,呜呜!