Bump map failing to cause changes in surface of sphere in Unity

90 Views Asked by At

I've been having some trouble with randomly perturbing the surface of a sphere with a bump map in Unity (v2021.3.18f1) for a VR application. Here are the steps I've taken so far:

  • created a sphere with radius of 30
  • created a material with maximum opacity (albedo=255) and assigned it to the sphere; the color of the material is green
  • written a custom shader (template=Standard Surface Shader) which does the following things:
    • creates a visible interior surface for the sphere by:
      • duplicating the mesh on the exterior face
      • flipping the normals
      • turning off backface culling
    • applies a bump map to the exterior surface
  • created a bump map in GIMP (100x100 noisy grayscale .png image)
  • imported the bump map as an asset and linked it to the abovementioned material; set the texture type of the bump map to "normal map"
  • set the bump scale to 1.0 to maximize its effect

ChatGPT suggests that the mesh geometry may not be detailed enough to render the bumps. The mesh has over 700 polygons and seems detailed enough but not totally sure, this is my first time using Unity or doing anything with graphics. A screenshot of the wireframe rendering is below. Also, there is a screenshot of the bump map itself.

The environment has a directional light pointing at the sphere at somewhat of an angle. I've tried to create shadows on the surface of the sphere to accentuate any tiny bumps to no avail.

Below the images is the shader code.

Wireframe Rendering of Sphere Mesh

Bump map

Shader "Custom/SphereShader"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0

        // START MODS
        _BumpMap ("Bump Map", 2D) = "bump" {}
        _BumpScale ("Bump Scale", Range(0, 1)) = 1.0
        // END MODS
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;
        
        // START MODS
        sampler2D _BumpMap;
        //END MODS

        struct Input
        {
            float2 uv_MainTex;
            
            // START MODS
            float3 worldNormal;
            float3 worldPos;
            INTERNAL_DATA
            // END MODS
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;

        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
        // #pragma instancing_options assume uniform scaling
        UNITY_INSTANCING_BUFFER_START(Props)
        // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)
        
        // START MODS
        // function to perturb surface normal
        inline float3 perturb_normal(float3 normal, float3 pos, float3 worldNormal, float3 worldTangent)
        {
            float3 map = UnpackNormal(tex2D(_BumpMap, pos.xy));
            map = 2.0 * map - 1.0;
            map.xy *= 1.0; // adjust the bump map strength here
            map = normalize(map);

            // calculate tangent space basis
            float3 worldBinormal = cross(worldNormal, worldTangent);
            float3x3 tangentSpace = float3x3(worldTangent, worldBinormal, worldNormal);

            // perturb normal
            return normalize(mul(tangentSpace, map));
        }

        void surf (Input IN, inout SurfaceOutputStandard o)
        { 

            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;

            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;

            // apply bump map to surface normal
            float3 worldNormal = UnpackNormal(tex2D(_BumpMap, IN.uv_MainTex) * 2.0 - 1.0);
            worldNormal = normalize(worldNormal);
            // use the worldNormal to perturb the surface normal
            o.Normal = perturb_normal(o.Normal, IN.worldPos, worldNormal, IN.worldNormal);
        }
        // END MODS

        ENDCG
        
        // START MODS
        // turn off backface culling
        Cull Off

        // make the mesh double-sided
        Pass
        {
            Name "FORWARD"
            Tags { "LIGHTMODE" = "ForwardBase" }
            ZWrite On
            Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
            };

            struct v2f {
                float4 pos : SV_POSITION;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float NORMALIZING_CONST = 255.0;
                float R = 30.0 / NORMALIZING_CONST;
                float G = 245.0 / NORMALIZING_CONST;
                float B = 90.0 / NORMALIZING_CONST;

                return fixed4(R, G, B, 1);
            }
            // END MODS

            ENDCG
        }
    
    }
    FallBack "Diffuse"
}

Why aren't there any bumps on the sphere's surface? What can I do to move towards that goal?

0

There are 0 best solutions below