今天做了一个天空盒的shader:
首先,我需要可调整的参数有:一张HDR Cubemap的贴图(绑定天空盒的 Cubemap),一个可调节的颜色(整体颜色调节(像给天空加一层颜色滤镜)),能够控制曝光(控制渲染出来的亮度。),开始的角度(基础旋转角度(手动设置的静态旋转)。),运根据时间自动旋转(天空盒每秒旋转多少度。负数代表逆时针。)Subshader标签Tag(说明是最底层的渲染背景)。关闭深度和不剔除任何面(Zwrite off。Cull Off)。。顶点着色器的输入(只需要顶点的位置)输出(屏幕坐标和传给Cubmap的方向)片元着色器的输入输出。这里对应的曝光度和HDR天空盒的解码,以及颜色曝光等的算法逻辑都需要写进去。一个简单的天空球可以跟随时间转动的
shader就可以了。这个是根据unity自带的天空球基础上添加了旋转。在片元着色器中有计算的逻辑。
具体脚本如下:
csharp
Shader "Skybox/Cubemap Rotating" {
Properties {
_Tint ("Tint Color", Color) = (0.500000,0.500000,0.500000,0.500000)
[Gamma] _Exposure ("Exposure", Range(0.000000,8.000000)) = 1.000000
_Rotation ("Rotation", Range(0.000000,360.000000)) = 0.000000
_SpeedRotation ("Speed Rotation", Range(-10.000000,10.000000)) = 0.000000
[NoScaleOffset] _Tex ("Cubemap (HDR)", CUBE) = "grey" { }
}
SubShader {
Tags { "QUEUE"="Background" "RenderType"="Background" "PreviewType"="Skybox" }
Pass {
Tags { "QUEUE"="Background" "RenderType"="Background" "PreviewType"="Skybox" }
ZWrite Off
Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
samplerCUBE _Tex;
half4 _Tex_HDR;
half4 _Tint;
half _Exposure;
float _Rotation;
float _SpeedRotation;
struct appdata {
float4 vertex : POSITION;
};
struct v2f {
float4 pos : SV_POSITION;
float3 texcoord : TEXCOORD0;
};
v2f vert (appdata v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
// 计算总旋转角度:基础旋转 + 随时间变化的旋转
float totalRotation = _Rotation + _SpeedRotation * _Time.y;
totalRotation = radians(totalRotation); // 转换为弧度
// 创建旋转矩阵(绕Y轴旋转)
float sinRot, cosRot;
sincos(totalRotation, sinRot, cosRot);
// 应用旋转到纹理坐标
float3 rotatedCoord;
rotatedCoord.x = v.vertex.x * cosRot - v.vertex.z * sinRot;
rotatedCoord.z = v.vertex.x * sinRot + v.vertex.z * cosRot;
rotatedCoord.y = v.vertex.y;
o.texcoord = rotatedCoord;
return o;
}
half4 frag (v2f i) : SV_Target {
half4 tex = texCUBE(_Tex, i.texcoord);
half3 c = DecodeHDR(tex, _Tex_HDR);
c = c * _Tint.rgb * unity_ColorSpaceDouble.rgb;
c *= _Exposure;
return half4(c, 1);
}
ENDCG
}
}
Fallback Off
}