Shader saturate()不应创建渐变

问题描述 投票:0回答:1

为Unity写一个着色器,我不明白这里发生了什么。我有一个附有材料的球体。材质已附加着色器。着色器非常简单,它会生成一些单纯形噪声,然后将其用作球体的颜色。

着色器代码:

Shader "SimplexTest"
{
    Properties
    {
      _SimplexScale("Simplex Scale", Vector) = (4.0,4.0,4.0,1.0)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" "Queue"="Geometry" }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "SimplexNoise3D.hlsl"

            float3 _SimplexScale;

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 position : SV_POSITION;
                float4 color : COLOR0;
            };

            v2f vert (appdata v)
            {
                v2f o;
                float4 worldPosition = mul(unity_ObjectToWorld, v.vertex);
                o.position = UnityObjectToClipPos(v.vertex);

                float small = snoise(_SimplexScale * worldPosition);
                // o.color = small * 10; // Non-Saturated (A) Version
                o.color = saturate(small * 10); // Saturated (B) Version

                return o;
            }


            fixed4 frag (v2f i) : SV_Target
            {
                return i.color;
            }
            ENDCG
        }
    }
}

单纯噪声函数来自Keijiro's Github

非饱和(A)版本:Version A

饱和(B)版本:Version B

非饱和版本(版本A)符合预期。通过将单纯形噪声乘以10,可以得到一系列的白色和黑色斑点。理论上,饱和(B版)应该将所有白色斑点从1处切掉,将黑色斑点从0处切掉。但是它似乎正在创建一个全新的渐变,我不知道为什么。

我想我缺少一些关键的假设,但由于数学似乎是正确的,所以我不清楚那会是什么。

unity3d shader vertex-shader cg
1个回答
0
投票

在灰色区域中,片段着色器的像素位于颜色0和1的顶点之间。这意味着输入将在这些值之间进行插值,从而创建灰色i.color值。


一种解决方案是为每个三角形具有单独的顶点,以便每个三角形都可以使其所有顶点具有相同的法线。一旦每个三角形的所有顶点共享相同的法线,就可以基于顶点着色器中的SV_NORMAL值而不是变换后的POSITION值来制作颜色。

然后,它将按预期工作。


示例A中您的问题未在很大程度上发生的原因是,它是在某物(0?非常负的数字?没有足够的信息可从问题中得出)之间进行插值。像素不在所有黑色顶点的三角形上,而是变为白色。

© www.soinside.com 2019 - 2024. All rights reserved.