Search Unity

LatLong RenderTexture SkyRenderer

Discussion in 'Graphics Experimental Previews' started by danielgsantana, Nov 27, 2019.

  1. danielgsantana

    danielgsantana

    Joined:
    Mar 11, 2015
    Posts:
    19
    Hi all,
    I was trying to do a simple thing for one of our tools that generates and HDR. So what I wanted was to use our preview LatLong HDR RenderTexture as a SkyRenderer. I tried to do a simple Sky (using the HDRISky as a base) that just reads the RenderTexture and then with a shader (similar to the PanoramicSky) render it in the SkyRenderer. The problem is that I don't see any result. Is there any way to trigger a Sky reevaluation this.
    We were trying to go this route, to avoid saving as an exr, import as cubemap and loaded it in the HDRISky, since saving and importing takes quite some time and breaks a "bit" the flow of the tool.

    Cheers,
    Daniel
     
  2. Olmi

    Olmi

    Joined:
    Nov 29, 2012
    Posts:
    624
    Hi @danielgsantana,

    Are you using HDRP?

    What little I've dabbled with custom sky rendering, it seems to be working ok for me. If I'm assuming that you are using HDRP, did you add the Visual Environment override and actually activate your sky and did you also add the override for your custom sky? There's Update Mode parameter, which allows you to define when it updates. I think the default is On Changed.

    At least the things I've tried update instantly when that Update Mode is On Changed.
     
  3. danielgsantana

    danielgsantana

    Joined:
    Mar 11, 2015
    Posts:
    19
    Hi @Olmi ,
    Yes, I'm on HDRP. My problem is that the texture I want to use doesn't exist physically on the disk, it's a render texture, that I want the SkyRenderer to read outside of play mode, so we can show the result of our tool. I do have my custom Sky and SkyRenderer setup on the Visual Enviroment.

    Here is an example of our tool, but running in standard pipeline, where we set the Sky material with a RenderTexture preview.

    That didn't need lots of fiddling to achieve, but in HDRP which has so many features and should handle something like this easily, I have found that is much more difficult due to scarce documentation.

    Cheers,
    Daniel
     
    PolyCrusher likes this.
  4. Olmi

    Olmi

    Joined:
    Nov 29, 2012
    Posts:
    624
    Hm. I wonder what you are doing so I could help a bit more.
    I just did a quick test, RenderTextures show up fine here (from disk) ?
    So just to clarify, you can get a RenderTexture that is on disk to show up, but not one that you render somewhere else?
     
  5. danielgsantana

    danielgsantana

    Joined:
    Mar 11, 2015
    Posts:
    19
    Yup, exactly, so I "fill" a RenderTexture on our tool, and then the on the SkyRenderer (RenderSky method) I get the RenderTexture (store in a static variable, which isn't a very good option, I try to avoid static) and pass it to the shader using the CoreUtils.DrawFullScreen.
    Just a side note, I can make all this work using textures from disk (exporting the RenderTexture every few seconds), but this causes lots of lags of course when you try to do what we show on the previous video.
    Also, most of the SkyRenderers code use Cubemaps, which is something I have been unable to create on our side using the latlong RenderTexture we produce :(, there should be an easy way to convert the RenderTexture to a Cubemap, as easy as there is on import.
     
  6. Olmi

    Olmi

    Joined:
    Nov 29, 2012
    Posts:
    624
    Ok, well I got the texture working from a compute shader too. It's nowhere on the disk and updates every frame. Just like with compute shaders with the old renderpipeline.
     
  7. danielgsantana

    danielgsantana

    Joined:
    Mar 11, 2015
    Posts:
    19
    Uhm interesting. Are you doing anything special with RenderTexture? And are you updating the texture on the RenderSky method? I haven't tried to use compute shaders, just a regular shader that reads the latlong texture doing an xyz to uv translation on the vertex coordinates.
     
  8. Olmi

    Olmi

    Joined:
    Nov 29, 2012
    Posts:
    624
    You have to assign the RenderTexture you have in your SkySettings, then also apply that to the material in your SkyRenderer implementation.
     
  9. danielgsantana

    danielgsantana

    Joined:
    Mar 11, 2015
    Posts:
    19
    Well, I did that already, but for some reason, it wasn't working. Going to review code, must be something I have missed.
    Thanks
     
  10. Olmi

    Olmi

    Joined:
    Nov 29, 2012
    Posts:
    624
    Create public RenderTextureParameter in the class you inherit from SkySettings, then in your RenderSky access that parameter's value and use SetTexture to set it to the material property block you are using. Use the name you have defined in your sky renderer shader. And make sure you have the UVs correct etc. There's many things that might make it look like it's not rendering... I'm sure it will work if you're on 7.1.5.
     
    danielgsantana likes this.
  11. danielgsantana

    danielgsantana

    Joined:
    Mar 11, 2015
    Posts:
    19
    Ok, I picked this again, but no success, I will put all the code I have, may someone can help a little bit. The result is just weird, and again trying to set the RenderTexture (generate at runtime) at runtime, just doesn't work.
    Code to set the RenderTexture at Runtime (snippet only):
    Code (CSharp):
    1.  
    2.             HDRCreatorSky sky = null;
    3.             var found = false;
    4.             var volumes = FindObjectsOfType<Volume>();
    5.             foreach (var volume in volumes)
    6.             {
    7.                 if (volume.sharedProfile.Has<HDRCreatorSky>())
    8.                 {
    9.                     found = volume.sharedProfile.TryGet(out sky);
    10.                     break;
    11.                 }
    12.             }
    13.             sky.skyRenderTexture.value = _cacheBackground;
    14.  
    Sky Settings
    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3. using UnityEngine.Rendering;
    4. using UnityEngine.Rendering.HighDefinition;
    5.  
    6. namespace HeadlessStudio.HDRCreator
    7. {
    8.     [VolumeComponentMenu("Sky/HDR Creator Sky")]
    9.     // Use 99 for the sky id.
    10.     [SkyUniqueID(99)]
    11.     public class HDRCreatorSky : SkySettings
    12.     {
    13.         [Tooltip("Specify the latlong texturemap HDRP uses to render the sky.")]
    14.         public RenderTextureParameter skyRenderTexture = new RenderTextureParameter(null);
    15.  
    16.         public override int GetHashCode()
    17.         {
    18.             int hash = base.GetHashCode();
    19.             unchecked
    20.             {
    21.                 hash = skyRenderTexture.value != null ? hash * 23 + skyRenderTexture.GetHashCode() : hash;
    22.             }
    23.             return hash;
    24.         }
    25.  
    26.         public override Type GetSkyRendererType() => typeof(HDRCreatorSkyRenderer);
    27.     }
    28. }
    SkyRenderer (adapt parts from HDRISky
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Rendering;
    3. using UnityEngine.Rendering.HighDefinition;
    4.  
    5. namespace HeadlessStudio.HDRCreator
    6. {
    7.     public static class HelperSky
    8.     {
    9.         public static RenderTexture _sky;
    10.     }
    11.  
    12.     public class HDRCreatorSkyRenderer : SkyRenderer
    13.     {
    14.         Material m_SkyHDRIMaterial; // Renders a cubemap into a render texture (can be a 3D cube or 2D)
    15.         MaterialPropertyBlock m_PropertyBlock = new MaterialPropertyBlock();
    16.  
    17.         public HDRCreatorSkyRenderer()
    18.         {
    19.         }
    20.  
    21.         public override void Build()
    22.         {
    23.             m_SkyHDRIMaterial = CoreUtils.CreateEngineMaterial(Shader.Find("Hidden/HDRCreator/SkyPreview"));
    24.         }
    25.  
    26.         public override void Cleanup()
    27.         {
    28.             CoreUtils.Destroy(m_SkyHDRIMaterial);
    29.         }
    30.  
    31.         protected override bool Update(BuiltinSkyParameters builtinParams)
    32.         {
    33.             return base.Update(builtinParams);
    34.         }
    35.  
    36.         public override void RenderSky(BuiltinSkyParameters builtinParams, bool renderForCubemap, bool renderSunDisk)
    37.         {
    38.             var hdriSky = (HDRCreatorSky)builtinParams.skySettings;
    39.             if (HelperSky._sky != null)
    40.             {
    41.                 //m_PropertyBlock.SetTexture("_MainTex", HelperSky._sky);
    42.                 m_PropertyBlock.SetTexture("_MainTex", hdriSky.skyRenderTexture.value);
    43.                 m_PropertyBlock.SetFloat("_Exposure", hdriSky.exposure.value);
    44.                 m_PropertyBlock.SetFloat("_Rotation", -Mathf.Deg2Rad * hdriSky.rotation.value);
    45.             }
    46.  
    47.             m_PropertyBlock.SetMatrix("_PixelCoordToViewDirWS", builtinParams.pixelCoordToViewDirMatrix);
    48.  
    49.             CoreUtils.DrawFullScreen(builtinParams.commandBuffer, m_SkyHDRIMaterial, m_PropertyBlock, renderForCubemap ? 0 : 1);
    50.         }
    51.     }
    52. }
    And the shader based on panoramic shader
    Code (CSharp):
    1. Shader "Hidden/HDRCreator/SkyPreview"
    2. {
    3.     HLSLINCLUDE
    4.    
    5.     #pragma vertex Vert
    6.    
    7.     #pragma editor_sync_compilation
    8.     #pragma target 4.5
    9.     #pragma only_renderers d3d11 ps4 xboxone vulkan metal switch
    10.    
    11.     #define LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
    12.    
    13.     #pragma multi_compile _ DEBUG_DISPLAY
    14.     #pragma multi_compile SHADOW_LOW SHADOW_MEDIUM SHADOW_HIGH
    15.    
    16.     #pragma multi_compile USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST
    17.    
    18.     #define ATTRIBUTES_NEED_NORMAL
    19.     #define ATTRIBUTES_NEED_TANGENT
    20.     #define VARYINGS_NEED_POSITION_WS
    21.     #define VARYINGS_NEED_TANGENT_TO_WORLD
    22.    
    23.     #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl"
    24.    
    25.     #define SHADERPASS SHADERPASS_FORWARD_UNLIT
    26.    
    27.     #define HAS_LIGHTLOOP
    28.    
    29.     #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
    30.     #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
    31.     #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonLighting.hlsl"
    32.     #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/SDF2D.hlsl"
    33.     #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
    34.     #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
    35.     #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesFunctions.hlsl"
    36.    
    37.    
    38.     TEXTURE2D(_MainTex);
    39.     SAMPLER(sampler_MainTex);
    40.     half _Exposure;
    41.     float _Rotation;
    42.    
    43.     inline float2 ToRadialCoords(float3 coords)
    44.     {
    45.         float3 normalizedCoords = normalize(coords);
    46.         float latitude = acos(normalizedCoords.y);
    47.         float longitude = atan2(normalizedCoords.z, normalizedCoords.x);
    48.         float2 sphereCoords = float2(longitude, latitude) * float2(0.5 / PI, 1.0 / PI);
    49.         return float2(0.5, 1.0) - sphereCoords;
    50.     }
    51.    
    52.     float3 RotateAroundYInDegrees(float3 vertex, float degrees)
    53.     {
    54.         float alpha = degrees * PI / 180.0;
    55.         float sina, cosa;
    56.         sincos(alpha, sina, cosa);
    57.         float2x2 m = float2x2(cosa, -sina, sina, cosa);
    58.         return float3(mul(m, vertex.xz), vertex.y).xzy;
    59.     }
    60.    
    61.     struct appdata_t
    62.     {
    63.         float4 vertex: POSITION;
    64.         UNITY_VERTEX_INPUT_INSTANCE_ID
    65.     };
    66.    
    67.     struct v2f
    68.     {
    69.         float4 vertex: SV_POSITION;
    70.         float3 texcoord: TEXCOORD0;
    71.         UNITY_VERTEX_OUTPUT_STEREO
    72.     };
    73.    
    74.     v2f Vert(appdata_t v)
    75.     {
    76.         v2f o;
    77.         UNITY_SETUP_INSTANCE_ID(v);
    78.         UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    79.         float3 rotated = RotateAroundYInDegrees(v.vertex, _Rotation);
    80.         o.vertex = TransformWorldToHClip(rotated);
    81.         o.texcoord = v.vertex.xyz;
    82.         return o;
    83.     }
    84.    
    85.     float4 RenderSky(v2f i, float exposure)
    86.     {
    87.         float2 tc = ToRadialCoords(i.texcoord);
    88.         if (tc.x > 1.0)
    89.             return float4(0, 0, 0, 1);
    90.         tc.x = fmod(tc.x, 1);
    91.        
    92.         float4 c = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, tc);
    93.         c *= exposure;
    94.         return float4(c.rgb, 1);
    95.     }
    96.    
    97.     float4 FragBaking(v2f i): SV_Target
    98.     {
    99.         return RenderSky(i, 1.0);
    100.     }
    101.    
    102.     float4 FragRender(v2f i): SV_Target
    103.     {
    104.         return RenderSky(i, _Exposure);
    105.     }
    106.     ENDHLSL
    107.    
    108.     SubShader
    109.     {
    110.         Pass
    111.         {
    112.             ZWrite Off
    113.             ZTest Always
    114.             Blend Off
    115.             Cull Off
    116.            
    117.             HLSLPROGRAM
    118.            
    119.             #pragma fragment FragBaking
    120.             ENDHLSL
    121.            
    122.         }
    123.        
    124.         Pass
    125.         {
    126.             ZWrite Off
    127.             ZTest LEqual
    128.             Blend Off
    129.             Cull Off
    130.            
    131.             HLSLPROGRAM
    132.            
    133.             #pragma fragment FragRender
    134.             ENDHLSL
    135.            
    136.         }
    137.     }
    138.     Fallback Off
    139. }
    140.  
     
  12. Olmi

    Olmi

    Joined:
    Nov 29, 2012
    Posts:
    624
    Just a question, did you actually check that you can access the Volume? Try reading values from it and see if you get correct reads.

    On the surface it looks pretty much OK to my eye. Can't spot the mistake (if there's any) right away after a long day of coding. hm.

    But I just repeat that I'd like to hear that you've tested 100% that you get values from the volume and that you get some test values written correctly to the shader, too.
     
    Last edited: Dec 6, 2019
  13. danielgsantana

    danielgsantana

    Joined:
    Mar 11, 2015
    Posts:
    19
    Hi,
    Yep pretty much tested, and I get the Volume stuff, and can access it. But it's easy to test, without even using the volume code. Just replacing the RenderTextureParameter by a TextureParameter, and feeding a normal equirectangular hdri doesn't show, and the background is all funky.

    Cheers,
    Daniel
     
  14. Olmi

    Olmi

    Joined:
    Nov 29, 2012
    Posts:
    624
    Just out of curiosity I checked a bit more your code; Looks like it's working all ok (if I remember all the changes I needed to make to get it running here) and I could feed my own render texture in just fine, but the problem is your shader which looks pretty weird and does not render the sky correctly here. Correctly I mean it can't output anything, just draws something from the rendering process (diffuse camera texture?) to the sky. Is that what you meant with "all funky" ?. So no wonder it's not working for you.

    I think it would be best to adapt your sky rendering to the current templates (the existing skies) in HDRP.
     
  15. headlessstudio

    headlessstudio

    Joined:
    Feb 25, 2016
    Posts:
    64
    We ended up solving this, as you've mentioned, there were some issues with the shader and some other bits. Unfortunately Unity documentation is very outdated and it's very hard to figure out things without trial and error which is very time consuming. Thanks for your timing looking at this!

    Cheers,
    Artur Leao