USD对程序纹理支持的研究


  • 网站研运

    大家好,又有一段时间没有发布文章了。这次还是介绍最近研究USD的一些内容。主要是USD针对程序纹理的支持。如果有时间的话,还会给大家分享更多有关USD的内容的。

    首先皮克斯工作室推出的USD文档以及一些示例代码并没有介绍程序化纹理的内容。但是有一些爱好者将自己输出的USD文档分享出来,其中包括了卡通着色的内容。下面就是一个简单的USD内容,它可以显示卡通着色(本例在USD 19.07中测试):

    cellshaded.usd

    #usda 1.0
    
    
    def Scope "Materials" {
    
        def Material "CelMaterial" { 
    
            rel displayLook:bxdf = </Materials/CelShader>
    
        }
    
        def Shader "CelShader" {
    
            uniform asset info:filename = @celshader.glslfx@
            
        }
    
    }
    
    def Scope "Geom" {
    
        def Mesh "Subdiv" {
    
            rel material:binding = </Materials/CelMaterial>
    
            float3[] extent = [(-1.21273, -1.21273, -1.21273), (1.21273, 1.21273, 1.21273)]
    
            color3f[] primvars:displayColor = [(0.078431372549019607, 0.51372549019607838, 0.80784313725490198)]
    
            int[] faceVertexCounts = [4, 4, 4, 4, 4, 4]
    
            int[] faceVertexIndices = [0, 1, 3, 2, 2, 3, 5, 4, 4, 5, 7, 6, 6, 7, 1, 0, 1, 7, 5, 3, 6, 0, 2, 4]
    
            point3f[] points = [(-1.21273, -1.21273, -1.21273), (1.21273, -1.21273, -1.21273), (-1.21273, -1.21273, 1.21273), (1.21273, -1.21273, 1.21273), (-1.21273, 1.21273, 1.21273), (1.21273, 1.21273, 1.21273), (-1.21273, 1.21273, -1.21273), (1.21273, 1.21273, -1.21273)]
    
            
        }
    }
    

    cellshader.glslfx

    -- glslfx version 0.1
    
    -- configuration
    {
        "techniques" : {
            "default" : {
                "surfaceShader" : {
                    "source": [ "Cel.SurfaceShader" ]
                }
            }
        }
    }
    
    -- glsl Cel.SurfaceShader
    
    vec4 
    surfaceShader(vec4 Peye, vec3 Neye, vec4 color, vec4 patchCoord)
    {
        float c = 0.0;
    
        // Hard-code the light direction for now
        vec3 l = vec3(0.0, 0.0, 1.0);
        vec3 n = normalize(Neye);
    
        c = dot(l, n);
    
        vec3 cl;
    
        if (c > 0.99)
            cl = vec3(1.0, 1.0, 1.0);
        else if (c > 0.9)
            cl = color.xyz;
        else if (c > 0.5)
            cl = color.xyz*0.75;
        else if (c > 0.25)
            cl = color.xyz*0.50;
        else 
            cl = color.xyz*0.25;
    
        return vec4(cl, color.w);
    }
    

    效果如下(右键另存图片,使用7z文件文档管理器可以解压获得源代码)
    1_7z.png

    我在这个例子的基础上加以发挥,想出了一个办法可以支持在纹理立方体上贴棋盘格图。整个着色器是使用GLSL做的。其中棋盘格的GLSL代码是我从“萌梦动作编辑器”中的时间轴例子借鉴的。

    7_29_1.usda

    #usda 1.0
    (
        defaultPrim = "cube"
        endTimeCode = 1
        startTimeCode = 1
        upAxis = "Y"
    )
    
    def Mesh "cube"
    {
        uniform bool doubleSided = 1
        float3[] extent = [(-0.5, -0.5, -0.5), (0.5, 0.5, 0.5)]
        int[] faceVertexCounts = [4, 4, 4, 4, 4, 4]
        int[] faceVertexIndices = [0, 1, 3, 2, 2, 3, 5, 4, 4, 5, 7, 6, 6, 7, 1, 0, 1, 7, 5, 3, 6, 0, 2, 4]
        normal3f[] normals = [(0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 1, 0), (0, 1, 0), (0, 1, 0), (0, 1, 0), (0, 0, -1), (0, 0, -1), (0, 0, -1), (0, 0, -1), (0, -1, 0), (0, -1, 0), (0, -1, 0), (0, -1, 0), (1, 0, 0), (1, 0, 0), (1, 0, 0), (1, 0, 0), (-1, 0, 0), (-1, 0, 0), (-1, 0, 0), (-1, 0, 0)] (
            interpolation = "faceVarying"
        )
        point3f[] points = [(-0.5, -0.5, 0.5), (0.5, -0.5, 0.5), (-0.5, 0.5, 0.5), (0.5, 0.5, 0.5), (-0.5, 0.5, -0.5), (0.5, 0.5, -0.5), (-0.5, -0.5, -0.5), (0.5, -0.5, -0.5)]
        float2[] primvars:st = [(0.375, 0), (0.625, 0), (0.625, 0.25), (0.375, 0.25), (0.625, 0.5), (0.375, 0.5), (0.625, 0.75), (0.375, 0.75), (0.625, 1), (0.375, 1), (0.875, 0), (0.875, 0.25), (0.125, 0), (0.125, 0.25)] (
            interpolation = "faceVarying"
        )
        int[] primvars:st:indices = [0, 1, 2, 3, 3, 2, 4, 5, 5, 4, 6, 7, 7, 6, 8, 9, 1, 10, 11, 2, 12, 0, 3, 13]
        uniform token subdivisionScheme = "none"
    
        rel material:binding = </cube/material>
        
        def Material "material"
        {
            token outputs:surface.connect = </cube/material/outputShader.outputs:surface>
    
            def Shader "PBRShader"
            {
                uniform token info:id = "UsdPreviewSurface"
                color3f inputs:diffuseColor = ( 1, 0, 0 )
                float inputs:metallic = 0
                float inputs:roughness = 0.4
                float inputs:opacity = 1
                //float inputs:ior = 0.1
                float inputs:clearcoat = 0.6
                float inputs:clearcoatRoughness = 1
                color4f outputs:color
            }
    
            def Shader "outputShader"
            {
                uniform asset info:filename = @./7_29_1.glslfx@
                color4f baseColor.connect = </cube/material/texture.outputs:color>
                color4f outputs:color
            }
    
            def Shader "texCoordReader"
            {
                uniform token info:id = "HwPrimvar_1"
                uniform token info:varname = "st"
                float2 outputs:result
            }
    
            def Shader "texture" 
            {
                uniform token info:id = "HwUvTexture_1"
                float2 uv.connect = </cube/material/texCoordReader.outputs:result>
                uniform asset info:filename = @./7_29_1.jpg@
                color4f outputs:color
            }
        }
    }
    

    7_29_1.glslfx

    -- glslfx version 0.1
    
    #import $TOOLS/glf/shaders/simpleLighting.glslfx
    
    -- configuration
    {
        "techniques": {
            "default": {
                "surfaceShader": {
                    "source": [ "test.Surface" ]
                }
            }
        }
    }
    
    -- glsl test.Surface
    
    float Mod( int x, int y )
    {
        return float( x ) - float( x / y ) * float( y );
    }
    vec4 checkerBoard( float opacity )
    {
        float gridWidth = 4.0;
        float gridHeight = 4.0;
        float width = 160.0;
        float height = 160.0;
        vec2 uv = HdGet_st().xy;
        float mod2X = Mod( int( width * uv.x / gridWidth ), 2 );
        float mod2Y = Mod( int( height * uv.y / gridHeight + 0.5 ), 2 );
        vec4 barColor = vec4( 1.0 );
        if ( mod2X == 1.0 && mod2Y == 0.0 ||
             mod2X == 0.0 && mod2Y == 1.0 )
        {
            barColor = vec4( 0.0, 0.0, 0.0, opacity );
        }
        else
        {
            barColor = vec4( 1.0, 1.0, 1.0, opacity );
        }
        return barColor;
    }
    
    vec4 surfaceShader( vec4 Peye, vec3 Neye, vec4 color, vec4 patchCoord )
    {
        vec4 result = checkerBoard( 0.3 );
    #if defined( HD_HAS_baseColor )
        result += HdGet_baseColor( );
    #endif
    #if defined( HD_HAS_selColor )
        result *= HdGet_selColor( );
    #endif
        return result;
    }
    

    2_7z.png
    (右键另存图片,使用7z文件文档管理器可以解压获得源代码)

    要说GLSLFX和GLSL的不同,我这边研究了一下,应该是GLSLFX是皮克斯工作室的USD项目在大实现Hydra的过程中自己研发了一个处理着色网络的格式。它对GLSL做了浅层的封装,并且定义了自己的渲染流程(渲染管线)。我们翻阅USD的源码,可以找到文件名带有.glslfx后缀的文件,通常包含了vertexShaderdisplacementShadergeometryShadersurfaceShaderfragmentShadercomputeShader等等。最终还是输出渲染API能够辨认的GLSL代码的。我们可以通过设置HDST_DUMP_SHADER_SOURCEFILE环境变量将生成后的着色器输出到文件中以便排错(在USD 19.07之前没有此宏)。


Log in to reply
 

最近的回复

  • E

    是不是好久都没有人了,站主找到工作了,还是说划水了

    read more
  • 请问一下如果原Qt桌面软件支持拖拽外部文件进去(比如把在用资源管理器里的一张图片拖拽到软件界面上就会显示这张图片),转成Webassembly之后这种拖拽操作还是否有效?劳烦大佬帮我试试看,可以的话我就学QML了

    read more
  • H
    Toou 2D 拿来即用,为简单而生。

    简称T2D,是一款采用自身模块规范编写的轻量级UI框架,遵循Qt书写与组织形式门槛极低无需深入学习简单易用可拿来即用,丰富的控件模块适合界面的快速开发,让程序人员拥有更多的精力来实现业务逻辑与算法。

    统一交互规范,丰富的Ui控件几十种常用控件放弃了Qt Controls 及 Controls 2 来提高性能。

    完善的主题系统,业务逻辑与界面主题设计分离,可通过简单修改变量自定义主题皮肤。灵活的多主题皮肤绑定机制、在不需要重启App即实现一键换肤

    ini皮肤配置规则与每一个控件融合。可在应用内配置也可在应用外动态扩展配置。

    框架自动化安装支持动态库、静态库多模式编译。使用方便更安全更自由。

    提供丰富Demo、全面的帮助文档,Api查阅快速方便。项目必备开源框架!

    已经集成最新版 Font Awesome 4.7

    开源地址:https://github.com/ShowFL/Toou-2D

    read more
  • 刚刚毕业,工作用QT开发,以后有问题多多请教各位前辈😬 抱拳了。

    read more

关注我们

微博
QQ群