chrisnolet / QuickOutline

Unity asset for adding outlines to game objects
MIT License
466 stars 53 forks source link

Outline width is dependent on camera distance from object #33

Open SpaceDogLaika opened 2 years ago

SpaceDogLaika commented 2 years ago

The width/thickness of the outline changes as the camera gets closer/further away from the game object. How do you set a constant width?

Kotevich commented 2 months ago

The width/thickness of the outline changes as the camera gets closer/further away from the game object. How do you set a constant width?

The with is constant, but it's appears larger than the object because no outline scaling occurs when you move your camera far from object. You can simply improve it

Add this to OutlineFill.shader code

Add new property Scale factor

  Properties {
    [Enum(UnityEngine.Rendering.CompareFunction)] _ZTest("ZTest", Float) = 0

    _OutlineColor("Outline Color", Color) = (1, 1, 1, 1)
    _OutlineWidth("Outline Width", Range(0, 20)) = 5
    _ScaleFactor("Outline Scale Factor", Range(0, 1)) = 1
  }

Modify vert function

      uniform fixed4 _OutlineColor;
      uniform float _OutlineWidth;
      uniform float _ScaleFactor; 

      v2f vert(appdata input) {
        v2f output;

        UNITY_SETUP_INSTANCE_ID(input);
        UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);

        float3 normal = any(input.smoothNormal) ? input.smoothNormal : input.normal;
        float3 viewPosition = UnityObjectToViewPos(input.vertex);
        float3 viewNormal = normalize(mul((float3x3)UNITY_MATRIX_IT_MV, normal));

        // Get distance to camera
        float distanceToCamera = length(viewPosition);

        // Calculate scale factor using camera distance
        float scaleFactor = 1.0 / distanceToCamera; 

        // 0 - standard behavior, 1 - full scaling
        float dynamicOutlineWidth = lerp(_OutlineWidth, _OutlineWidth * scaleFactor, _ScaleFactor);

       // Here we use our dynamic outline width
        output.position = UnityViewToClipPos(viewPosition + viewNormal * -viewPosition.z * dynamicOutlineWidth / 1000.0);

        output.color = _OutlineColor;

        return output;
      }

It needs more calculation of course