Search Unity

Bug Reflections in the wrong position

Discussion in 'Shaders' started by MatheusMarkies, Aug 3, 2020.

  1. MatheusMarkies

    MatheusMarkies

    Joined:
    Apr 16, 2017
    Posts:
    67
    Good afternoon.
    I have a GI system using Enlighten, however the reflexes are getting into the wrong positions in relation to the world. I believe it is a problem with some position matrix I am using.

    sdfg.PNG asgtsafg.PNG asdf.PNG


    GI:
    Code (CSharp):
    1. float3 SampleEnvironment (Surface surfaceWS, BRDF brdf) {
    2.     float3 uvw = reflect(-surfaceWS.viewDirection, surfaceWS.normal);
    3.     float mip = PerceptualRoughnessToMipmapLevel(brdf.perceptualRoughness);
    4.     float4 environment = SAMPLE_TEXTURECUBE_LOD(unity_SpecCube0, samplerunity_SpecCube0, uvw, mip);
    5.     return DecodeHDREnvironment(environment, unity_SpecCube0_HDR);
    6. }
    Shader:
    Code (CSharp):
    1. struct Attributes {
    2.     float3 positionOS : POSITION;
    3.     float3 normalOS : NORMAL;
    4.     float4 tangentOS : TANGENT;
    5.     float2 baseUV : TEXCOORD0;
    6.     float2 lightmapUV: TEXCOORD1;
    7.     float2 dynamicLightmapUV : TEXCOORD2;
    8.     UNITY_VERTEX_INPUT_INSTANCE_ID
    9. };
    10.  
    11. struct Varyings {
    12.     float4 positionCS : SV_POSITION;
    13.     float3 positionWS : VAR_POSITION;
    14.     float3 normalWS : VAR_NORMAL;
    15.     float4 tangentWS : VAR_TANGENT;
    16.     float2 baseUV : VAR_BASE_UV;
    17.     //#if defined(LIGHTMAP_ON)
    18.     float2 lightmapUV : TEXCOORD4;
    19.     //#endif
    20.     //#if defined(DYNAMICLIGHTMAP_ON)
    21.         float2 dynamicLightmapUV : TEXCOORD5;
    22.     //#endif
    23.     UNITY_VERTEX_INPUT_INSTANCE_ID
    24. };
    25.  
    26. Varyings LitPassVertex (Attributes input) {
    27. UNITY_SETUP_INSTANCE_ID(input);
    28.     Varyings output;
    29.  
    30.     output.lightmapUV = input.lightmapUV * unity_LightmapST.xy + unity_LightmapST.zw;
    31.  
    32.     output.dynamicLightmapUV = input.dynamicLightmapUV * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
    33.  
    34.     output.positionWS = TransformObjectToWorld(input.positionOS);
    35.     output.positionCS = TransformWorldToHClip(output.positionWS);
    36.     output.normalWS = TransformObjectToWorldNormal(input.normalOS);
    37.     output.tangentWS = float4(TransformObjectToWorldDir(input.tangentOS.xyz), input.tangentOS.w);
    38.     output.baseUV = input.baseUV;
    39.     return output;
    40. }
    Pixel Shader:
    Code (CSharp):
    1. float4 NmapSec = SAMPLE_TEXTURE2D(_NormalSecond, sampler_NormalSecond, NormalSecUV);
    2.     float scaleSec = UNITY_ACCESS_INSTANCED_PROP(UnityPerMaterial, _NormalSecondStrength);
    3.     float3 normalSec = DecodeNormal(NmapSec, scaleSec);
    4.  
    5.     water.metallic = UNITY_ACCESS_INSTANCED_PROP(UnityPerMaterial, _Metallic);
    6.     water.smoothness = UNITY_ACCESS_INSTANCED_PROP(UnityPerMaterial, _Smoothness);
    7.  
    8.     float3 normal = BlendNormalRNM(normalMain, normalSec);
    9.  
    10.     water.normal = NormalTangentToWorld(normal, input.normalWS, input.tangentWS);
    11.  
    12.     water.fresnelStrength = UNITY_ACCESS_INSTANCED_PROP(UnityPerMaterial, _Fresnel);
    13.     water.color = lerp(UNITY_ACCESS_INSTANCED_PROP(UnityPerMaterial, _WaterDistanceColor),
    14.         lerp(UNITY_ACCESS_INSTANCED_PROP(UnityPerMaterial, _WaterBaseColor), UNITY_ACCESS_INSTANCED_PROP(UnityPerMaterial, _WaterBlendColor),
    15.             Fresnel(water.fresnelStrength, NormalTangentToWorld(water.normal, input.normalWS, input.tangentWS), normalize(_WorldSpaceCameraPos - input.positionWS))),
    16.             input.baseUV.y);
    17.  
    18.     water.interpolatedNormal = input.normalWS;
    19.     water.viewDirection = normalize(_WorldSpaceCameraPos - input.positionWS);
    I am also having a similar problem with Fresnel.
     
    Last edited: Aug 3, 2020
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    Those reflections are working as expected. Reflection probe and cube map based reflections are a rough approximation. It's capturing the world from a specific point in space and using point single point of view that as all of the reflections' point of view. If the surface doing the reflecting isn't aligned to the center of the reflection probe it won't be correct. So basically nothing is going to be showing the correct reflection with reflection probes. It's usually only good enough that people don't notice if they aren't paying attention.

    Planar reflections can more accurate handle reflections on a flat surface, like a floor, and are often used to fake reflections on water, but they're still just an approximation. Even more advanced screen space reflections are just an approximation since it's common for reflections to see things the main view can't, but that's all screen space reflections can show.

    The solution is true raytracing, but that's still expensive, and not supported by Unity outside of the HDRP.
     
    OlliQueck likes this.
  3. MatheusMarkies

    MatheusMarkies

    Joined:
    Apr 16, 2017
    Posts:
    67
    OK! Thank you! But what about the fresnel?
    asdf.PNG
    Code (CSharp):
    1. float Fresnel(float fresnelStrength, float3 normal,float viewDirection){
    2. return fresnelStrength * Pow4(1.0 - saturate(dot(normal, viewDirection)));
    3. }
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    What's the issue with them? Looks about right to me.
     
  5. MatheusMarkies

    MatheusMarkies

    Joined:
    Apr 16, 2017
    Posts:
    67
    I want it like this:
    image_99708.jpg

    The fresnel effect of the URP adjusts in relation to the camera position.
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    Okay. What are you currently seeing in your shader? If you’re not seeing something like the above fresnel (or the 1-fresnel) then something your feeding into is wrong. Either the world space normal isn’t correct, or the view direction isn’t, or the view direction needs to be negated. I don’t know what the rest of your code looks like so it’s not like I can debug it.
     
    MatheusMarkies likes this.
  7. MatheusMarkies

    MatheusMarkies

    Joined:
    Apr 16, 2017
    Posts:
    67
    Properties:
    Code (CSharp):
    1.     Properties {
    2.      
    3.         _WaterBaseColor("Water Color",Color) = (0, 0, 1, 1)
    4.         _WaterBlendColor("Water Blend Color",Color) = (0, 0, 1, 1)
    5.         _WaterDistanceColor("Water Blend Color",Color) = (0, 0, 1, 1)
    6.  
    7.         _Normal("Main Wave Normal",2D) = "bump" {}
    8.  
    9.         _NormalStrength("Normal Strength",Range(0, 1)) = 1
    10.         _NormalSpeed("Normal Speed",Vector) = (0,0,0,0)
    11.  
    12.         _Metallic("Metallic",Range(0, 1)) = 1
    13.         _Smoothness("Smoothness",Range(0, 1)) = 0.97
    14.  
    15.         _Fresnel("Fresnel",Range(0, 1)) = 1
    16.  
    17.         _NormalSecond("Second Wave Normal",2D) = "bump" {}
    18.  
    19.         _NormalSecondStrength("Second Normal Strength",Range(0, 1)) = 1
    20.         _NormalSecondSpeed("Second Normal Speed",Vector) = (0,0,0,0)
    21.  
    22.  
    23.         _Emission("Emission",2D) = "white" {}
    24.   [HDR] _EmissionColor("Emission Color",Color) = (0, 0, 1, 1)
    25.  
    26.           [Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend ("Src Blend", Float) = 1
    27.         [Enum(UnityEngine.Rendering.BlendMode)] _DstBlend ("Dst Blend", Float) = 0
    28.         [Enum(Off, 0, On, 1)] _ZWrite ("Z Write", Float) = 1
    29.  
    Code (CSharp):
    1. UNITY_INSTANCING_BUFFER_START(UnityPerMaterial)
    2.     UNITY_DEFINE_INSTANCED_PROP(float4, _WaterBaseColor)
    3.     UNITY_DEFINE_INSTANCED_PROP(float4, _WaterBlendColor)
    4.     UNITY_DEFINE_INSTANCED_PROP(float4, _WaterDistanceColor)
    5.     UNITY_DEFINE_INSTANCED_PROP(float4, _EmissionColor)
    6.     UNITY_DEFINE_INSTANCED_PROP(float, _NormalStrength)
    7.     UNITY_DEFINE_INSTANCED_PROP(float2, _NormalSpeed)
    8.     UNITY_DEFINE_INSTANCED_PROP(float, _NormalSecondStrength)
    9.     UNITY_DEFINE_INSTANCED_PROP(float2, _NormalSecondSpeed)
    10.     UNITY_DEFINE_INSTANCED_PROP(float, _Metallic)
    11.     UNITY_DEFINE_INSTANCED_PROP(float, _Smoothness)
    12.     UNITY_DEFINE_INSTANCED_PROP(float, _Fresnel)
    13. UNITY_INSTANCING_BUFFER_END(UnityPerMaterial)
    14.  
    15. struct Water{
    16.     float3 baseColor;
    17.     float3 position;
    18.     float3 normal;
    19.     float3 interpolatedNormal;
    20.     float3 viewDirection;
    21.     float depth;
    22.     float3 tangent;
    23.     float3 binormal;
    24. };
    25.  
    26. struct Attributes {
    27.     float3 positionOS : POSITION;
    28.     float3 normalOS : NORMAL;
    29.     float4 tangentOS : TANGENT;
    30.     float2 baseUV : TEXCOORD0;
    31.     float2 lightmapUV: TEXCOORD1;
    32.     float2 dynamicLightmapUV : TEXCOORD2;
    33.     UNITY_VERTEX_INPUT_INSTANCE_ID
    34. };
    35.  
    36. struct Varyings {
    37.     float4 positionCS : SV_POSITION;
    38.     float3 positionWS : VAR_POSITION;
    39.     float3 normalWS : VAR_NORMAL;
    40.     float4 tangentWS : VAR_TANGENT;
    41.     float2 baseUV : VAR_BASE_UV;
    42.     //#if defined(LIGHTMAP_ON)
    43.     float2 lightmapUV : TEXCOORD4;
    44.     //#endif
    45.     //#if defined(DYNAMICLIGHTMAP_ON)
    46.         float2 dynamicLightmapUV : TEXCOORD5;
    47.     //#endif
    48.     UNITY_VERTEX_INPUT_INSTANCE_ID
    49. };
    50.  
    Vertex Shader:
    Code (CSharp):
    1. Varyings LitPassVertex (Attributes input) {
    2. UNITY_SETUP_INSTANCE_ID(input);
    3.     Varyings output;
    4.  
    5.     output.lightmapUV = input.lightmapUV * unity_LightmapST.xy + unity_LightmapST.zw;
    6.  
    7.     output.dynamicLightmapUV = input.dynamicLightmapUV * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
    8.  
    9.     output.positionWS = TransformObjectToWorld(input.positionOS);
    10.     output.positionCS = TransformWorldToHClip(output.positionWS);
    11.     output.normalWS = TransformObjectToWorldNormal(input.normalOS);
    12.     output.tangentWS = float4(TransformObjectToWorldDir(input.tangentOS.xyz), input.tangentOS.w);
    13.     output.baseUV = input.baseUV;
    14.     return output;
    15. }
    Pixel Shader:

    ViewDir:
    Code (CSharp):
    1. water.viewDirection =  normalize(_WorldSpaceCameraPos.xyz - input.positionWS.xyz);
    2.  
    Normal (Pixel Shader):
    Code (CSharp):
    1. water.normal = NormalTangentToWorld (normal, input.normalWS, input.tangentWS);
    2.  
    Fresnel + BaseColor:
    Code (CSharp):
    1. water.fresnelStrength = UNITY_ACCESS_INSTANCED_PROP(UnityPerMaterial, _Fresnel);
    2.     water.color = lerp(UNITY_ACCESS_INSTANCED_PROP(UnityPerMaterial, _WaterDistanceColor),
    3.         lerp(UNITY_ACCESS_INSTANCED_PROP(UnityPerMaterial, _WaterBaseColor), UNITY_ACCESS_INSTANCED_PROP(UnityPerMaterial, _WaterBlendColor),
    4.             Fresnel(water.fresnelStrength, water.normal, water.viewDirection)),
    5.             input.baseUV.y);
    Fresnel Function:
    Code (CSharp):
    1. float Fresnel(float fresnelStrength, float3 normal,float viewDirection){
    2. return fresnelStrength * Pow4(1.0 - saturate(dot(normal, viewDirection)));
    3. }

    The shader is a bit messy, so I just sent the parts of the fresnel .:confused:

    Capturar.PNG dasf.PNG DNS.PNG sdfg.PNG
     
  8. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    Unfortunately, there's still not really anything obvious in that code, though I agree the reflections look weird on that plane. That might not be caused by the fresnel itself though. I'd go the route of having your shader explicitly output the fresnel to double check it looks wrong. Then check the world normal; output the world space normal and see if it looks correct and roughly aligns with the world axis.
     
    MatheusMarkies likes this.
  9. MatheusMarkies

    MatheusMarkies

    Joined:
    Apr 16, 2017
    Posts:
    67
    Thank you for your help!
    I just discovered the problem.
    I put float in ViewDir instead of float3 :confused: kkkkkkkkkkkkkk.

    In that Line:
    Code (CSharp):
    1. float Fresnel(float fresnelStrength, float3 normal,float <-- viewDirection)
    2. {
    3.  
    asdf.PNG
     
  10. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    Oh, hah! Yeah. It was right there the whole time. I was looking at the code and not the function declaration!