让AI臣服,而不是被它替代!让ChatGPT为我们编写Unity3d Shaderlab的着色器(shader)

前言

ChatGPT的火热大家应该都有目共睹,文案工作者、翻译工作者和画师等各种行业都在被嘲即将失业。不光是这些岗位的员工,作为资深社畜程序猿也能感受到会受到冲击。网上很多人都在发ChatGPT写的代码,并开始大肆宣扬AI要取代程序员了,今天测一测使用ChatGPT来生成一些代码,看看到底AI到底会不会真的直接替程序猿,还是大家炒作的噱头。当然使用ChatGPT还是需要各种操作,科学上网、注册和付费等,这里就不进行教学了,如果愿意折腾的请自行查询折腾吧。这里就以Unity3d的着色器需求进行了测试。

绿幕抠图

绿幕抠图功能在视频交互场景还是很有这方面的需求,在有绿幕摄像头画面的场景中,将人物进行抠图并叠加场景等,这里我让ChatGPT帮我编写一个绿幕抠图的着色器:
在这里插入图片描述

其给出的源码如下:

Shader "Custom/GreenScreen" {
    
    
    Properties {
    
    
        _MainTex ("Texture", 2D) = "white" {
    
    }
        _GreenScreenKeyColor ("Green Screen Key Color", Color) = (0,1,0,1)
    }
 
    SubShader {
    
    
        Tags {
    
    "Queue"="Transparent" "RenderType"="Opaque"}
        Pass {
    
    
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
 
            sampler2D _MainTex;
            float4 _GreenScreenKeyColor;
            float4 _ScreenParams;
 
            struct appdata {
    
    
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };
 
            struct v2f {
    
    
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };
 
            v2f vert (appdata v) {
    
    
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }
 
            fixed4 frag (v2f i) : SV_Target {
    
    
                float4 tex = tex2D(_MainTex, i.uv);
                float3 key = _GreenScreenKeyColor.rgb;
                float3 src = tex.rgb;
                float dist = distance(key, src);
                if (dist < 0.05) {
    
    
                    discard;
                } else {
    
    
                    return tex;
                }
            }
            ENDCG
        }
    }
}

并给出了简单的说明:

该shader使用了一个名为“_GreenScreenKeyColor”的属性,它接受一个颜色值作为输入,用于指定要去除的颜色。在顶点着色器中,将纹理坐标(uv)传递给片段着色器。在片段着色器中,将使用tex2D函数从_MainTex采样纹理,并计算像素的颜色是否与关键颜色接近。如果是,则放弃该像素;否则返回原始纹理颜色。

当我将上面的代码放入Unity工程中新建的shader文件中时,还是不正确的效果,而且编译有错误:
在这里插入图片描述
在这里插入图片描述

我依次按提示进行了修改,一个是多出的变量定义,另一个错误是if – else中有分支无返回的逻辑错误。修改后的代码:

Shader "Custom/GreenScreen" {
    
    
    Properties{
    
    
        _MainTex("Texture", 2D) = "white" {
    
    }
        _GreenScreenKeyColor("Green Screen Key Color", Color) = (0,1,0,1)
    }

        SubShader{
    
    
            Tags {
    
    "Queue" = "Transparent" "RenderType" = "Opaque"}
            Pass {
    
    
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag

                sampler2D _MainTex;
                float4 _GreenScreenKeyColor;

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

                struct v2f {
    
    
                    float2 uv : TEXCOORD0;
                    float4 vertex : SV_POSITION;
                };

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

                fixed4 frag(v2f i) : SV_Target {
    
    
                    float4 tex = tex2D(_MainTex, i.uv);
                    float3 key = _GreenScreenKeyColor.rgb;
                    float3 src = tex.rgb;
                    float dist = distance(key, src);
                    if (dist < 0.05) {
    
    
                        discard;
                    }
                    return tex;
                }
               ENDCG
            }
        }
}

这样我在网上找了个“勇敢勇敢我的朋友”的绿幕素材视频进行了测试,在设置了抠图颜色值的_GreenScreenKeyColor,效果如下:
在这里插入图片描述

其实这个着色器基本满足了我的功能需求,不过因为它的属性还是单一的颜色抠图设置,所以会有边缘未扣干净的情况。

轮廓增强

这里我继续进行了轮廓增强的shader的对话:
在这里插入图片描述

自带的说明,该shader具有三个属性:纹理、轮廓颜色和轮廓宽度。在主Pass中,我们获取输入像素的颜色,并根据轮廓宽度计算出alpha值,然后将输入颜色和轮廓颜色进行插值,从而产生轮廓增强效果。

同样的这个着色器也是没法直接使用的:

undeclared identifier '_MainTex’Compiling Fragment program Platform…

‘tex2D’: no matching 2 parameter intrinsic function; Possible intrinsic functions are: tex2D(sampler2D, float2|half2|min10float2|min16float2)…

invalid subscript ‘uv’ Compiling Vertex program Platform…

Output value ‘vert’ is not completely initialized Compiling Vertex program Platform…

按提示修改为如下:

Shader "Custom/Outline" {
    
    
    Properties{
    
    
        _MainTex("Texture", 2D) = "white" {
    
    }
        _OutlineColor("Outline Color", Color) = (0,0,0,1)
        _OutlineWidth("Outline Width", Range(0,10)) = 1
    }

        SubShader{
    
    
            Tags {
    
    "Queue" = "Transparent" "RenderType" = "Opaque"}
            Pass {
    
    
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag

                sampler2D _MainTex;
                fixed4 _OutlineColor;
                float _OutlineWidth;

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

                struct v2f {
    
    
                    float4 pos : SV_POSITION;
                    float2 uv : TEXCOORD0;
                };

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


                fixed4 frag(v2f i) : SV_Target {
    
    
                    fixed4 col = tex2D(_MainTex, i.uv);
                    float2 d = fwidth(i.uv);
                    float alpha = 1 - smoothstep(_OutlineWidth - d.x, _OutlineWidth + d.x, col.a);
                    return lerp(col, _OutlineColor, alpha);
                }
                ENDCG
            }
        }
}

但是功能并不是我所需要的:
在这里插入图片描述

可能进行多次对话和优化,其充分理解了需求能解决这个问题。我让他继续进行了代码解释:

以上Shader代码定义了一个名为"Custom/Outline"的Shader。该Shader有三个属性:_MainTex(纹理)、_OutlineColor(轮廓颜色)和_OutlineWidth(轮廓宽度)。在实际使用中,这些属性可以在Material面板上进行设置。

Shader中的SubShader定义了渲染管线阶段,并且使用了Tags指令来指定Shader Queue和RenderType。在这个例子中,我们将队列设置为Transparent并将RenderType设置为Opaque以确保深度测试正常工作。

Pass指令用于定义着色器最终的输出颜色,包括顶点着色器和片元着色器两种类型。在这个例子中,我们使用CGPROGRAM指令将Cg/HLSL语言嵌入到Shader中,然后使用#pragma vertex vert和#pragma fragment frag指令分别定义了顶点着色器和片元着色器。

在接下来的代码中,我们定义了两个结构体:appdata和v2f。appdata结构体保存了输入顶点的位置信息,而v2f结构体保存了传递给片元着色器的位置信息。

在顶点着色器vert函数中,我们将输入位置转换为剪裁空间中的位置,并将其赋值给v2。

赛博朋克风格

之后我再让其帮忙编写一个简单的赛博朋克风格的shaderlab代码着色器:
在这里插入图片描述

其简单说明了该着色器:

这个shader使用了标准的表面着色模型,在表面着色函数中对材质的属性进行了设置和计算。其中,Albedo属性使用了一个2D纹理和颜色值来确定表面的基础色,Metallic属性用于控制金属感,Smoothness属性用于控制光滑度,Emission属性用于添加发光效果。此外,还添加了一些伪装置光,使得物体表面呈现出类似赛博朋克风格的效果。

给出的代码也是没法直接进行使用的,报错如下:

invalid subscript ‘worldNormal’

在输入的结构体内添加了参数:

struct Input {
    
    
   float2 uv_MainTex;
   float3 worldNormal : TEXCOORD0;
};

去除了报错,其效果如下:
在这里插入图片描述

感觉效果还行的,不过具体是否是赛博朋克风格我也无法界定了,不过Albedo属性和Emission属性其实都是没有的。

总结

从上面的测试能看出ChatGPT的强大毋庸置疑,当然它给出的代码也不是完美无瑕的(从上面的测试可以看出来都是有错误的),目前来说它直接平替一个程序员应该说还不现实的,因为它写的代码还是需要程序员来走查代码,并进行修改和优化。
当然它还在不断优化,不说干掉所有的程序员,干掉那些很基础的工作内容是完全可能的,到时候可能就涉及到程序猿的大幅缩减了(仅个人看法),虽然“马斯克们”呼吁暂停,OpenAI创始人:AI需要政府与社会的共同监管,但是等发展和监管体系完善后AI的发展仍然会向前发展。不过我们现在在使用这个ChatGPT完全是被别人掐这脖子走,不给我们用就不给,目前ChatGPT突遭大面积封号,根据传闻,受影响的账户已经达到了数百万,亚洲是重灾区,其中不少都是国内的账号。所以我们要正常使用可能还有很长的路走。
当然面临AI的对我们搬砖人的冲击,我们应该怎样面对呢?
说说个人的拙见吧,与其恐惧它,排斥和抵触AI,不如尝试驾驭它,让其成为我们的工具,让其臣服于我们,而不是敌视它、被它替换。

猜你喜欢

转载自blog.csdn.net/qq_33789001/article/details/129935077