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
 

走马观花

最近的回复

  • 这个错误没多大影响,qt模块可以在QT setting里进行勾选

    read more
  • 如果对操作不是很熟悉或者是操作不便的话,也可以在Windows的命令行执行NDK的安装。参数是一样的:
    Windows命令行安装NDK

    read more
  • 忘记补充图片了。这里需要点击更新安装才行。😆
    点击更新安装

    read more
  • 问:
    如何在Qt Creator安装NDK呢?
    除了那个🔽 按钮外,还有别的办法吗?
    答:
    Qt Creaator 4.11中更加整合了Android SDK Manager。其实大家都可以不运行默认的Android SDK Manager,直接在Qt Creator中选项->设备->Android,就可以进行操作了。

    通过````高级选项……,启动一些Android SDK Manager,只需要带上参数ndk-bundle```。原来没有NDK的你,也可以通过Android SDK Manager安装了。很简单吧。
    Android SDK Manager安装NDK

    read more

关注我们

微博
QQ群