标准着色器顶部的自定义剪切着色器? (统一)

时间:2018-02-11 15:22:02

标签: unity3d opengl shader

我想用着色器代码(hlsl)在对象上绘制一条水平线。

剪切着色器只是将距离移动到曲面着色器中的给定Y坐标,并检查它是否高于给定值。

如果是这样,它会丢弃。结果是一个着色器,它可以简单地剪掉所有不在一条线上的像素。

void surf (Input IN, inout SurfaceOutputStandard o) {
    // Albedo comes from a texture tinted by color
    fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    float d = abs(_YClip - IN.worldPos.y); // _YClip is is the properties and can be changed

    if (d > _LineThickness) {
        discard;
    }
}

我可以在不更改代码的情况下以某种方式将此着色器与标准Unity着色器结合使用吗?

我计划使用Gizmo着色器渲染线条和所有类型的东西。如果我能告诉团结将这个Gizmo着色器渲染到最顶层,那将是非常实用的。

1 个答案:

答案 0 :(得分:0)

我相信您可以根据自己的目的使用或改编此着色器。

在y轴到达之前显示的图像。

Before

显示期间的图像,其中一半高于截止y值,另一半低于。请注意,它溶解的图案取决于您自己提供的纹理图案。所以应该可以有一个严格的截止,而不是更奇怪和不均匀的模式。

During

对象完全通过截止y值后。我在这种情况下所做的是隐藏起始对象内部的一个对象,该对象比您看到的第一个对象略小。但是如果你内心没有任何东西,那么这个物体就会被看不见或被剪掉。

After

Shader "Dissolve/Dissolve"
{
Properties
{
    _MainTex ("Texture", 2D) = "white" {}
    _DissolveTexture("Dissolve Texture", 2D) = "white" {}
    _DissolveY("Current Y of the dissolve effect", Float) = 0
    _DissolveSize("Size of the effect", Float) = 2
    _StartingY("Starting point of the effect", Float) = -1 //the number is supposedly in meters. Is compared to the Y coordinate in world space I believe.
}
SubShader
{
    Tags { "RenderType"="Opaque" }
    LOD 100

    Pass
    {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        // make fog work
        //#pragma multi_compile_fog

        #include "UnityCG.cginc"

        struct appdata
        {
            float4 vertex : POSITION;
            float2 uv : TEXCOORD0;
        };

        struct v2f
        {
            float2 uv : TEXCOORD0;
            //UNITY_FOG_COORDS(1)
            float4 vertex : SV_POSITION;
            float3 worldPos : TEXCOORD1;
        };

        sampler2D _MainTex;
        float4 _MainTex_ST;
        sampler2D _DissolveTexture;
        float _DissolveY;
        float _DissolveSize;
        float _StartingY;

        v2f vert (appdata v) //"The vertex shader"
        {
            v2f o;
            o.vertex = UnityObjectToClipPos(v.vertex);
            o.uv = TRANSFORM_TEX(v.uv, _MainTex);
            o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
            //UNITY_TRANSFER_FOG(o,o.vertex);
            return o;
        }

        fixed4 frag (v2f i) : SV_Target //"For drawing the pixel on top"
        {
        float transition = _DissolveY - i.worldPos.y; //Cutoff value where world position is taken into account.
        clip(_StartingY + (transition + (tex2D(_DissolveTexture, i.uv)) * _DissolveSize)); //Clip = cutoff if above 0.
        //My understanding: If StartingY for dissolve effect + transition value and uv mapping of the texture is taken into account, clip off using the _DissolveSize.
        //This happens to each individual pixel.

            // sample the texture
            fixed4 col = tex2D(_MainTex, i.uv);
            // apply fog
            //UNITY_APPLY_FOG(i.fogCoord, col);
            //clip(1 - i.vertex.x % 10); //"A pixel is NOT rendered if clip is below 0."
            return col;
        }
        ENDCG
    }
}
}

您可以在此处看到可用的检查器字段。

Inspector

我有一个与x轴相似的脚本。