首页 > 其他分享 >Catlike Coding Custom SRP笔记 - 平行光

Catlike Coding Custom SRP笔记 - 平行光

时间:2025-01-21 23:43:04浏览次数:1  
标签:Catlike float Coding unity surface Custom UNITY brdf float3

原文链接:Directional Lights

 

效果图

 

CustomRenderPipelineAsset.cs

[CreateAssetMenu(menuName = "Rendering/Custom Render Pipeline")]
public class CustomRenderPipelineAsset : RenderPipelineAsset {
    
    public bool useDynamicBatching = true; //启用动态合批
    public bool useGPUInstancing = true; //GPU Instancing
    public bool useSRPBatcher = true; //SRP合批

    protected override RenderPipeline CreatePipeline () {
        return new CustomRenderPipeline(useDynamicBatching, useGPUInstancing, useSRPBatcher);
    }
    
}

 

CustomRenderPipeline.cs

public class CustomRenderPipeline : RenderPipeline {

    CameraRenderer renderer = new CameraRenderer();

    bool useDynamicBatching, useGPUInstancing;

    public CustomRenderPipeline (bool useDynamicBatching, bool useGPUInstancing, bool useSRPBatcher) {
        this.useDynamicBatching = useDynamicBatching;
        this.useGPUInstancing = useGPUInstancing;
        GraphicsSettings.useScriptableRenderPipelineBatching = useSRPBatcher;
        GraphicsSettings.lightsUseLinearIntensity = true;
    }

    protected override void Render(ScriptableRenderContext context, Camera[] cameras) {}

    protected override void Render(ScriptableRenderContext context, List<Camera> cameras) {
        for (int i = 0; i < cameras.Count; i++) {
            renderer.Render(context, cameras[i], useDynamicBatching, useGPUInstancing);
        }
    }
    
}

 

CameraRenderer.cs

public partial class CameraRenderer {

    const string bufferName = "Render Camera";

    static ShaderTagId unlitShaderTagId = new ShaderTagId("SRPDefaultUnlit");
    static ShaderTagId litShaderTagId = new ShaderTagId("CustomLit");

    CommandBuffer buffer = new CommandBuffer {
        name = bufferName
    };

    ScriptableRenderContext context;

    Camera camera;

    CullingResults cullingResults;

    Lighting lighting = new Lighting();

    public void Render(ScriptableRenderContext context, Camera camera,
        bool useDynamicBatching, bool useGPUInstancing
    ) {
        this.context = context;
        this.camera = camera;

#if UNITY_EDITOR
        PrepareBuffer();
        PrepareForSceneWindow();
#endif
        if (!Cull()) {
            return;
        }

        Setup();
        lighting.Setup(context, cullingResults);
        DrawVisibleGeometry(useDynamicBatching, useGPUInstancing);
#if UNITY_EDITOR
        DrawUnsupportedShaders();
        DrawGizmos();
#endif
        Submit();
    }

    bool Cull() {
        if (camera.TryGetCullingParameters(out ScriptableCullingParameters p)) {
            cullingResults = context.Cull(ref p);
            return true;
        }
        return false;
    }

    void Setup() {
        context.SetupCameraProperties(camera);
        CameraClearFlags flags = camera.clearFlags;
        buffer.ClearRenderTarget(
            flags <= CameraClearFlags.Depth,
            flags <= CameraClearFlags.Color,
            (flags == CameraClearFlags.Color) ? camera.backgroundColor.linear : Color.clear
        );
        buffer.BeginSample(SampleName);
        ExecuteBuffer();
    }

    void Submit() {
        buffer.EndSample(SampleName);
        ExecuteBuffer();
        context.Submit();
    }

    void ExecuteBuffer() {
        context.ExecuteCommandBuffer(buffer);
        buffer.Clear();
    }

    void DrawVisibleGeometry(bool useDynamicBatching, bool useGPUInstancing) {
        //先渲染不透明物体
        var sortingSettings = new SortingSettings(camera) {
            criteria = SortingCriteria.CommonOpaque
        };
        var drawingSettings = new DrawingSettings(
            unlitShaderTagId, sortingSettings
        ) {
            enableDynamicBatching = useDynamicBatching,
            enableInstancing = useGPUInstancing
        };
        drawingSettings.SetShaderPassName(1, litShaderTagId);

        var filteringSettings = new FilteringSettings(RenderQueueRange.opaque);
        context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);

        //再渲染天空盒
        context.DrawSkybox(camera);

        //再渲染半透明物体
        sortingSettings.criteria = SortingCriteria.CommonTransparent;
        drawingSettings.sortingSettings = sortingSettings;
        filteringSettings.renderQueueRange = RenderQueueRange.transparent;

        context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
    }
    
}

 

CameraRenderer.Edtor.cs

partial class CameraRenderer {

#if UNITY_EDITOR

    //内置渲染管线的tag标识
    static ShaderTagId[] legacyShaderTagIds = {
        new ShaderTagId("Always"),
        new ShaderTagId("ForwardBase"),
        new ShaderTagId("PrepassBase"),
        new ShaderTagId("Vertex"),
        new ShaderTagId("VertexLMRGBM"),
        new ShaderTagId("VertexLM")
    };

    static Material errorMaterial;

    string SampleName { get; set; }

    void DrawGizmos() {
        if (Handles.ShouldRenderGizmos()) {
            context.DrawGizmos(camera, GizmoSubset.PreImageEffects);
            context.DrawGizmos(camera, GizmoSubset.PostImageEffects);
        }
    }

    //shader错误时, 显示为粉红
    void DrawUnsupportedShaders() {
        if (errorMaterial == null) {
            errorMaterial = new Material(Shader.Find("Hidden/InternalErrorShader"));
        }
        var drawingSettings = new DrawingSettings(legacyShaderTagIds[0], new SortingSettings(camera)) {
            overrideMaterial = errorMaterial
        };
        for (int i = 1; i < legacyShaderTagIds.Length; i++) {
            drawingSettings.SetShaderPassName(i, legacyShaderTagIds[i]);
        }
        var filteringSettings = FilteringSettings.defaultValue;
        context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
    }

    void PrepareForSceneWindow() {
        if (camera.cameraType == CameraType.SceneView) {
            ScriptableRenderContext.EmitWorldGeometryForSceneView(camera); //渲染ugui的几何图形
        }
    }

    void PrepareBuffer() {
        Profiler.BeginSample("Editor Only"); //Window -> Analysis -> Profile -> CPU Usage:Hierarchy中会显示
        buffer.name = SampleName = camera.name; //编辑器下BeginSample使用相机名字, Player下使用固定名字(Render Camera)
        Profiler.EndSample();
    }

#else
    const string SampleName = bufferName;
#endif

}

 

Lighting.cs

public class Lighting {

    const string Sample_Name = "Lighting";

    const int maxDirLightCount = 4;

    static int dirLightCountId = Shader.PropertyToID("_DirectionalLightCount");
    static int dirLightColorsId = Shader.PropertyToID("_DirectionalLightColors");
    static int dirLightDirectionsId = Shader.PropertyToID("_DirectionalLightDirections");

    static Vector4[] dirLightColors = new Vector4[maxDirLightCount];
    static Vector4[] dirLightDirections = new Vector4[maxDirLightCount];

    CommandBuffer buffer = new CommandBuffer {
        name = "Lighting"
    };

    CullingResults cullingResults;

    public void Setup(ScriptableRenderContext context, CullingResults cullingResults) {
        this.cullingResults = cullingResults;
        buffer.BeginSample(Sample_Name);
        SetupLights();
        buffer.EndSample(Sample_Name);
        context.ExecuteCommandBuffer(buffer);
        buffer.Clear();
    }

    void SetupLights() {
        NativeArray<VisibleLight> visibleLights = cullingResults.visibleLights;
        int dirLightCount = 0;
        for (int i = 0; i < visibleLights.Length; i++) {
            VisibleLight visibleLight = visibleLights[i];
            if (visibleLight.lightType == LightType.Directional) {
                SetupDirectionalLight(dirLightCount++, ref visibleLight);
                if (dirLightCount >= maxDirLightCount) 
                    break;
            }
        }

        buffer.SetGlobalInt(dirLightCountId, dirLightCount);
        buffer.SetGlobalVectorArray(dirLightColorsId, dirLightColors);
        buffer.SetGlobalVectorArray(dirLightDirectionsId, dirLightDirections);
    }

    void SetupDirectionalLight (int index, ref VisibleLight visibleLight) {
        dirLightColors[index] = visibleLight.finalColor;
        dirLightDirections[index] = -visibleLight.localToWorldMatrix.GetColumn(2);
    }
    
}

 

ShaderLibrary/UnityInput.hlsl

#ifndef CUSTOM_UNITY_INPUT_INCLUDED
#define CUSTOM_UNITY_INPUT_INCLUDED

CBUFFER_START(UnityPerDraw)
    float4x4 unity_ObjectToWorld;
    float4x4 unity_WorldToObject;
    float4 unity_LODFade;
    real4 unity_WorldTransformParams;
CBUFFER_END

float4x4 unity_MatrixVP; //世界空间坐标转裁剪空间
float4x4 unity_MatrixV; //世界空间坐标转相机空间
float4x4 unity_MatrixInvV;
float4x4 unity_prev_MatrixM;
float4x4 unity_prev_MatrixIM;
float4x4 glstate_matrix_projection; //投影矩阵

float3 _WorldSpaceCameraPos; //相机位置

#endif

 

ShaderLibrary/Common.hlsl

#ifndef CUSTOM_COMMON_INCLUDED
#define CUSTOM_COMMON_INCLUDED

#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
#include "UnityInput.hlsl"

//下面的宏是SpaceTransforms会用到, 不定义无法通过编译
#define UNITY_MATRIX_M unity_ObjectToWorld
#define UNITY_MATRIX_I_M unity_WorldToObject
#define UNITY_MATRIX_V unity_MatrixV
#define UNITY_MATRIX_I_V unity_MatrixInvV
#define UNITY_MATRIX_VP unity_MatrixVP
#define UNITY_PREV_MATRIX_M unity_prev_MatrixM
#define UNITY_PREV_MATRIX_I_M unity_prev_MatrixIM
#define UNITY_MATRIX_P glstate_matrix_projection

#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl"

float Square(float x) {
    return x * x;
}

#endif

 

ShaderLibrary/Surface.hlsl

#ifndef CUSTOM_SURFACE_INCLUDED
#define CUSTOM_SURFACE_INCLUDED

//光照射到的物体表面的相关信息
struct Surface {
    float3 normal; //法线
    float3 viewDirection; //视角方向
    float3 color; //光照计算前的颜色
    float alpha;
    float metallic; //金属度
    float smoothness; //光滑度
};

#endif

 

ShaderLibrary/Light.hlsl

#ifndef CUSTOM_LIGHT_INCLUDED
#define CUSTOM_LIGHT_INCLUDED

#define MAX_DIRECTIONAL_LIGHT_COUNT 4

CBUFFER_START(_CustomLight)
    int _DirectionalLightCount;
    float4 _DirectionalLightColors[MAX_DIRECTIONAL_LIGHT_COUNT];
    float4 _DirectionalLightDirections[MAX_DIRECTIONAL_LIGHT_COUNT];
CBUFFER_END

struct Light {
    float3 color; //光源颜色
    float3 direction; //光源方向
};

//平行光总数量
int GetDirectionalLightCount() {
    return _DirectionalLightCount;
}

//获取某个平行光信息
Light GetDirectionalLight(int index) {
    Light light;
    light.color = _DirectionalLightColors[index].rgb;
    light.direction = _DirectionalLightDirections[index].xyz;
    return light;
}

#endif

 

ShaderLibrary/BRDF.hlsl

#ifndef CUSTOM_BRDF_INCLUDED
#define CUSTOM_BRDF_INCLUDED

//光照到物体表面后, 一部分被漫反射(向各个方向均匀反射), 其余部分被镜面反射(某个方向完全反射)。 注意: 折射和进入物体等情况不考虑时
//金属度决定镜面反射比例, 光滑度决定镜面反射比例中有多少比例反射出来

//双向反射分布计算要用到的数据
struct BRDF {
    float3 diffuse;  //漫反射
    float3 specular; //高光
    float roughness; //粗糙度
};

#define MIN_REFLECTIVITY 0.04 //非金属的平均镜面反射比例

//获取漫反射比例
float OneMinusReflectivity(float metallic) {
    float range = 1.0 - MIN_REFLECTIVITY;
    return range - metallic * range; //确保metallic=0时也有镜面反射
}

//双向反射分布计算后的漫反射(会比物体原有颜色弱)和镜面反射
BRDF GetBRDF(Surface surface, bool applyAlphaToDiffuse = false) {
    BRDF brdf;
    float oneMinusReflectivity = OneMinusReflectivity(surface.metallic);

    brdf.diffuse = surface.color * oneMinusReflectivity;
    if (applyAlphaToDiffuse) {
        brdf.diffuse *= surface.alpha;
    }
    brdf.specular = lerp(MIN_REFLECTIVITY, surface.color, surface.metallic);

    //迪士尼光照模型中的方法计算出粗糙度
    float perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(surface.smoothness);
    brdf.roughness = PerceptualRoughnessToRoughness(perceptualRoughness); //直观方式表示的粗糙度(即: 0~1)转换为公式使用的粗糙度
    return brdf;
}

//高光反射强度取决于视角方向和完全发射方向的正对程度, 这边使用简化版CookTorrance BRDF公式计算
float SpecularStrength(Surface surface, BRDF brdf, Light light) {
    // r^2 / (d^2*max(0.1, (L·H)^2)*n), r为粗糙度
    // d = (N·H)^2*(r^2 - 1) + 1.0001, N为表面法线方向
    // H = L+V, L为光源方向, V为视角方向
    // n = 4*r+2
    float3 h = SafeNormalize(light.direction + surface.viewDirection);
    float nh2 = Square(saturate(dot(surface.normal, h)));
    float lh2 = Square(saturate(dot(light.direction, h)));
    float r2 = Square(brdf.roughness);
    float d2 = Square(nh2 * (r2 - 1.0) + 1.00001);
    float normalization = brdf.roughness * 4.0 + 2.0;
    return r2 / (d2 * max(0.1, lh2) * normalization);
}

//平行光的BRDF
float3 DirectBRDF(Surface surface, BRDF brdf, Light light) {
    //高光反射叠加漫反射(叠加用+,混合用乘)
    return SpecularStrength(surface, brdf, light) * brdf.specular + brdf.diffuse;
}

#endif

 

ShaderLibrary/Lighting.hlsl

#ifndef CUSTOM_LIGHTING_INCLUDED
#define CUSTOM_LIGHTING_INCLUDED

//入射光强度计算
float3 IncomingLight(Surface surface, Light light) {
    return saturate(dot(surface.normal, light.direction)) * light.color;
}

//单个入射光照到物体表面后的光照的计算
float3 GetLighting(Surface surface, BRDF brdf, Light light) {
    return IncomingLight(surface, light) * DirectBRDF(surface, brdf, light);
}

//所有光照的计算
float3 GetLighting(Surface surface, BRDF brdf) {
    float3 color = 0.0;
    for (int i = 0; i < GetDirectionalLightCount(); i++) {
        color += GetLighting(surface, brdf, GetDirectionalLight(i));
    }
    return color;
}

#endif

 

LitPass.hlsl

#ifndef CUSTOM_LIT_PASS_INCLUDED
#define CUSTOM_LIT_PASS_INCLUDED

#include "../ShaderLibrary/Common.hlsl"
#include "../ShaderLibrary/Surface.hlsl"
#include "../ShaderLibrary/Light.hlsl"
#include "../ShaderLibrary/BRDF.hlsl"
#include "../ShaderLibrary/Lighting.hlsl"

TEXTURE2D(_BaseMap);
SAMPLER(sampler_BaseMap);

UNITY_INSTANCING_BUFFER_START(UnityPerMaterial)
    UNITY_DEFINE_INSTANCED_PROP(float4, _BaseMap_ST)
    UNITY_DEFINE_INSTANCED_PROP(float4, _BaseColor)
    UNITY_DEFINE_INSTANCED_PROP(float, _Cutoff)
    UNITY_DEFINE_INSTANCED_PROP(float, _Metallic)
    UNITY_DEFINE_INSTANCED_PROP(float, _Smoothness)
UNITY_INSTANCING_BUFFER_END(UnityPerMaterial)

struct Attributes {  //程序传入顶点着色器的数据
    float3 positionOS : POSITION; //用模型空间顶点坐标填充该变量
    float3 normalOS : NORMAL; //用模型空间法线方向填充该变量
    float2 baseUV : TEXCOORD0; //用模型的第一套纹理坐标(uv)填充该变量
    UNITY_VERTEX_INPUT_INSTANCE_ID
};

struct Varyings { //顶点着色器传入片元着色器的数据
    float4 positionCS : SV_POSITION; //该变量存放了裁剪空间的顶点坐标
    float3 positionWS : VAR_POSITION;
    float3 normalWS : VAR_NORMAL;
    float2 baseUV : VAR_BASE_UV;
    UNITY_VERTEX_INPUT_INSTANCE_ID
};

Varyings LitPassVertex (Attributes input) { //顶点着色器
    Varyings output;
    UNITY_SETUP_INSTANCE_ID(input);
    UNITY_TRANSFER_INSTANCE_ID(input, output);
    output.positionWS = TransformObjectToWorld(input.positionOS); //模型空间转世界空间
    output.positionCS = TransformWorldToHClip(output.positionWS); //世界空间转裁剪空间
    output.normalWS = TransformObjectToWorldNormal(input.normalOS);

    float4 baseST = UNITY_ACCESS_INSTANCED_PROP(UnityPerMaterial, _BaseMap_ST);
    output.baseUV = input.baseUV * baseST.xy + baseST.zw; //应用贴图的tiling和offset
    return output;
}

float4 LitPassFragment (Varyings input) : SV_TARGET { //片元着色器
    UNITY_SETUP_INSTANCE_ID(input);
    float4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.baseUV); //根据纹理坐标获取像素颜色
    float4 baseColor = UNITY_ACCESS_INSTANCED_PROP(UnityPerMaterial, _BaseColor);
    float4 base = baseMap * baseColor;
    #if defined(_CLIPPING)
        clip(base.a - UNITY_ACCESS_INSTANCED_PROP(UnityPerMaterial, _Cutoff));
    #endif

    Surface surface;
    surface.normal = normalize(input.normalWS);
    surface.viewDirection = normalize(_WorldSpaceCameraPos - input.positionWS); //视角方向
    surface.color = base.rgb;
    surface.alpha = base.a;
    surface.metallic = UNITY_ACCESS_INSTANCED_PROP(UnityPerMaterial, _Metallic);
    surface.smoothness =
        UNITY_ACCESS_INSTANCED_PROP(UnityPerMaterial, _Smoothness);
    
    #if defined(_PREMULTIPLY_ALPHA)
        BRDF brdf = GetBRDF(surface, true);
    #else
        BRDF brdf = GetBRDF(surface);
    #endif
    float3 color = GetLighting(surface, brdf);
    return float4(color, surface.alpha);
}

#endif

 

Lit.shader

Shader "Custom RP/Lit" {
    
    Properties {
        _BaseMap("Texture", 2D) = "white" {} //主贴图
        _BaseColor("Color", Color) = (0.5, 0.5, 0.5, 1.0) //混合颜色
        _Cutoff ("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
        [Toggle(_CLIPPING)] _Clipping ("Alpha Clipping", Float) = 0

        _Metallic ("Metallic", Range(0, 1)) = 0  //金属度
        _Smoothness ("Smoothness", Range(0, 1)) = 0.5  //光滑度

        [Toggle(_PREMULTIPLY_ALPHA)] _PremulAlpha ("Premultiply Alpha", Float) = 0

        [Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend ("Src Blend", Float) = 1
        [Enum(UnityEngine.Rendering.BlendMode)] _DstBlend ("Dst Blend", Float) = 0
        [Enum(Off, 0, On, 1)] _ZWrite ("Z Write", Float) = 1
    }
    
    SubShader {
        Pass {
            Tags {
                "LightMode" = "CustomLit"
            }

            Blend [_SrcBlend] [_DstBlend]
            ZWrite [_ZWrite]

            HLSLPROGRAM //hlsl代码需要用这个包着
            #pragma target 3.5 //Shader Model版本低于3.5, 核心库无法通过编译
            #pragma shader_feature _CLIPPING
            #pragma shader_feature _PREMULTIPLY_ALPHA
            #pragma multi_compile_instancing
            #pragma vertex LitPassVertex
            #pragma fragment LitPassFragment
            #include "LitPass.hlsl"
            ENDHLSL
        }
    }
}

 

翻译备忘:

We would only see this light if the camera were aligned with it 只有当相机正对它时,我们才能看到这束光   But if the surface isn't perfectly flat then the light gets scattered 如果表面不是完全光滑的, 那么光就会散射   because the fragment effectively consists of many smaller fragments that have different orientations 因为片元实际上由许多不同朝向的小片元组成   This splits the beam of light into smaller beams that go in different directions, which effectively blurs the specular reflection 这将一束光分散成更小的光(不同方向),这有效的柔化了镜面反射   Surfaces can be perfectly diffuse, perfect mirrors, or anything in between 表面可以完全漫反射, 完全镜面反射, 或介于两者之间

标签:Catlike,float,Coding,unity,surface,Custom,UNITY,brdf,float3
From: https://www.cnblogs.com/sailJs/p/18617601

相关文章

  • 差异编码(Delta Encoding) 和 字典压缩(Dictionary Encoding)
    1.差异编码(DeltaEncoding):倒排列表中可能会采用差异编码,即存储相邻文档ID之间的差值,而不是直接存储每个文档ID,这样可以进一步压缩空间。2.字典压缩(DictionaryEncoding):对于倒排列表中的文档ID,可以使用字典进行压缩,进一步减少存储需求。举例学习和说明这两个方法 差异......
  • 我用AI Assistant编写代码,竟完成了100%的Coding工作!还在蒙头敲代码的时代已经过去啦!
    大家好,欢迎来到程序视点!我是小二哥。前言昨天我们详细分享了Cursor、GitHubCopilot和AIAssistant三款AI工具怎么选的问题。今天,我们用AIAssistant来解决下实践中的问题–AIAssistant写代码。这是某高校技能大赛的题目之一。大家自己评估一下,写出这道题需要多久?AI......
  • Chromium CDP 开发(十三):为自己的Domain建立CustomCDPHandler
    引言在开发ChromiumCDP(ChromeDevToolsProtocol)时,除了创建PDL和JSON文件来定义自定义的CDPDomain和指令外,还需要编写对应的Handler实现文件,以便使这些自定义指令能够被正确执行。本章将详细介绍如何为自定义的CDPDomain创建和实现Handler文件custom_cdp_ha......
  • 学习012-04-09-01-02 How to: Show a Custom Data-Bound Control in an XAF View (Bla
    Howto:ShowaCustomData-BoundControlinanXAFView(Blazor)-CurrentObjectData(如何:在XAF视图(Blazor)中显示自定义数据绑定控件-当前对象数据)ThisarticleexplainshowtocreateareusableViewItemthatcanworkwithdatasuppliedbytheView’sc......
  • 【AIcoding技术必知必会】11问--CI/CD流水线是什么?
    基础介绍软件开发生命周期(SDLC)由下面这几个关键阶段组成:开发、测试、部署和运维。CI/CD将这些阶段自动化并整合起来,实现更快更可靠的发布。当代码提交到git仓库,便会触发自动的构建和测试流程。其中会运行端到端测试用例来验证代码。如果测试通过,代码就会自动部署到预发或生产......
  • 【AIcoding技术必知必会】10问--命令行是什么?
    基础介绍命令行(CommandLine)是一种通过输入文本命令来与计算机交互的界面,也称为命令行界面(CLI-CommandLineInterface)。它是一种交互方法,而不是具体的程序。相比图形用户界面(GUI),命令行提供了更直接和强大的方式来控制计算机。熟练掌握后会大大提高工作效率,特别是在服务器管......
  • 从 AI Coding 演进路径看通义灵码 AI 程序员的发布,让更多 idea 变成产品
    点击链接,回顾发布会:https://www.bilibili.com/video/BV1v6c9euESz/根据StackOverflow的一个开发者调查报告:2024年有62% 的开发者正在使用AI编码工具;根据IDC的一个调查报告,对于已经探索生成式AI的中国企业,有31% 的研发人员已经在使用代码生成产品。AI编码工具的使用人......
  • 从 AI Coding 演进路径看通义灵码 AI 程序员的发布,让更多 idea 变成产品
    点击链接,回顾发布会:https://www.bilibili.com/video/BV1v6c9euESz/根据StackOverflow的一个开发者调查报告:2024年有62% 的开发者正在使用AI编码工具;根据IDC的一个调查报告,对于已经探索生成式AI的中国企业,有31% 的研发人员已经在使用代码生成产品。AI编码工具的使用人......
  • [PCIE5.0] 4.2.8 Compliance Pattern in 8b/10b Encoding
    这段文字描述的是在PCIe或类似高速接口协议中,Polling.Compliance子状态的具体要求,特别是合规模式(CompliancePattern)在传输过程中的处理方式。这个过程主要是通过SKPOrderedSet来验证链路的合规性,确保链路在高频率下的稳定性、可靠性和时序准确性。我们来逐步解读这......
  • [Vue warn]: Unknown custom element:
    [Vuewarn]:Unknowncustomelement:<experience-share>-didyouregisterthecomponentcorrectly?Forrecursivecomponents,makesuretoprovidethe"name"option.foundin---><ProductListDialog>atsrc/views/tools/fake-strat......