首页 > 其他分享 >几何着色器 Geometry Shader

几何着色器 Geometry Shader

时间:2024-07-10 19:30:48浏览次数:17  
标签:输出 Geometry uv pos Shader g2f 顶点 着色器

参考: 

【Unity Shader入门】4、几何着色器Geometry Shaders之结构解析_shader编译目标级别-CSDN博客

Geometry Shader(Unity几何着色器)_unity geometry shader-CSDN博客

Unity几何着色器详解 - 知乎 (zhihu.com)

 

/* 
    [maxvertexcount(N)]:用来指定几何着色器单次调用所输出的顶点数量最大值。
    其中,N是几何着色器单次调用所输出的顶点数量最大值。几何着色器每次输出的顶点个数都可能不同,但是这个数量不能超过之前定义的最大值。
    出于对性能方面的考虑,我们应当令maxvertexcount的值尽可能小。线管资料显示,GS着色器每次输出的标量数量在1-20时,它将发挥出最佳的性能;而当27-40时,它的性能将下降到峰值性能的50%。
    每次调用几何着色器所输出的标量个数为:maxvertexcount与输出顶点类型结构体中标量个数的乘积。
    例如,如果顶点结构体定义了float3 pos : POSITION与float2 tex : COORD0,即顶点元素中含有5个标量。
    假设此时将maxvertexcount设置为4,则几何着色器每次输出20个标量,以峰值性能执行。
*/
[maxvertexcount(3)] 
/*
    *  Input: PrimitiveType InputVertexType InputName[NumElements]
        PrimitiveType:表示输入的图元类型,我们一般都是处理基于3角形的3D模型,一般选三角形,可以有以下几种:
            point:输入图元为点,顶点数量1
            line:输入图元为线,顶点数量2
            triangle:输入图元为三角形,顶点数量3
            lineadj:输入图元为带有邻接信息的直线,由4个顶点构成3条线,顶点数量4
            triangleadj:输入图元为带有邻接信息的三角形,由6个顶点构成,顶点数量4
        InputVertexType:表示输入的结构体,例如v2g,在代码里定义
        NumElements:表示输入的顶点数据元素数量,根据上面的输入图元类型填对应的顶点数量
        
    *  Inout: StreamOutputObjectVertexType<OutputVertexType> OutputName
        StreamOutputObjectVertexType:表示输出的顶点类型,可以有:
            PointStream:输出图元为点,即最终模型只显示顶点
            LineStream:输出图元为线,即最终模型只显示线框
            TriangleStream:输出图元为三角形,普通的模型面显示方式
        OutputVertexType:表示输出的顶点类型,例如g2f,在代码里定义
    */
void geom(triangle v2g p[3], inout TriangleStream<g2f> tStream)
{
    for (int i = 0; i < 3; i++) 
    {
        // 定义一个g2f输出结构体,并将参数都初始化为0
        g2f o = (g2f)0;
        o.pos = p[i].pos;
        o.normal = p[i].normal;
        o.uv  = p[i].uv ;
        // 将每个顶点添加到TriangleStream流里
        tStream.Append(o);
    }
    // 如果是添加三角面,每输出点足够对应相应的图元后,都要RestartStrip()一下再继续构成下一图元,其他两种输出模式不需要这步骤
    tStream.RestartStrip();
}

 

// 一个例子,在每个三角形的每个顶点周围均匀分布生成10个裂变顶点,并且随时间变化在原位置上移动
[maxvertexcount(30)]
void geom(triangle v2g p[3], inout PointStream<g2f> pStream)
{
    float time = _Time.y; // 获取当前时间

    // 对每个三角形的每个顶点进行裂变
    for (int i = 0; i < 3; ++i)
    {
        for (int j = 0; j < 10; ++j)
        {
            g2f o;
            // 在三角形顶点周围均匀分布生成新顶点
            float phi = 2 * 3.14159265359 * float(j) / 10.0f;
            float r = 0.1f; // 裂变顶点的半径,可以根据需求调整

            // 计算新顶点位置,同时考虑时间变化
            float3 offset = float3(cos(phi), sin(phi), 0) * r;
            float movement = sin(time + phi * 2) * 0.02f; // 时间因子,用于随时间变化
            o.pos = p[i].pos + float4(offset * (1.0 + movement), 0);

            // 使用原始顶点的法线和纹理坐标
            o.normal = p[i].normal;
            o.uv = p[i].uv;

            // 添加到输出流
            pStream.Append(o);
        }
    }
}

 

 

Shader "Custom/GeometryShader"
{
    Properties
    {
        _MainTex("MainTex", 2D) = "white" {}
        _Color ("Main Color", Color) = (1,1,1,1)
    }

    SubShader
    {
        Pass
        {
            Tags{ "RenderType" = "Opaque" }
            LOD 200

            CGPROGRAM
            #pragma vertex vert
            // 这里指明要使用一个名为geom的几何着色器
            #pragma geometry geom
            #pragma fragment frag
            #include "UnityCG.cginc"

            uniform sampler2D _MainTex;
            fixed4 _Color;

            // 定义输入结构体,用于顶点着色器输出,几何着色器输入
            struct v2g
            {
                float4  pos     : POSITION;
                float3  normal  : NORMAL;
                float2  uv      : TEXCOORD0;
            };

            // 定义输出结构体,用于几何着色器输出,片段着色器输入
            struct g2f
            {
                float4  pos     : POSITION;
                float3  normal  : NORMAL;
                float2  uv      : TEXCOORD0;
            };

            // 顶点着色器
            v2g vert(appdata_base v)
            {
                v2g o = (v2g)0;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv  = v.texcoord;
                return o;
            }

            // 几何着色器
            // 将模型输出为点
            [maxvertexcount(3)] 
            void geom(triangle v2g p[3], inout PointStream<g2f> pStream)
            {
                for (int i = 0; i < 3; i++) 
                {
                    g2f o = (g2f)0;
                    o.pos = p[i].pos;
                    o.normal = p[i].normal;
                    o.uv  = p[i].uv ;
                    //将每个顶点添加到PointStream流里
                    pStream.Append(o);
                }
            }

            // [maxvertexcount(3)] 
            // 将模型输出为线框
            // void geom(triangle v2g p[3], inout LineStream<g2f> lStream)
            // {
            //     for (int i = 0; i < 3; i++) 
            //     {
            //         g2f o = (g2f)0;
            //         o.pos = p[i].pos;
            //         o.normal = p[i].normal;
            //         o.uv  = p[i].uv ;
            //         //将每个顶点添加到LineStream流里
            //         lStream.Append(o);
            //     }
            // }

            // [maxvertexcount(3)] 
            // 将模型输出为三角面
            // void geom(triangle v2g p[3], inout TriangleStream<g2f> tStream)
            // {
            //     for (int i = 0; i < 3; i++) 
            //     {
            //         g2f o = (g2f)0;
            //         o.pos = p[i].pos;
            //         o.normal = p[i].normal;
            //         o.uv  = p[i].uv ;
            //         //将每个顶点添加到TriangleStream流里
            //         tStream.Append(o);
            //     }
            //     //添加三角面
            //     //每输出点足够对应相应的图元后
            //     //都要RestartStrip()一下再继续构成下一图元
            //     tStream.RestartStrip();
            // }

            // 片段着色器
            fixed4 frag(g2f i) : COLOR
            {
                return tex2D(_MainTex, i.uv) * _Color;
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

 

标签:输出,Geometry,uv,pos,Shader,g2f,顶点,着色器
From: https://www.cnblogs.com/jeason1997/p/18294851

相关文章

  • Body Clipping Geometry
    BodyClippingGeometry实体剪裁几何图形是通过使用仅涉及半空间实体的差分运算的构造实体几何模型来表示产品的三维形状。 应使用保持该几何表示的IfcShapeResentation的以下属性值:IfcShapeRepresentation.RepresentationIdentifier ='Body'IfcShapeRepresentation.Repr......
  • Unity Shader技巧:实现带投影机效果,有效避免边缘拉伸问题
    这个是原始的projector投影组件,边缘会有拉伸经过修改shader后边缘就没有拉伸了(实现代码在文章最后)这个着色器通过检查每个像素的UV坐标是否在定义的边界内,来确定是否应用黑色边框。如果UV坐标处于边缘区域,那么像素颜色会被强制设为黑色,从而在投影图像周围形成一个黑色......
  • 扩散几何(Diffusion Geometry)
    扩散几何(DiffusionGeometry)是一种用于分析和处理高维数据的几何方法。它利用数据的局部结构来推断和捕捉全局几何信息,通过定义和计算数据点之间的扩散距离或扩散度量,来揭示数据的内在几何结构和相关性。扩散几何的核心思想是基于扩散过程和随机游走理论,常用于降维、数据分类、聚......
  • Body SurfaceModel Geometry
    BodySurfaceModelGeometry实体曲面模型几何图形是通过曲面模型表示产品的三维形状。应使用保持该几何表示的IfcShapeResentation的以下属性值:IfcShapeRepresentation.RepresentationIdentifier ='Body'IfcShapeRepresentation.RepresentationType ='SurfaceModel'IfcSh......
  • CesiumJS【Basic】- #054 绘制渐变填充多边形(Entity方式)-使用shader
    文章目录绘制渐变填充多边形(Entity方式)-使用shader1目标2代码2.1main.ts绘制渐变填充多边形(Entity方式)-使用shader1目标使用Entity方式绘制绘制渐变填充多边形-使用shader2代码2.1main.tsimport*asCesiumfrom'cesium';constviewer......
  • Cesium 3DTiles customshader的使用-动态高度设置
    之前要编辑3DTiles 的shader来实现一些例如压平之类的操作 还需要更改源码Cesium新版本更新了3Dtiles的自定义着色器 可以直接定义两个着色器并往里面传uniform新版本添加3dtiles的方式发生了改变 原有的方式不能用了新版本必须通过fromurl函数进行异步添加即asyncfu......
  • 可计算离散整体几何结构的 MeshDGP使用——基于C#的geometry processing framework几
    目录引出MeshDGP项目下载和打开遇到的报错解决如何运行使用打开使用函数工具菜单等总结其他CAD/CAE/CAM几何引擎-软件概述郝建兵CAD/CAE/CAMCADCAECAM几何模型内核ACIS两个老大之一OpenCascadeParasolid两个老大之一Autodesk的内核各种CAD自定义信号和槽1.自定......
  • mach(zig):从webGPU api了解渲染通道&shader
    学opengl3.3教程,你将了解通用图形渲染api。学vulkan,你将用1000+行代码画一个三角形。学webGPUapi,你将获得跨平台的图形api设计规范。reddit上有人说:OpenGL只是与3D硬件连接的几个应用程序接口之一。所有这些应用程序接口的基本概念都是一样的,即使应用程序本身的方式略有不......
  • WPF Path GeometryCombineMode Union, Exclude,Intersect,Xor
    union<Windowx:Class="WpfApp172.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.mi......
  • WPF StreamGeometry
    usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Net.Http;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Windows;usingSystem.Windows.Controls;usingSystem.Windows.Data;usingSystem.Windows.Documents;usin......