Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

How To Make Realtime Reflection?

Discussion in 'General Graphics' started by awplays49, Dec 23, 2015.

  1. awplays49

    awplays49

    Joined:
    Nov 9, 2014
    Posts:
    36
    I want to bring my progress to the table so that no one thinks I tried nothing.

    Mirror shader:

    Code (CSharp):
    1. Shader "Example/Specular" {
    2.     Properties {
    3.         _Color ("Color", Color) = (1.0,1.0,1.0,1.0)
    4.         _Atten ("Atten", float) = 1
    5.         _SpecColor ("Specular Color", Color) = (1.0,1.0,1.0,1.0)
    6.         _Shininess ("Shininess", float) = 10
    7.         _Reflection ("Reflection", float) = 0.5
    8.         _Cube ("Cubemap", Cube) = "" {}
    9.     }
    10.     SubShader {
    11.         Tags
    12.         {
    13.             "LightMode" = "ForwardBase"
    14.         }
    15.         Pass
    16.         {
    17.             CGPROGRAM
    18.            
    19.             #pragma vertex vert
    20.             #pragma fragment frag
    21.            
    22.             float4 _Color;
    23.             float _Atten;
    24.             float4 _SpecColor;
    25.             float _Shininess;
    26.             float _Reflection;
    27.            
    28.             float4 _LightColor0;
    29.  
    30.             samplerCUBE _Cube;
    31.            
    32.             struct VertexInput {
    33.                 float4 vertex : POSITION;
    34.                 float3 normal : NORMAL;
    35.             };
    36.  
    37.             struct VertexOutput {
    38.                 float4 pos : POSITION;
    39.                 float4 col : COLOR;
    40.                 float3 view : TEXCOORD0;
    41.                 float3 norm : TEXCOORD1;
    42.             };
    43.            
    44.             VertexOutput vert (VertexInput input) {  
    45.                 VertexOutput output;
    46.  
    47.                 // Matrix variables
    48.                    float4x4 worldMatrix = _Object2World;
    49.                 float4x4 localMatrix = _World2Object;
    50.  
    51.                 // Positions
    52.                 float3 cameraPosition = mul (localMatrix, _WorldSpaceCameraPos);
    53.                
    54.                 // Directions
    55.                 float3 normalDirection = normalize (mul (localMatrix, float4 (input.normal, 0.0)).xyz);
    56.                 float3 lightDirection = normalize (_WorldSpaceLightPos0.xyz);
    57.                 float3 viewDirection = normalize (cameraPosition - input.vertex);
    58.  
    59.                 // Diffuse
    60.                 float3 diffuseLightColor = _LightColor0.rgb * max (0.0, dot (normalDirection, lightDirection));
    61.                 float3 diffuseColor = _Color.rgb * diffuseLightColor * _Atten;
    62.  
    63.                 // Specular
    64.                   float3 lightToView = normalize(lightDirection + viewDirection);
    65.                   float3 specularLightColor = pow (max (0, dot (normalDirection, lightToView)), _Shininess) * pow (max (0, dot (reflect (-lightDirection, normalDirection), viewDirection)), _Shininess);
    66.                   float3 specularColor = _SpecColor.rgb * specularLightColor * _Atten;
    67.  
    68.                   // Combination of all colors
    69.                 float3 colorFinal = diffuseColor + specularColor + UNITY_LIGHTMODEL_AMBIENT;
    70.  
    71.                 // Apply variables calculated above
    72.                 output.col = float4 (colorFinal, 1.0);
    73.                 output.pos = mul (UNITY_MATRIX_MVP, input.vertex);
    74.                 output.view = viewDirection;
    75.                 output.norm = normalDirection;
    76.                 return output;
    77.             }
    78.                
    79.             float4 frag (VertexOutput output) : COLOR {  
    80.                 float3 reflection = reflect (output.view, normalize (output.norm)) * _Reflection;
    81.                 return texCUBE (_Cube, reflection) * _Reflection;
    82.             }
    83.             ENDCG
    84.         }
    85.     }
    86. }
    Reflection probe code:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class RenderProbe : MonoBehaviour {
    5.  
    6.     public ReflectionProbe probe;
    7.  
    8.     void Update () {
    9.         probe.RenderProbe();
    10.     }
    11. }
    12.  
    Mirror Code:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class SetMirror : MonoBehaviour {
    5.  
    6.     public ReflectionProbe probe;
    7.  
    8.     void Update () {
    9.         GetComponent <MeshRenderer> ().material.SetTexture ("_Cube", probe.texture);
    10.     }
    11. }
    12.  
    Outcome? As I get closer, the mirror gets more pixelated, and the reflection is upside down.

    Another question while I'm here, how can I make my shader so that it can be semi-reflective?
     
  2. awplays49

    awplays49

    Joined:
    Nov 9, 2014
    Posts:
    36
  3. macdude2

    macdude2

    Joined:
    Sep 22, 2010
    Posts:
    686
    Thats a horrible nigh atrocious way to do it no offense. Look it up on the asset store for a significantly more efficient way.
     
  4. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,328
    At a quick glance I can tell you that you'll get much better results if you stop normalizing stuff like view vector, light vector and direction to whatever vector in the vertex shader.

    Calculate the difference (worldPos - whateverPos), pass it into pixel shader unnormalized and normalize within pixelshader.

    However, you don't even need to write the shader.

    Just use standard shader, make reflective material, and put it into reflection probe. Set probe to realtime.

    ---

    The jagged lines are triangle edges. That's what you get when you normalize stuff in vertex shader. Normalized vectors (to light, to camera, to whatever) don't interpolate properly.
     
    theANMATOR2b, goat and Ryiah like this.
  5. awplays49

    awplays49

    Joined:
    Nov 9, 2014
    Posts:
    36
    @neginfinity Hello,

    Thanks for your quick reply, Im glad it is something I can fix. I am actually just writing the shader because I want to write a specific shader I had in mind in the future. But there is no use in trying to write a new shader if I have no understanding of how certain effects are performed. That is why Im trying to make a mirror shader.

    Regarding the upside down effect, Mirrors don't actually act like that in real life, do you think it has to do with the normalizing?

    Now that you mention it, I actually do see myself in the mirror properly when I get about 1 unit away from the surface.

    One other thing, the pixelatedness? I have it on 256 in the reflection probe. It looks fine from a distance, but when my capsule player gets close it almost seems to "zoom" in on it if it were far away, rather than rendering it in higher detail when it gets close.
     
  6. awplays49

    awplays49

    Joined:
    Nov 9, 2014
    Posts:
    36
    @neginfinity Hello again,

    I took out the normalize words and nothing happened. Im not sure what to do now. I suppose Ill wait for a reply and in the meantime keep looking.