gpt4 book ai didi

unity3d - 如何在 Unity 中将表面着色器转换为顶点/片段代码?

转载 作者:行者123 更新时间:2023-12-03 21:51:55 25 4
gpt4 key购买 nike

我想知道如何将这个表面着色器代码转换为顶点/片段编译指示:

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"
}

上面的着色器代码就是下图左边的红色 gem :

no shadow

我的目标是看起来与右边的 gem 相似。一路上我遇到了一些挑战。左边的 gem 是不透明的,可以接受阴影。右边的 gem 具有正面透明度,但背面没有。然而,这不接受阴影。我必须在 let BlinnPhong 上制作 gem ,这样它才能转换和接收阴影。

shadow

是否可以为正面和背面透明度创建不同的控件?还有透明物体接受阴影的方法吗?我想为 gem 添加轮廓,以便可以在更远的地方看到它。有没有办法在同一个通行证中添加轮廓,还是必须有自己的单独通行证?另外,如何使接收到的阴影变暗?所有这些要求都会对 GPU 造成极大的负担吗?该游戏适用于移动平台。

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

我确实在 Assets 商店购买了一些 gem Assets ,但其中一些可以转换阴影但无法接收或根本无法转换或接收。是什么赋予了?右侧的 gem 着色器来自从 Assets 商店购买的 Assets 之一。未经他们的许可,我不想在此站点上共享他们的着色器脚本。

最佳答案

这实际上是一个相当复杂的过程,但我建议您先从他们的网站下载统一着色器源代码。大多数实际着色是在 UnityStandardBRDF.cginc、UnityPBSLighting.cginc 和 UnityStandardCore.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
}
}
}

请注意,您还需要一个 shadowcaster pass 才能转换阴影(您可以只复制标准着色器源代码中使用的 pass),如果您想使用烘焙光照,还需要一个 Meta pass。

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

// 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 channel ,您需要包含“AutoLight.cginc”并在顶点函数中使用此宏:

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 光衰减是这样工作的:

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;

就个人而言,我喜欢为每个功能创建小型 CGIncludes,例如反射、折射、三平面贴图等,并在需要时将它们包含在内。我还倾向于在其自己的包含文件中保留一个名为“Lighting”的单独函数,因为照明计算在各个 channel 之间共享。此函数将所有变量(如 lightDir、viewDir、反照率、粗糙度等)作为参数并返回片段的阴影颜色。

正如我所说,这是一个相当复杂的过程,而这只是入门。实现照明功能是一个独立的故事,尽管查看 UnityStandardBRDF.cginc 可以帮助解决这个问题。我建议您从用于调试的基本 blinn-phong 模型开始,并以此为基础进行改进。

关于unity3d - 如何在 Unity 中将表面着色器转换为顶点/片段代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50224617/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com