Search Unity

Rotate Textures In Fragment Shader And Blending

Discussion in 'Shaders' started by mike158, Apr 11, 2019.

  1. mike158

    mike158

    Joined:
    Oct 6, 2018
    Posts:
    11
    Hello, I need to create a shader that receives two equirectangular textures, rotation around each axis for both textures (6 in total) and parameter in range <0,1> to lerp these two images in fragment shader. I've found shaders for equirectangular textures and another one for blending cubemaps. I just need to mix them together. Unfortunately I'm not good at writing shaders. This is the equirectangular shader:

    Code (CSharp):
    1. Shader "Skybox/Equirectangular" {
    2.     Properties{
    3.         _Tint("Tint Color", Color) = (.5, .5, .5, .5)
    4.         [Gamma] _Exposure("Exposure", Range(0, 8)) = 1.0
    5.         _Rotation("Rotation", Range(0, 360)) = 0
    6.         [NoScaleOffset] _Tex("Panorama (HDR)", 2D) = "grey" {}
    7.     }
    8.  
    9.         SubShader{
    10.             Tags { "Queue" = "Background" "RenderType" = "Background" "PreviewType" = "Skybox" }
    11.             Cull front
    12.  
    13.             Pass {
    14.  
    15.                 CGPROGRAM
    16.                 #pragma vertex vert
    17.                 #pragma fragment frag
    18.  
    19.                 #include "UnityCG.cginc"
    20.  
    21.                 sampler2D _Tex;
    22.                 half4 _Tex_HDR;
    23.                 half4 _Tint;
    24.                 half _Exposure;
    25.                 float _Rotation;
    26.  
    27.                 float4 RotateAroundYInDegrees(float4 vertex, float degrees)
    28.                 {
    29.                     float alpha = degrees * UNITY_PI / 180.0;
    30.                     float sina, cosa;
    31.                     sincos(alpha, sina, cosa);
    32.                     float2x2 m = float2x2(cosa, -sina, sina, cosa);
    33.                     return float4(mul(m, vertex.xz), vertex.yw).xzyw;
    34.                 }
    35.  
    36.                 struct appdata_t {
    37.                     float4 vertex : POSITION;
    38.                 };
    39.  
    40.                 struct v2f {
    41.                     float4 vertex : SV_POSITION;
    42.                     float3 texcoord : TEXCOORD0;
    43.                 };
    44.  
    45.                 v2f vert(appdata_t v)
    46.                 {
    47.                     v2f o;
    48.                     o.vertex = UnityObjectToClipPos(RotateAroundYInDegrees(v.vertex, _Rotation));
    49.                     o.texcoord = v.vertex.xyz;
    50.                     return o;
    51.                 }
    52.  
    53.                 fixed4 frag(v2f i) : SV_Target
    54.                 {
    55.                     float3 dir = normalize(i.texcoord);
    56.                     float2 longlat = float2(atan2(dir.x, dir.z) + UNITY_PI, acos(-dir.y));
    57.                     float2 uv = longlat / float2(2.0 * UNITY_PI, UNITY_PI);
    58.                     half4 tex = tex2D(_Tex, uv);
    59.                     half3 c = DecodeHDR(tex, _Tex_HDR);
    60.                     c = c * _Tint.rgb * unity_ColorSpaceDouble.rgb;
    61.                     c *= _Exposure;
    62.  
    63.                     return half4(c, 1);
    64.                 }
    65.                 ENDCG
    66.             }
    67.     }
    68.  
    69.         Fallback Off
    70. }
    And this is the blending shader:
    Code (CSharp):
    1. Shader "Custom/SkyboxShader" {
    2.     Properties{
    3.          _Tint("Tint Color", Color) = (.5, .5, .5, 1)
    4.          _Tint2("Tint Color 2", Color) = (.5, .5, .5, 1)
    5.          [Gamma] _Exposure("Exposure", Range(0, 8)) = 1.0
    6.          _Rotation("Rotation", Range(0, 360)) = 0
    7.          _BlendCubemaps("Blend Cubemaps", Range(0, 1)) = 0.5
    8.          [NoScaleOffset] _Tex("Cubemap (HDR)", Cube) = "grey" {}
    9.          [NoScaleOffset] _Tex2("Cubemap (HDR) 2", Cube) = "grey" {}
    10.     }
    11.         SubShader{
    12.             Tags { "Queue" = "Background" "RenderType" = "Background" "PreviewType" = "Skybox" }
    13.             Cull Off ZWrite Off
    14.             Blend SrcAlpha OneMinusSrcAlpha
    15.  
    16.             Pass {
    17.  
    18.                 CGPROGRAM
    19.                 #pragma vertex vert
    20.                 #pragma fragment frag
    21.  
    22.                 #include "UnityCG.cginc"
    23.  
    24.                 samplerCUBE _Tex;
    25.                 samplerCUBE _Tex2;
    26.                 float _BlendCubemaps;
    27.                 half4 _Tex_HDR;
    28.                 half4 _Tint;
    29.                 half4 _Tint2;
    30.                 half _Exposure;
    31.                 float _Rotation;
    32.  
    33.                 float4 RotateAroundYInDegrees(float4 vertex, float degrees)
    34.                 {
    35.                     float alpha = degrees * UNITY_PI / 180.0;
    36.                     float sina, cosa;
    37.                     sincos(alpha, sina, cosa);
    38.                     float2x2 m = float2x2(cosa, -sina, sina, cosa);
    39.                     return float4(mul(m, vertex.xz), vertex.yw).xzyw;
    40.                 }
    41.  
    42.                 struct appdata_t {
    43.                     float4 vertex : POSITION;
    44.                     float3 normal : NORMAL;
    45.                 };
    46.  
    47.                 struct v2f {
    48.                     float4 vertex : SV_POSITION;
    49.                     float3 texcoord : TEXCOORD0;
    50.                 };
    51.  
    52.                 v2f vert(appdata_t v)
    53.                 {
    54.                     v2f o;
    55.                     o.vertex = UnityObjectToClipPos(RotateAroundYInDegrees(v.vertex, _Rotation));
    56.                     o.texcoord = v.vertex;
    57.                     return o;
    58.                 }
    59.  
    60.                 fixed4 frag(v2f i) : SV_Target
    61.                 {
    62.                     float4 env1 = texCUBE(_Tex, i.texcoord);
    63.                     float4 env2 = texCUBE(_Tex2, i.texcoord);
    64.                     float4 env = lerp(env2, env1, _BlendCubemaps);
    65.                     float4 tint = lerp(_Tint, _Tint2, _BlendCubemaps);
    66.                     half3 c = DecodeHDR(env, _Tex_HDR);
    67.                     c = c * tint.rgb * unity_ColorSpaceDouble;
    68.                     c *= _Exposure;
    69.                     return half4(c, tint.a);
    70.                 }
    71.                 ENDCG
    72.             }
    73.     }
    74.         Fallback Off
    75. }
    I need to move rotation from vertex shader into fragment shader, add rotation for axis X and axis Z (same for second texture). I would really appreciate if anybode could help me out. Thanks in advance.
     
  2. mike158

    mike158

    Joined:
    Oct 6, 2018
    Posts:
    11
    After whole night I figured out myself. I didn't have to move rotation into fragment shader. I had to create rotation functions (like the one for Y axis I already had) for each axis, then into v2f struct add another texcoord, in vertex shader calculate rotations for both texcoords separately with rotation functions and the fragment shader was just combining both shaders together with using calculated texcoords from vertex shader.
     
    bgolus and sylon like this.