Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unity3d 如何将曲面着色器转换为Unity中的顶点/片段代码?_Unity3d_Shader_Fragment Shader_Vertex Shader - Fatal编程技术网

Unity3d 如何将曲面着色器转换为Unity中的顶点/片段代码?

Unity3d 如何将曲面着色器转换为Unity中的顶点/片段代码?,unity3d,shader,fragment-shader,vertex-shader,Unity3d,Shader,Fragment Shader,Vertex Shader,我想知道如何将此曲面着色器代码转换为顶点/片段杂注: Shader "Custom/Diamond Opaque Test" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _SpecColor ("Specular Color", Color) = (0.5,0.5,0.5,1) _Shininess ("Shininess", Range (0.01, 1)) = 0.07

我想知道如何将此曲面着色器代码转换为顶点/片段杂注:

Shader "Custom/Diamond Opaque Test" {
    Properties {
        _Color ("Main Color", Color) = (1,1,1,1)
        _SpecColor ("Specular Color", Color) = (0.5,0.5,0.5,1)
        _Shininess ("Shininess", Range (0.01, 1)) = 0.078125
        _RimPower ("Rim Power", Range(0,8.0)) = 3.0
        _ReflectColor ("Reflection Color", Color) = (1,1,1,0.5)
        [NoScaleOffset] _Cube ("Cubemap", CUBE) = "" {}
    }

    SubShader {

        CGPROGRAM
        #pragma surface surf BlinnPhong

        struct Input {
            float3 worldRefl;
            float3 viewDir;
        };

        samplerCUBE _Cube;
        fixed4 _Color;
        fixed4 _ReflectColor;
        half _Shininess;
        half _RimPower;

        void surf (Input IN, inout SurfaceOutput o) {
            o.Albedo = _Color.rgb;
            o.Gloss = _Color.a;
            o.Specular = _Shininess;
            half rim = saturate(dot (normalize(IN.viewDir), o.Normal));
            o.Emission = texCUBE (_Cube, IN.worldRefl).rgb * _ReflectColor.rgb * pow(rim,_RimPower);;
        }
        ENDCG
    } 
    FallBack "Mobile/Diffuse"
}
上面的着色器代码是下图左侧的红色宝石:

我的目标是看起来像右边的宝石。在此过程中,我面临着一些挑战。左边的宝石是不透明的,可以接受阴影。右边的宝石正面透明,背面透明。但是,这不接受阴影。我必须在let Blinnfong上制作宝石,这样它才能投射和接收阴影

是否可以为正面和背面透明度创建不同的控件?还有一种透明对象接受阴影的方法吗?我想给宝石添加轮廓,这样它就可以被看得更远。有没有办法在同一关卡中添加轮廓,还是必须有自己的单独关卡?此外,如何使接收到的阴影变暗?所有这些要求会对GPU征税吗?该游戏适用于移动平台

我是CG编程的初学者。我的第一步是找出将曲面编程转换为顶点/片段的方法。任何例子都将不胜感激


我确实在资产商店购买了一些宝石资产,但其中一些可以投射阴影,但不能接收或根本不能投射或接收。有什么好处?右侧的gem着色器来自从资产存储购买的资产之一。我不想在未经他们允许的情况下在此网站上共享他们的着色器脚本。

这实际上是一个相当复杂的过程,不过我建议您从他们的网站下载unity着色器源代码开始。大多数实际着色是在UNITYSTANDBRDF.cginc、UNITYPBSLIGHT.cginc和UNITYSTANDCORE.cginc中完成的。如果你用谷歌搜索这些文件,你也可以在github上找到它们

基本上,前向添加着色器的基本结构如下所示:

Shader "MyForwardAddShader"
{
    Properties
    {
        _MainTex("Some texture", 2D) = "white"{}
    }

    SubShader
    {
        Tags {"RenderType"="Geometry" "Queue" = "Geometry"}

        Pass 
        {
            // Forward Base pass - this applies main directional light and ambient
            Name "FORWARD"
            Tags { "LightMode" = "ForwardBase" }

            CGPROGRAM
            #pragma target 3.5

            #pragma multi_compile_fwdbase
            #pragma multi_compile_fog
            #pragma multi_compile_instancing

            #pragma vertex vert
            #pragma fragment frag

            // I Like to keep these in separate include files
            #include "MyForwardBase.cginc"

            ENDCG
        }

        Pass
        {
            // Forward Add pass - this is added once per extra light source

            Name "FORWARD_DELTA"
            Tags { "LightMode" = "ForwardAdd" }
            Blend SrcAlpha One
            Fog { Color (0,0,0,0) } // in additive pass fog should be black
            ZWrite Off
            ZTest LEqual

            CGPROGRAM
            #pragma target 3.5

            #pragma multi_compile_fwdadd_fullshadows
            #pragma multi_compile_fog

            #pragma vertex vert
            #pragma fragment frag

            #include "MyForwardAdd.cginc"

            ENDCG
        }
    }
}
UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos.xyz); // Here, worldPos is stored in the vertex output struct and calculated per vertex
half3 lightColor = _LightColor0.rgb * atten;
请注意,您还需要阴影投射器过程来投射阴影(您可以只复制标准着色器源代码中使用的过程),如果要使用烘焙照明,还需要元过程

像“MyForwardBase.cginc”这样的文件应该包括顶点输入和输出结构的定义,以及过程的顶点和片段函数。使用此设置,还需要在其中定义统一(属性变量)。灯光计算可能需要的一些变量:

// Calculate this in the vertex shader and normalize per fragment
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
float3 viewDir = _WorldSpaceCameraPos.xyz - o.worldPos;

// In the ForwardBase pass, _WorldSPaceLightPos0.xyz stores the direction of the main directional light, instead of position. 
// Use this in the vertex function:
half3 mainLightColor = _LightColor0.rgb;
half3 mainLightDir = _WorldSpaceLightPos0.xyz;
对于ForwardBase过程,您需要包括“AutoLight.cginc”,并在vertex函数中使用此宏:

COMPUTE_LIGHT_COORDS(o);
这反过来要求您在VertexOutput结构中具有此宏:

UNITY_LIGHTING_COORDS(6,7) // 6, 7 can be any texture interpolator IDs, they will translate to TEXCOORD6 and TEXCOORD7 in this case
ForwardAdd灯光衰减的工作原理如下:

Shader "MyForwardAddShader"
{
    Properties
    {
        _MainTex("Some texture", 2D) = "white"{}
    }

    SubShader
    {
        Tags {"RenderType"="Geometry" "Queue" = "Geometry"}

        Pass 
        {
            // Forward Base pass - this applies main directional light and ambient
            Name "FORWARD"
            Tags { "LightMode" = "ForwardBase" }

            CGPROGRAM
            #pragma target 3.5

            #pragma multi_compile_fwdbase
            #pragma multi_compile_fog
            #pragma multi_compile_instancing

            #pragma vertex vert
            #pragma fragment frag

            // I Like to keep these in separate include files
            #include "MyForwardBase.cginc"

            ENDCG
        }

        Pass
        {
            // Forward Add pass - this is added once per extra light source

            Name "FORWARD_DELTA"
            Tags { "LightMode" = "ForwardAdd" }
            Blend SrcAlpha One
            Fog { Color (0,0,0,0) } // in additive pass fog should be black
            ZWrite Off
            ZTest LEqual

            CGPROGRAM
            #pragma target 3.5

            #pragma multi_compile_fwdadd_fullshadows
            #pragma multi_compile_fog

            #pragma vertex vert
            #pragma fragment frag

            #include "MyForwardAdd.cginc"

            ENDCG
        }
    }
}
UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos.xyz); // Here, worldPos is stored in the vertex output struct and calculated per vertex
half3 lightColor = _LightColor0.rgb * atten;
还有一些宏用于确定像素是否在阴影中,您可以在AutoLight.cginc中找到它们。在ForwardAdd过程中,灯光方向按顶点计算,如下所示:

o.lightDir      = _WorldSpaceLightPos0.xyz - o.worldPos.xyz * _WorldSpaceLightPos0.w;
就我个人而言,我喜欢为每个特征创建小的CGInclude,例如反射、折射、三平面贴图等,并且只要我需要它们,就可以包含它们。我还倾向于在自己的include文件中保留一个名为“Lighting”的单独函数,因为照明计算在通道之间共享。此函数将所有变量(如lightDir、viewDir、反照率、粗糙度等)作为参数,并返回片段的着色颜色


正如我所说,这是一个相当复杂的过程,这只是一个入门。实现照明功能本身就是一个故事,尽管查看UnityStandardBRDF.cginc可以有所帮助。我建议您从基本的blinn phong模型开始进行调试,并从中改进

我很困惑你的问题中有很多问题?1-曲面到碎片2-双面透明为什么要将此着色器转换为碎片着色器?最好使用曲面着色器,因为它易于编辑。@SeyedMortezaKamali 1)。我所购买的资产中有一些我喜欢的功能,但它是由vertex/fragment编写的。我想把代码的一些部分添加到我的代码中。我想将曲面转换为顶点/碎片,以便了解如何操作它。2). 我想通过控制正面和背面的alpha来控制宝石中的雾量。为整个宝石设置alpha使其看起来更像玻璃或塑料。例如,我想将白色宝石的背面alpha设置为更接近纯色,而不是更暗的颜色。我希望这是有意义的。编写片段着色器并不容易,但如果您喜欢这样做,您应该学习片段着色器,但无论如何,每个灯光建模都有片段着色器