赞
踩
gpu着色顺序是顶点着色-曲面细分着色-几何着色-片段着色
为了实现法线可视化,我们需要在顶点着色器传递给几何着色器世界坐标以及世界法线(如果用object空间可能会导致法线变形)
在几何着色器中,[maxvertexcount(6)]声明了传进去的三角形图元的三个顶点会生成多少顶点,每个顶点生成法线的两段的点,所以是6个,triangle geomdata data[3]中triangle声明了你所操作的图元类型,LineStream声明了我们创建的图元类型,有PointStream,LineStream和TriangleStream三种。
Append方法添加顶点,每创建两个顶点后RestartStrip表示一个线段实例的创建完成开始下一个. GPU会在几何着色后进行插值运算,给线段起点设置0,末尾设置1能实现线段的颜色变化.
[maxvertexcount(6)]
void geom(triangle geomdata data[3],inout LineStream<v2fgeom>stream){
for(int i=0;i<3;++i){
v2fgeom v1,v2;
v1.vertex=TransformWorldToHClip(data[i].vertex);
v2.vertex=TransformWorldToHClip(data[i].vertex+_LineLength*normalize(data[i].normal));
v1.normal=data[i].normal;
v2.normal=data[i].normal;
v1.d=0;
v2.d=1;
stream.Append(v1);
stream.Append(v2);
stream.RestartStrip();
}
}
第一个Pass进行简单的直接光+间接光的漫反射着色,第二个Pass法线可视化.
效果
完整着色器
Shader "Custom/GeometryShader" { Properties { [Header(Main)] _Color("Color",Color)=(1,1,1,1) [Space] [Header(Line)] _LineColorLerp("Line Color Lerp",Color)=(0,1,0,1) _LineColor("Line Color",Color)=(0,0,1,1) _LineLength("Line Length",Range(0.01,2))=0.5 } SubShader { Tags { "RenderType"="Opaque" } LOD 100 HLSLINCLUDE #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" struct appdata { float3 vertex : POSITION; float3 normal:NORMAL; }; struct geomdata{ float3 vertex : INTERNALGEOPOS; float3 normal:NORMAL; }; struct v2f { float3 normal:TEXCOORD0; float4 vertex : SV_POSITION; }; struct v2fgeom { float3 normal:TEXCOORD0; float4 vertex : SV_POSITION; float d:TEXCOORD1; }; half4 _Color; half4 _LineColor; half4 _LineColorLerp; float _LineLength; geomdata vertgeom (appdata v) { geomdata o; o.vertex = TransformObjectToWorld(v.vertex); o.normal=TransformObjectToWorldNormal(v.normal); return o; } [maxvertexcount(6)] void geom(triangle geomdata data[3],inout LineStream<v2fgeom>stream){ for(int i=0;i<3;++i){ v2fgeom v1,v2; v1.vertex=TransformWorldToHClip(data[i].vertex); v2.vertex=TransformWorldToHClip(data[i].vertex+_LineLength*normalize(data[i].normal)); v1.normal=data[i].normal; v2.normal=data[i].normal; v1.d=0; v2.d=1; stream.Append(v1); stream.Append(v2); stream.RestartStrip(); } } v2f vert(appdata v){ v2f o; o.vertex=TransformObjectToHClip(v.vertex); o.normal=TransformObjectToWorldNormal(v.normal); return o; } half4 fraggeom (v2fgeom i) : SV_Target { half3 col=lerp(_LineColorLerp.rgb,_LineColor.rgb,i.d); return half4(col,1.0); } half4 frag (v2f i):SV_Target{ Light light=GetMainLight(); float d=max(0,dot(light.direction,i.normal)); float3 SHColor=SampleSH(i.normal); half3 col=_Color*light.color*d+_Color*SHColor; return half4(col,1.0); } ENDHLSL Pass { Name "Geometry" Tags{"LightMode"="SRPDefaultUnlit"} HLSLPROGRAM #pragma vertex vertgeom #pragma geometry geom #pragma fragment fraggeom #pragma target 4.0 ENDHLSL } Pass { Cull Off Name "SimpleLit" Tags{"LightMode"="UniversalForward"} HLSLPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 4.0 ENDHLSL } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。