2

Hello I have followed a video series on YouTube made by Sebastian league on procedural generation and I have followed his whole video series, however on my part there are black spots in the mesh, only on water regions. I'm using global mode for those wondering, also using unity 2019.4.6f1. I want to get rid of the black spots have tried to build and run the and the blackspots were there.

Link to his serie is: https://www.youtube.com/watch?v=wbpMiKiSKm8&list=PLFt_AvWsXl0eBW2EiBtl_sxmDtSgZBxB3 I have dowloaded his project on GitHub and he seems doesn't have a problem with here is his GitHub page: https://github.com/SebLague/Procedural-Landmass-Generation Also here is a picture -> here

I'm creating my own custom shader for the terrain, here it is

Shader "Custom/terrain"
{   
    // this properties will be added to our meshMaterial
    Properties {
        testTexture("Texture", 2D) = "white"{}
        testScale("Scale", Float) = 1
    }
    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

        const static int maxLayerCount = 8;
        const static float epsilon = 1E-4;

        int layerCount;
        // float3 because of RGB
        float3 baseColors[maxLayerCount];
        float baseStartHeights[maxLayerCount];
        float baseBlends[maxLayerCount];
        float baseColorStrength[maxLayerCount];
        float baseTextureScales[maxLayerCount];

        float minHeight;
        float maxHeight;

        sampler2D testTexture;
        float testScale;

        UNITY_DECLARE_TEX2DARRAY(baseTextures);

        struct Input {
            float3 worldPos;
            float worldNormal;
        };

        // float a is min value, float b is max value and value is current value 
        float inverseLerp(float a, float b, float value) {
            // saturate means clamp the value between 0 and 1 
            return saturate((value - a)/(b - a));
        }
        // 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 assumeuniformscaling
        UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)


        float3 triplanar(float3 worldPos, float scale, float3 blendAxis, int textureIndex) {
            float3 scaledWorldPos = worldPos / scale;
            // tripleaner mapping 
            float3 xProjection = UNITY_SAMPLE_TEX2DARRAY(baseTextures, 
            float3(scaledWorldPos.y, scaledWorldPos.z, textureIndex)) * blendAxis.x;

            float3 yProjection = UNITY_SAMPLE_TEX2DARRAY(baseTextures, 
            float3(scaledWorldPos.x, scaledWorldPos.z, textureIndex)) * blendAxis.y;

            float3 zProjection = UNITY_SAMPLE_TEX2DARRAY(baseTextures, 
            float3(scaledWorldPos.x, scaledWorldPos.y, textureIndex)) * blendAxis.z;
            return xProjection + yProjection + zProjection;
        }

        // this function will be called for every pixel that our mesh is visible
        // we want to set the color at that surface 
        void surf (Input IN, inout SurfaceOutputStandard o) {
            float heightPercent = inverseLerp(minHeight, maxHeight, IN.worldPos.y);
            float3 blendAxis = abs(IN.worldNormal);
            blendAxis /= blendAxis.x + blendAxis.y + blendAxis.z;

            for (int i = 0; i < layerCount; i++) { 
                float drawStrength = inverseLerp(-baseBlends[i]/2 - epsilon, baseBlends[i]/2, (heightPercent - baseStartHeights[i]));
                float3 baseColor = baseColors[i] * baseColorStrength[i];
                float3 textureColor = triplanar(IN.worldPos, baseTextureScales[i], blendAxis, i) * (1-baseColorStrength[i]);
                // if drawStrength is 0 then we would set color to black 
                // but what we want is that if drawstength is 0 
                // then we want to use the same color, albedo * 1 + 0 will be same (what we want)
                o.Albedo = o.Albedo * (1-drawStrength) + (baseColor + textureColor) * drawStrength;
            }
        }
        ENDCG
    }
    FallBack "Diffuse"
}
Ruzihm
  • 19,749
  • 5
  • 36
  • 48
atheer21
  • 61
  • 1
  • 9
  • looks like it could be that `drawStrength` is always 0 for those pixels. Just to confirm, what happens if you add the line `o.Albedo = float3(1,0,1);` at the top of the `surf` function and change the `o.Albedo = o.Albedo *...` line to `o.Albedo = o.Albedo * (1-drawStrength) + float3(0,1,0) * drawStrength;` I'm curious if you get pure magenta where the black spots were and degrees of green-magenta everywhere else. – Ruzihm Oct 03 '19 at 06:05
  • If that's the case, make sure that the lowest `baseStartHeights` is exactly 0. In case the inspector might be displaying 0 even though it is actually slightly nonzero, make sure you type in 0 and press **Enter** in the field. Let me know if that helps or if that wasn't the case. – Ruzihm Oct 03 '19 at 06:34
  • 1
    @Ruzihm I Have tried your solution and everything is just green a very powerful color of green, the whole chunk is green there is none magenta, the black spots have disappeared. And bout the baseStartHeight the thing is that I divided mesh in layers based where on the height on mesh we are. The water part start at baseheight zero so I don't think that the value is slight nonzero. – atheer21 Oct 03 '19 at 20:11
  • Okay. I'm curious if it is due to the height of those pixels being at the minHeight, or if the normals also play a part in the problem. Starting back from the code in the question, change the `float heightPercent = ... ` line to `float heightPercent = 0;`. Let me know what it looks like when you do that. if the black spots stay where they are, if everything turns black, if everything turns blue, or something else. – Ruzihm Oct 03 '19 at 20:36
  • Also, can you share any c# code and/or inspector screenshots where you assign to `baseStartHeights` and `baseBlends`. I'm having trouble seeing problems in the shader code and I think there might be something going wrong in how the parameters are set. – Ruzihm Oct 03 '19 at 20:43
  • @ruzihm The problem is solved, there was an error in the code. Thank you for your time :) – atheer21 Oct 04 '19 at 20:48
  • Glad to hear it! Consider [answering your own question](https://stackoverflow.com/help/self-answer) and accepting it to help people who come here looking for help to the same question. – Ruzihm Oct 04 '19 at 20:49

1 Answers1

2

So I thought the problem was the code but I compared my code against Sebastian league code that is by the way available at GitHub and the there was nothing there however the problem turned out to be with the animation curve that we used to assign base heights. Just make sure that it stars a bit below zero and that was in my case the solution

Github Link: https://github.com/SebLague/Procedural-Landmass-Generation/tree/master/Proc%20Gen%20E21

atheer21
  • 61
  • 1
  • 9