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根华子吧,他的私房钱被老婆没收了,呜呜!
浙公网安备 33010602011771号