Search Unity

Lock a skybox position during teleport?

Discussion in 'General Graphics' started by Zebbi, May 12, 2020.

  1. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    Is it possible to lock the position of a skybox during a teleport to an identical environment so it's impossible to tell the player has been teleported? Currently I have two sections of the scene that match perfectly and when the player teleports, no matter which facing angle or direction, when they arrive, it's indistinguishable, besides the skybox. That changes unless the destination facing orientation is exactly the same, which it won't be. Is there a way of offsetting the skybox, or locking it in place so that it doesn't rotate when the player does?
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    It’s not possible to “lock the position”, but you can certainly change the rotation of the skybox when you teleport the player. Most skybox shaders have a rotation property you can set.
     
  3. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    Thanks, I'm using this shader for a simple quad sky which doesn't seem to have an override :/
    Code (CSharp):
    1.  Shader "FX/DoomSky"
    2. {
    3.      Properties
    4.      {
    5.          _MainTex ("Texture", 2D) = "white" {}
    6.          _StretchDown ("Stretch", Range(0, 0.5)) = 0
    7.      }
    8.      SubShader
    9.      {
    10.          Tags { "RenderType"="Opaque" }
    11.          Cull off ZWrite On ZTest Lequal
    12.          LOD 100
    13.          Pass
    14.          {
    15.              CGPROGRAM
    16.              #pragma vertex vert
    17.              #pragma fragment frag
    18.            
    19.              #include "UnityCG.cginc"
    20.              struct appdata
    21.              {
    22.                  float4 vertex : POSITION;
    23.              };
    24.              struct v2f
    25.              {
    26.                  float3 worldView : TEXCOORD1;
    27.                  float4 vertex : SV_POSITION;
    28.              };
    29.              v2f vert (appdata v)
    30.              {
    31.                  v2f o;
    32.                  o.vertex = UnityObjectToClipPos(v.vertex);
    33.                  o.worldView = -WorldSpaceViewDir (v.vertex);
    34.                  return o;
    35.              }
    36.              sampler2D _MainTex;
    37.              float _StretchDown;
    38.            
    39.              fixed4 frag (v2f i) : SV_Target
    40.              {
    41.                  float3 dir = normalize(i.worldView);
    42.                  float2 uv = float2(0.5+atan2(dir.z, dir.x)/(2*UNITY_PI), _StretchDown+dir.y*(1-_StretchDown));
    43.                  uv.x*=3;
    44.                  fixed4 col = tex2D(_MainTex, uv);
    45.                  return col;
    46.              }
    47.              ENDCG
    48.          }
    49.      }
    50. }
    I'm teleporting the player when they hit a collider by setting the player's transform:
    Code (CSharp):
    1. obj.transform.position = portalB.transform.TransformPoint(portalA.transform.InverseTransformPoint(obj.transform.position));
    And the player's rotation:
    Code (CSharp):
    1. obj.transform.rotation = portalB.transform.rotation * Quaternion.Inverse(portalA.transform.rotation) * obj.transform.rotation;
    The position is irrelevant for the skybox, but could the rotation value be somehow applied to this skybox shader (with a multiplier of some amount, I assume) to counter the repositioning? This way, no matter which orientation the collider are and the player is rotated, the skybox would look the same after the teleportation?
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
  5. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    Does this allow for this flat, retro looking mapping?

    That's the reason I used this shader, to give a Doom 1993 style skyboard that just uses a single image that doesn't warp other than the camera's natural FOV. I'm also not quite sure if I can take the rotation quat and use it to rotate a skybox shader, but using the Y axis might be a good start.
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    It should, just in your case you only need to worry about rotating the worldView, not the mesh.
     
  7. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    For some reason, skybox-panoramic is a lot bigger than the quad shader:


    The quad shader I'm using appears properly on screen:


    I tried playing with the settings, but it's still surprisingly large, is this because of the PPU size?
     
  8. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    The panoramic skybox is assume a equirectangular image that's a full sphere. The one you posted above appears to be setup to allow for sky textures that can be scaled so they're not a full sphere, and your example looks like it might be only a top hemisphere with it wrapping at the horizon.

    The original Doom used a texture that was mapped from the middle of the screen to the top of the screen and didn't have to worry about you looking up or down. ;) Later hacks & doom engine games that added looking up and down just stretched the texture to be shown as tall as the highest "up" was allowed. Also they didn't actually allow you to look up since it wasn't a real 3D engine, it was just skewing the camera projection up and down, so it a little different.

    You'd need to modify the panoramic skybox shader to let you scale the texture UVs, or double the height of your textures and fill the bottom half in with black or a copy of the texture if you want to mimic what the original shader you had did.
     
  9. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    Yeah, this shader does work best with y-shearing, but this looks elegant enough even with true look up/down:


    The panoramic shader not only isn't tiled, but it's also cubic:


    Is there a way of either adding rotation to the DoomSky shader, or making the panoramic one act more like the DoomSky shader? I'm not quite sure where to start :D
     
  10. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    You're using the wrong settings for your material. The shader has two "Mapping" options, and that's using the "6 frames layout" which seems to be for cubemap texture based layouts ... in which case I'm not sure why you wouldn't use an actual cubemap but whatever. You want the "Latitude Longitude Layout".

    Yes. Look at the
    _Rotation
    property from that shader and the
    RotateAroundYInDegrees
    function. Those are the only things you need. Then...
     
    Zebbi likes this.
  11. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    Thanks, okay so now it's spherical:


    It just needs tiling. Now, originally this was posted as part of the DoomSky shader:
    So could a similar technique be used for the panoramic shader? This way it could be on parity with the DoomSky shader, and all I'd need to do is somehow offset the rotation. (PS: I am pre-beginner with shaders, I barely ever get anything working properly without explicit instruction :D )
     
  12. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    So, can this:
    Code (CSharp):
    1. uv.x *= 4;
    be added to the Panoramic shader to get the same effect as DoomSky, or will it always be a little more spherical than DoomSky? I'm not quite sure if I can just add it in the same sort of place I did in DoomSky or not.
     
  13. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    @bgolus would adding tiling to the spherical panorama shader work the same as the DoomSky shader, or would it still be a little more spherical? (I want it to be as flat as possible, besides camera distortion) If so, how could I go about adding tiling?
     
  14. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    I would copy the one function and add the two lines of code needed to make the DoomSky rotate rather than modify the panorama shader.
     
    Zebbi likes this.
  15. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    Sounds good! But I still don't reeeeally know where to start:
    Code (CSharp):
    1.  Shader "FX/DoomSky"
    2. {
    3.      Properties
    4.      {
    5.          _MainTex ("Texture", 2D) = "white" {}
    6.          _StretchDown ("Stretch", Range(0, 0.5)) = 0
    7.      }
    8.      SubShader
    9.      {
    10.          Tags { "RenderType"="Opaque" }
    11.          Cull off ZWrite On ZTest Lequal
    12.          LOD 100
    13.          Pass
    14.          {
    15.              CGPROGRAM
    16.              #pragma vertex vert
    17.              #pragma fragment frag
    18.            
    19.              #include "UnityCG.cginc"
    20.              struct appdata
    21.              {
    22.                  float4 vertex : POSITION;
    23.              };
    24.              struct v2f
    25.              {
    26.                  float3 worldView : TEXCOORD1;
    27.                  float4 vertex : SV_POSITION;
    28.              };
    29.              v2f vert (appdata v)
    30.              {
    31.                  v2f o;
    32.                  o.vertex = UnityObjectToClipPos(v.vertex);
    33.                  o.worldView = -WorldSpaceViewDir (v.vertex);
    34.                  return o;
    35.              }
    36.              sampler2D _MainTex;
    37.              float _StretchDown;
    38.            
    39.              fixed4 frag (v2f i) : SV_Target
    40.              {
    41.                  float3 dir = normalize(i.worldView);
    42.                  float2 uv = float2(0.5+atan2(dir.z, dir.x)/(2*UNITY_PI), _StretchDown+dir.y*(1-_StretchDown));
    43.                  uv.x*=3;
    44.                  fixed4 col = tex2D(_MainTex, uv);
    45.                  return col;
    46.              }
    47.              ENDCG
    48.          }
    49.      }
    50. }
    (I used uv.x*=3; as it looked more appropriate)
    Also, I get this, but it still works, is this okay?
     

    Attached Files:

  16. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    Also need to confirm the 'Shader of this material does not support skybox rendering' error isn't a big issue? I'm not even sure why it's saying that when it clearly works as a skybox.
     
  17. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    I'm not sure what it's checking to see if a shader is a "skybox" shader or not. Might be as simple as your shader isn't set to the background queue or skybox preview. Really most of those warnings are there to make sure people are dragging a Standard shader material onto the skybox slot. If it works, it's probably fine.
     
  18. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    Erm, I'm trying something here, but I'm not doing a great job:
    Code (CSharp):
    1.  Shader "FX/DoomSkyRotate"
    2. {
    3.      Properties
    4.      {
    5.          _MainTex ("Texture", 2D) = "white" {}
    6.          _StretchDown ("Stretch", Range(0, 0.5)) = 0
    7.          _Rotation ("Rotation", Range(0, 360)) = 0
    8.      }
    9.      SubShader
    10.      {
    11.          Tags { "RenderType"="Opaque" }
    12.          Cull off ZWrite On ZTest Lequal
    13.          LOD 100
    14.          Pass
    15.          {
    16.              CGPROGRAM
    17.              #pragma vertex vert
    18.              #pragma fragment frag
    19.            
    20.              #include "UnityCG.cginc"
    21.              struct appdata
    22.              {
    23.                  float4 vertex : POSITION;
    24.              };
    25.              struct v2f
    26.              {
    27.                  float3 worldView : TEXCOORD1;
    28.                  float4 vertex : SV_POSITION;
    29.              };
    30.              v2f vert (appdata v)
    31.              {
    32.                  v2f o;
    33.                  o.vertex = UnityObjectToClipPos(v.vertex);
    34.                  o.worldView = -WorldSpaceViewDir (v.vertex);
    35.                  float3 rotated = RotateAroundYInDegrees(v.vertex, _Rotation);
    36.                  return o;
    37.              }
    38.              sampler2D _MainTex;
    39.              float _StretchDown;
    40.              float _Rotation;
    41.            
    42.              fixed4 frag (v2f i) : SV_Target
    43.              {
    44.                  float3 dir = normalize(i.worldView);
    45.                  float2 uv = float2(0.5+atan2(dir.z, dir.x)/(2*UNITY_PI), _StretchDown+dir.y*(1-_StretchDown));
    46.                  uv.x*=3;
    47.                  fixed4 col = tex2D(_MainTex, uv);
    48.                  return col;
    49.              }
    50.  
    51.              float3 RotateAroundYInDegrees (float3 vertex, float degrees)
    52.         {
    53.             float alpha = degrees * UNITY_PI / 180.0;
    54.             float sina, cosa;
    55.             sincos(alpha, sina, cosa);
    56.             float2x2 m = float2x2(cosa, -sina, sina, cosa);
    57.             return float3(mul(m, vertex.xz), vertex.y).xzy;
    58.         }
    59.              ENDCG
    60.          }
    61.      }
    62. }
     
    Last edited: May 20, 2020
  19. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    The
    float _Rotation;
    uniform (a shader value defined outside of a function) needs to be defined before the first time it's used in the shader file, so you need to move that above the
    vert
    function.

    Then I'll quote myself again.
    Look at the code you have. What are you applying the
    RotateAroundYInDegress
    function to, and what are you doing with the output value?
     
  20. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    I'm sorry, I'm not sure which vert function? I'm really terrible with shader language, do you mean
    Code (CSharp):
    1. v2f vert (appdata v)
    ? Whereabouts above it, I tried putting it directly above and it I got:
    Code (CSharp):
    1. Shader error in 'FX/DoomSkyRotate': undeclared identifier 'RotateAroundYInDegrees' at line 40 (on d3d11)
    2.  
    3. Compiling Vertex program
    4. Platform defines: UNITY_ENABLE_REFLECTION_BUFFERS UNITY_USE_DITHER_MASK_FOR_ALPHABLENDED_SHADOWS UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BOX_PROJECTION UNITY_SPECCUBE_BLENDING UNITY_ENABLE_DETAIL_NORMALMAP SHADER_API_DESKTOP UNITY_COLORSPACE_GAMMA UNITY_LIGHT_PROBE_PROXY_VOLUME UNITY_LIGHTMAP_FULL_HDR
    5.  
    I'm not sure how to apply that to this, I can barely understand what that parts actually doing, does
    Code (CSharp):
    1. float3 rotated = RotateAroundYInDegrees(v.vertex, _Rotation);
    need changing?
     
  21. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
  22. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Yes, but I'm leaving it to you to figure it out.

    The
    RotateAroundYInDegrees
    function isn't something that comes with Unity's cginc files, it's included with each skybox shader. If you haven't included the function in the shader, then trying to call it in code won't do anything.

    And then I'll again quote myself.
    Maybe also look at the original Doom shader to see what values from the vert function are getting used in the frag function.
     
  23. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    Mean! :p

    The thing is, I have practically zero understanding of shaders, so a lot of this means nothing to me, unfortunately.

    I'm really not sure, the panoramic shader is thusly:
    Code (CSharp):
    1. float3 RotateAroundYInDegrees (float3 vertex, float degrees)
    2.         {
    3.             float alpha = degrees * UNITY_PI / 180.0;
    4.             float sina, cosa;
    5.             sincos(alpha, sina, cosa);
    6.             float2x2 m = float2x2(cosa, -sina, sina, cosa);
    7.             return float3(mul(m, vertex.xz), vertex.y).xzy;
    8.         }
    A bunch of cosine?

    Code (CSharp):
    1. float3 rotated = RotateAroundYInDegrees(v.vertex, _Rotation);
    I guess v.vertex and whatever _Rotation is?

    Doomshader's frag function is:
    Code (CSharp):
    1. fixed4 frag (v2f i) : SV_Target
    2.              {
    3.                  float3 dir = normalize(i.worldView);
    4.                  float2 uv = float2(0.5+atan2(dir.z, dir.x)/(2*UNITY_PI), _StretchDown+dir.y*(1-_StretchDown));
    5.                  uv.x*=3;
    6.                  fixed4 col = tex2D(_MainTex, uv);
    7.                  return col;
    8.              }
    Doomshader's vert is (I think):
    Code (CSharp):
    1. v2f vert (appdata v)
    2.              {
    3.                  v2f o;
    4.                  o.vertex = UnityObjectToClipPos(v.vertex);
    5.                  o.worldView = -WorldSpaceViewDir (v.vertex);
    6.                  float3 rotated = RotateAroundYInDegrees(v.vertex, _Rotation);
    7.                  return o;
    8.              }
    So, that would be... none of it? Or maybe worldView?
     
  24. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    https://en.wikipedia.org/wiki/Rotation_matrix

    The first parameter is the input position you want to have rotated, and
    _Rotation
    is the rotation in degrees that the function will rotate the input position around the y axis, hence why the function is named
    RotateAroundYInDegrees
    .

    Yes.

    Code (csharp):
    1. ────────▄▀▀▄─────────────
    2. ────────█──█─────────────
    3. ────────█──█▄▄───────────
    4. ────────█──█──█▀▀▄▄──────
    5. ────▄▄▄─█──█──█──█─▀▄────
    6. ────█──▀█────────▀──█────
    7. ─────▀▄─█───────────█────
    8. ──────▀▄────────────█────
    9. ───────▀▄──────────█─────
    10. ─────────█▄▄▄▄▄▄▄▄█──────  
     
  25. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    Okay, firstly, I'm not sure why I'm getting this issue with RotateAroundYInDegrees:

    I moved the function before using it in vert, but it's seems to give the same error. If I should be using worldview, would that go in replacement of v.vertex? Here's the modded shader so far:

    Code (CSharp):
    1.  Shader "FX/DoomSkyRotate"
    2. {
    3.      Properties
    4.      {
    5.          _MainTex ("Texture", 2D) = "white" {}
    6.          _StretchDown ("Stretch", Range(0, 0.5)) = 0
    7.          _Rotation ("Rotation", Range(0, 360)) = 0
    8.      }
    9.      SubShader
    10.      {
    11.          Tags { "RenderType"="Opaque" }
    12.          Cull off ZWrite On ZTest Lequal
    13.          LOD 100
    14.          Pass
    15.          {
    16.              CGPROGRAM
    17.              #pragma vertex vert
    18.              #pragma fragment frag
    19.            
    20.              #include "UnityCG.cginc"
    21.              struct appdata
    22.              {
    23.                  float4 vertex : POSITION;
    24.              };
    25.              struct v2f
    26.              {
    27.                  float3 worldView : TEXCOORD1;
    28.                  float4 vertex : SV_POSITION;
    29.              };
    30.            
    31.              float3 RotateAroundYInDegrees (float3 vertex, float degrees)
    32.         {
    33.             float alpha = degrees * UNITY_PI / 180.0;
    34.             float sina, cosa;
    35.             sincos(alpha, sina, cosa);
    36.             float2x2 m = float2x2(cosa, -sina, sina, cosa);
    37.             return float3(mul(m, vertex.xz), vertex.y).xzy;
    38.         }
    39.  
    40.              v2f vert (appdata v)
    41.              {
    42.                  v2f o;
    43.                  o.vertex = UnityObjectToClipPos(v.vertex);
    44.                  o.worldView = -WorldSpaceViewDir (v.vertex);
    45.                  float3 rotated = RotateAroundYInDegrees(v.vertex, _Rotation);
    46.                  return o;
    47.              }
    48.              sampler2D _MainTex;
    49.              float _StretchDown;
    50.              float _Rotation;
    51.            
    52.              fixed4 frag (v2f i) : SV_Target
    53.              {
    54.                  float3 dir = normalize(i.worldView);
    55.                  float2 uv = float2(0.5+atan2(dir.z, dir.x)/(2*UNITY_PI), _StretchDown+dir.y*(1-_StretchDown));
    56.                  uv.x*=3;
    57.                  fixed4 col = tex2D(_MainTex, uv);
    58.                  return col;
    59.              }
    60.  
    61.              ENDCG
    62.          }
    63.      }
    64. }
     
  26. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Read the error carefully. It’s not going to be the same error. Similar, yes, but not the same.

    That question literally starts with you saying the answer. ;)
     
  27. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    Something like this?
    Code (CSharp):
    1. float3 rotated = RotateAroundYInDegrees(o.worldView, _Rotation);
    The error I'm getting is:
    Code (CSharp):
    1. Shader error in 'FX/DoomSkyRotate': 'RotateAroundYInDegrees': no matching 2 parameter function at line 49 (on d3d11)
    2.  
    3. Compiling Vertex program
    4. Platform defines: UNITY_ENABLE_REFLECTION_BUFFERS UNITY_USE_DITHER_MASK_FOR_ALPHABLENDED_SHADOWS UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BOX_PROJECTION UNITY_SPECCUBE_BLENDING UNITY_ENABLE_DETAIL_NORMALMAP SHADER_API_DESKTOP UNITY_COLORSPACE_GAMMA UNITY_LIGHT_PROBE_PROXY_VOLUME UNITY_LIGHTMAP_FULL_HDR
    5.  
    And
    Code (CSharp):
    1. Shader error in 'FX/DoomSkyRotate': undeclared identifier '_Rotation' at line 49 (on d3d11)
    2.  
    3. Compiling Vertex program
    4. Platform defines: UNITY_ENABLE_REFLECTION_BUFFERS UNITY_USE_DITHER_MASK_FOR_ALPHABLENDED_SHADOWS UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BOX_PROJECTION UNITY_SPECCUBE_BLENDING UNITY_ENABLE_DETAIL_NORMALMAP SHADER_API_DESKTOP UNITY_COLORSPACE_GAMMA UNITY_LIGHT_PROBE_PROXY_VOLUME UNITY_LIGHTMAP_FULL_HDR
    5.  
    If I move
    Code (CSharp):
    1. float _Rotation;
    before v2f vert (appdata v), it still gives the same error?
     
  28. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    Was I only half right? Using o.worldview didn’t seem to work.
     
  29. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Most functions take some input values and return an output. The original input variables are generally not directly modified, instead the function modifies a copy of that variable’s data within the function. The
    RotateAroundYInDegress
    takes an input position, and rotation angle, and outputs a rotated position. The output being what you’re setting the function equal to. I.e.:
    vartype output = functionName(input);


    So, what variable are you outputting the function to? And what are you then doing with that output?

    And as an extra hint, remember what value is being used in the fragment shader function.
     
  30. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    Fragment shader is:
    Code (CSharp):
    1.  
    2.   fixed4 frag (v2f i) : SV_Target
    3.              {
    4.                  float3 dir = normalize(i.worldView);
    5.                  float2 uv = float2(0.5+atan2(dir.z, dir.x)/(2*UNITY_PI), _StretchDown+dir.y*(1-_StretchDown));
    6.                  uv.x*=3;
    7.                  fixed4 col = tex2D(_MainTex, uv);
    8.                  return col;
    9.              }
    10.  
    I believe?

    So, i.worldView is the correct value? I thought maybe
    Code (CSharp):
    1. float3 rotated = RotateAroundYInDegrees(i.worldView, _Rotation);
    but that still gives me:
    Code (CSharp):
    1. Shader error in 'FX/DoomSkyRotate': undeclared identifier 'i' at line 49 (on d3d11)
     
  31. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    I think you need to take a step back and go read some basic shader programming tutorials, or maybe just tutorials on basic programming in general.

    No.
    Correct. There is no 'i' in the vertex shader. But there is another
    worldView
    property in the vertex shader. Look at how it's different, and try to understand why.
     
  32. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    There's
    o.worldView
    but I tried that as
    float3 rotated = RotateAroundYInDegrees(o.worldView, _Rotation);
    and it also didn't work, I think o.worldview is just the negative of
    WorldSpaceViewDir 
    ?

    As I said, I'm really inexperienced with shader programming, I'm mainly trying to add a manual rotation to a DoomSky shader that I unfortunately didn't write either. I have worked with shaders before, but I've never been terribly successful with them, I just find it so hard to understand what each part is doing.

    Probably true, but I try my best, shaders just seem to be a lot more involved than other simpler types of game programming, IMHO.
     
  33. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    I think you're overthinking the problem here.

    At this point we're focused on a single line of code. That bit of code and how it functions is basically identical regardless of what kind of programming you're doing.

    You have a function that does something and takes some set of arguments. That function returns a value that you then use. I will tell you that you now have the correct arguments being passed into the function, but you're not seeing anything work because you're not taking the time to understand what you're doing.

    I'm going to try saying this a different way and see if it clicks for you. You want to rotate your skybox. The shader's fragment shader uses a view direction as its only input to calculate a texture UV. That view direction is calculated in the vertex shader as a world space view direction vector that's passed to the fragment shader. So to rotate the skybox you only need to rotate that world space view direction vector. That world space view direction vector is what
    o.worldView
    is. To rotate that you need the math or a function to rotate by some amount around the world up (what the
    RotateAroundYInDegrees
    function does). The function you have outputs (aka "returns") a rotated vector, it does not modify any of the input arguments.

    So what do you need to do to get the world space view direction vector that's passed to the fragment shader to be the rotated value?
     
  34. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    Okay, just to clarify, do I first need to fix this persistent problem with line 49?
    Code (CSharp):
    1.  Shader "FX/DoomSkyRotate"
    2. {
    3.      Properties
    4.      {
    5.          _MainTex ("Texture", 2D) = "white" {}
    6.          _StretchDown ("Stretch", Range(0, 0.5)) = 0
    7.          _Rotation ("Rotation", Range(0, 360)) = 0
    8.      }
    9.      SubShader
    10.      {
    11.          Tags { "RenderType"="Opaque" }
    12.          Cull off ZWrite On ZTest Lequal
    13.          LOD 100
    14.          Pass
    15.          {
    16.              CGPROGRAM
    17.              #pragma vertex vert
    18.              #pragma fragment frag
    19.            
    20.              #include "UnityCG.cginc"
    21.              struct appdata
    22.              {
    23.                  float4 vertex : POSITION;
    24.              };
    25.              struct v2f
    26.              {
    27.                  float3 worldView : TEXCOORD1;
    28.                  float4 vertex : SV_POSITION;
    29.              };
    30.            
    31.              float3 RotateAroundYInDegrees (float3 vertex, float degrees)
    32.         {
    33.             float alpha = degrees * UNITY_PI / 180.0;
    34.             float sina, cosa;
    35.             sincos(alpha, sina, cosa);
    36.             float2x2 m = float2x2(cosa, -sina, sina, cosa);
    37.             return float3(mul(m, vertex.xz), vertex.y).xzy;
    38.         }
    39.  
    40.              v2f vert (appdata v)
    41.              {
    42.                  v2f o;
    43.                  o.vertex = UnityObjectToClipPos(v.vertex);
    44.                  o.worldView = -WorldSpaceViewDir (v.vertex);
    45.                  float3 rotated = RotateAroundYInDegrees(o.worldView, _Rotation);
    46.                  return o;
    47.              }
    48.              sampler2D _MainTex;
    49.              float _StretchDown;
    50.              float _Rotation;
    51.            
    52.              fixed4 frag (v2f i) : SV_Target
    53.              {
    54.                  float3 dir = normalize(o.worldView);
    55.                  float2 uv = float2(0.5+atan2(dir.z, dir.x)/(2*UNITY_PI), _StretchDown+dir.y*(1-_StretchDown));
    56.                  uv.x*=3;
    57.                  fixed4 col = tex2D(_MainTex, uv);
    58.                  return col;
    59.              }
    60.  
    61.              ENDCG
    62.          }
    63.      }
    64. }
    I'm getting:
    Code (CSharp):
    1. Shader error in 'FX/DoomSkyRotate': 'RotateAroundYInDegrees': no matching 2 parameter function at line 49 (on d3d11)
    2.  
    3. Compiling Vertex program
    4. Platform defines: UNITY_ENABLE_REFLECTION_BUFFERS UNITY_USE_DITHER_MASK_FOR_ALPHABLENDED_SHADOWS UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BOX_PROJECTION UNITY_SPECCUBE_BLENDING UNITY_ENABLE_DETAIL_NORMALMAP SHADER_API_DESKTOP UNITY_COLORSPACE_GAMMA UNITY_LIGHT_PROBE_PROXY_VOLUME UNITY_LIGHTMAP_FULL_HDR
    5.  
    and

    Code (CSharp):
    1. Shader error in 'FX/DoomSkyRotate': undeclared identifier '_Rotation' at line 49 (on d3d11)
    2.  
    3. Compiling Vertex program
    4. Platform defines: UNITY_ENABLE_REFLECTION_BUFFERS UNITY_USE_DITHER_MASK_FOR_ALPHABLENDED_SHADOWS UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BOX_PROJECTION UNITY_SPECCUBE_BLENDING UNITY_ENABLE_DETAIL_NORMALMAP SHADER_API_DESKTOP UNITY_COLORSPACE_GAMMA UNITY_LIGHT_PROBE_PROXY_VOLUME UNITY_LIGHTMAP_FULL_HDR
    5.  
    I assume

    fixed4 frag
    is the fragment shader? I would have thought either:

    float3 dir = normalize(o.worldView);


    or

    float3 dir = normalize(rotated);
    ?
     
  35. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    The shader you posted and the line error you're showing don't match, which probably means your shader has some empty lines or other commented stuff at the top, but it's clear what line the error is actually on. And I've already told you how to fix that above. Please read my comments about
    _Rotation
    again.

    https://www.alanzucconi.com/2015/06/10/a-gentle-introduction-to-shaders-in-unity3d/
    Go through all 5 parts., though the first and fourth are the most important ones.
     
  36. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    I currently am doing, thanks for the link.

    This gives me no errors. But it still appears as a pink void, meaning it's obviously not working properly. You mention you told me how to use
    _Rotation
    properly, but I'm not sure if I'm using it properly currently since it's appearing pink (though I guess no errors are thrown up).
     
  37. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    Am I close so far with what I have, or am I still a fair bit off getting a Rotation value to function correctly?
     
  38. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    I'm really trying here, but shaders are really hard!
     
  39. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    I reposted the shader without errors, I'm really stuck on figuring out which part needs changing now :'(
     
  40. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Reposted where?
     
  41. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    Whoops, the quotes messed up:

    Code (CSharp):
    1.  Shader "FX/DoomSkyRotate"
    2. {
    3.      Properties
    4.      {
    5.          _MainTex ("Texture", 2D) = "white" {}
    6.          _StretchDown ("Stretch", Range(0, 0.5)) = 0
    7.          _Rotation ("Rotation", Range(0, 360)) = 0
    8.      }
    9.      SubShader
    10.      {
    11.          Tags { "RenderType"="Opaque" }
    12.          Cull off ZWrite On ZTest Lequal
    13.          LOD 100
    14.          Pass
    15.          {
    16.              CGPROGRAM
    17.              #pragma vertex vert
    18.              #pragma fragment frag
    19.          
    20.              #include "UnityCG.cginc"
    21.              struct appdata
    22.              {
    23.                  float4 vertex : POSITION;
    24.              };
    25.              struct v2f
    26.              {
    27.                  float3 worldView : TEXCOORD1;
    28.                  float4 vertex : SV_POSITION;
    29.              };
    30.          
    31.              float3 RotateAroundYInDegrees (float3 vertex, float degrees)
    32.         {
    33.             float alpha = degrees * UNITY_PI / 180.0;
    34.             float sina, cosa;
    35.             sincos(alpha, sina, cosa);
    36.             float2x2 m = float2x2(cosa, -sina, sina, cosa);
    37.             return float3(mul(m, vertex.xz), vertex.y).xzy;
    38.         }
    39.              v2f vert (appdata v)
    40.              {
    41.                  v2f o;
    42.                  o.vertex = UnityObjectToClipPos(v.vertex);
    43.                  o.worldView = -WorldSpaceViewDir (v.vertex);
    44.                  float3 rotated = RotateAroundYInDegrees(o.worldView, _Rotation);
    45.                  return o;
    46.              }
    47.              sampler2D _MainTex;
    48.              float _StretchDown;
    49.              float _Rotation;
    50.          
    51.              fixed4 frag (v2f i) : SV_Target
    52.              {
    53.                  float3 dir = normalize(rotated);
    54.                  float2 uv = float2(0.5+atan2(dir.z, dir.x)/(2*UNITY_PI), _StretchDown+dir.y*(1-_StretchDown));
    55.                  uv.x*=3;
    56.                  fixed4 col = tex2D(_MainTex, uv);
    57.                  return col;
    58.              }
    59.              ENDCG
    60.          }
    61.      }
    62. }
     
  42. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    You just posted the exact same shader you had before, but with some of the blank lines removed. You've made zero tangible changes to the code. That shader still has the same errors, but you might not see them in the console since Unity won't bother showing the errors again if the compiled shader isn't actually changing. Select the shader in the Project view and look at the errors listed in the inspector. You'll see basically the same ones you've had this whole time.

    Ask specific questions about why something doesn't work or what you don't understand and I may answer them. Don't just repeat the blanket "the shader doesn't work, how do I fix it?" question over and over. As I've said, I'm not going to fix the shader for you. I'm happy to help people learn, but so far you don't seem to be showing any sign your attempting to do so.

    I've already told you what you need to do to fix the problems the shader has. I even tried to explain some of the beginner basics of programming. You're either willfully ignoring it, or just don't understand how to read code. If it's the prior, I'm done. If it's the later, the only recommendation I have left for you is to do a free beginner programming tutorial.

    edit: Actually, I see you did make one additional change. But from that change it is clear you didn't understand the previous tutorial I told you to read.
     
  43. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    Yeah, it didn't show any more errors so I assumed it had stopped causing the issue with the additional change I made. Thanks, I'll check in the inspector instead.

    The problem is I didn't write the original shader, and as I've said, I have zero experience with shader code, all I've been looking to add is a rotation slider to someone else's shader so I can apply the rotational offset of my player to the shader (mod 360 so it works no matter how much is needed). The other option of course was to make the panoramic shader look exactly like this Doomsky shader, but that seemed even harder to someone with no shader coding experience.
    Thing is, programming game logic and programming shaders is a lot different to someone who doesn't understand shaders. I really don't write them or ever need to get dirty with them, this is a one-off situation where I'm trying to add a simple function to a shader I didn't write, and looking at these tutorials, while great for learning, isn't helping me solve this problem sooner, nor understand any easier what it is I need to do to "fix it".

    I'm not a great programmer by any estimation, but I understand most Unity-related code snippets I've been offered and have found on the forums, the answers site and the discord, but this shader code, while it might seem very similar and easy to someone with extensive shader coding experience, is like a completely different language to someone with no experience with it (and someone who is literally trying to just add one thing to an existing shader).
     
  44. Zebbi

    Zebbi

    Joined:
    Jan 17, 2017
    Posts:
    521
    Not sure if anyone else can help with this?