Pixel Shader 2.x 的问题

 
Pixel Shader 2.x的问题
作者: cywater2000
日期: 2007-4-19
 
一直以为支持 Pixel Shader( 以下简称 ps)2.0 的显卡自然支持 2.x ,因为 D3DPS_VERSION 只有 (2,0) 这个版本号可以检查。事实证明是错误的。
这几天把一个 demo 放到 ATI Radeon X600 上跑,结果发现程序始终无法正确运行。调了半天都找不出错误。由于我检查了每个函数的返回值 ( V) ,所以应该不是 API 参数没有设对 ( 比如创建的纹理格式不支持 ) 。最后在 debug 信息窗口中发现了一些线索:
D3DX: ID3DXEffect: Warning! Failed to create shader on this device (probably because shader version is unsupported)
我靠 ! D3DXCreateEffectFromFile 返回值是 S_OK ! WTH!
然后把范围缩小到某个 ps 程序上。这个程序我是用 ps_2_a 编译的,难道 X 600 不支持?于是 google 之。
果然是这样 ! 而且 ps_2_a ps_2_b 也是不一样的。简单来说,前者是 NVIDIA 支持的标准,后者是 ATI
具体的比较可以看这个:
 
 
 
于是有老外戏称使用 ps_2_nv ps_2_at 更准确,更有甚者取名为:
ps_2_we_suck_too_much_to_just_make_it_3 (ps_2_a)
ps_2_wtf_we_dont_need_this (ps_2_b)
233max
 
实际上大家可以看到 ps_2_b 差不多可以算 2_a 的子集 ( 除了 temp register) ,虽然名字靠后一些。
 
因此,如果要检测硬件是否支持 ps_2_x ,不能光用 D3DPS_VERSION(2, 0) 来判断。下面给出一个简单的方法:
g_pD3DDevice->GetDeviceCaps(&d3dCaps);
if ( d3dCaps.PixelShaderVersion >= D3DPS_VERSION(2, 0) )         //2.0
{
 if(3dCaps.PS20Caps.Caps & D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT) //2.x
{
    if(d3dCaps.PS20Caps.Caps & D3DPS20CAPS_ARBITRARYSWIZZLE) //2.a
    {
    }
    else //2.b
    {
    }
}
}
 
关于检测硬件信息更详细的例子,可以参考 D3D 的例子: Config System Sample
 
最后说一句:也许 DX10 的作法是对的,之前的硬件差别确实太大,对开方者来说确实很不方便 ...
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Wireframe shader,也被称为线框着色器,是一种在计算机图形学中常用的着色器程序,用于将三维物体以线框的形式显示出来。其源码实现的基本思路是将物体的表面细分为一组三角形,然后通过在这些三角形的边界上绘制线段,以形成线框的效果。 Wireframe shader的源码实现通常使用的编程语言是着色器语言。具体实现方式会根据使用的图形库或框架而有所不同,下面是一个简单的示例: ```cpp // vertex shader #version 330 core layout (location = 0) in vec3 position; uniform mat4 model; uniform mat4 view; uniform mat4 projection; void main() { gl_Position = projection * view * model * vec4(position, 1.0); } // geometry shader #version 330 core layout (triangles) in; layout (line_strip, max_vertices = 3) out; void main() { for (int i = 0; i < gl_in.length(); i++) { gl_Position = gl_in[i].gl_Position; EmitVertex(); } EndPrimitive(); } // fragment shader #version 330 core out vec4 FragColor; uniform vec3 lineColor; void main() { FragColor = vec4(lineColor, 1.0); } ``` 上面的代码展示了一个简单的Wireframe shader的实现。顶点着色器(vertex shader)负责将物体的顶点坐标进行变换;几何着色器(geometry shader)负责接收三角形输入,并将三角形的顶点输出为线段来创建线框的效果;片段着色器(fragment shader)负责将线段的颜色设置为指定的线框颜色。 以上是一个基本的Wireframe shader的源码实现,具体的实现方式会根据实际需求和图形库的使用而有所不同,可根据具体情况进行进一步的修改和优化。 ### 回答2: wireframe shader 源码是用于在计算机图形中绘制物体线框的一种着色器程序。它通过将三维模型的多边形表面转化为线条,使得物体的边框和构造变得清晰可见。 以下是一个简单的wireframe shader 源码示例: ``` Shader "Custom/Wireframe" { Properties { _MainTex ("Texture", 2D) = "white" {} _Color ("Color", Color) = (1,1,1,1) _Thickness ("Thickness", Range(0.001, 0.1)) = 0.01 } SubShader { Tags {"Queue"="Transparent" "RenderType"="Transparent"} LOD 100 CGPROGRAM #pragma surface surf Lambert vertex:vert sampler2D _MainTex; fixed4 _Color; float _Thickness; struct Input { float2 uv_MainTex; }; void vert(inout appdata_full v, out Input o) { UNITY_INITIALIZE_OUTPUT(Input, o); o.uv_MainTex = v.texcoord.xy; } void surf(Input IN, inout SurfaceOutput o) { fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color; o.Albedo = c.rgb; o.Alpha = c.a; } // Wireframe rendering sampler2D _CameraNormalTexture; half4 frag(v2f IN) : SV_Target { half4 col = tex2D(_MainTex, IN.uv_MainTex) * _Color; float2 ddx_sample_uv = ddx(IN.uv_MainTex); float2 ddy_sample_uv = ddy(IN.uv_MainTex); float3 n = UnpackNormal(tex2D(_CameraNormalTexture, IN.uv_MainTex)); float3 du = float3(ddx_sample_uv.x, ddy_sample_uv.x, 0.0); float3 dv = float3(ddx_sample_uv.y, ddy_sample_uv.y, 0.0); float3 l = normalize(cross(du, dv)); float thickness = _Thickness * 0.01; float4 wireframe_color = float4(1, 1, 1, 1); float2 pixel_size = 1.0 / _ScreenParams.xy; float2 offset1 = pixel_size * thickness * l.x; float2 offset2 = pixel_size * thickness * l.y; // Draw wireframe lines col = col * (1 - saturate(tex2Dbilinear(_MainTex, IN.uv_MainTex + offset1) - col.a)); col = col * (1 - saturate(tex2Dbilinear(_MainTex, IN.uv_MainTex - offset1) - col.a)); col = col * (1 - saturate(tex2Dbilinear(_MainTex, IN.uv_MainTex + offset2) - col.a)); col = col * (1 - saturate(tex2Dbilinear(_MainTex, IN.uv_MainTex - offset2) - col.a)); return col; } ENDCG } FallBack "Diffuse" } ``` 这段源码首先定义了一个名为"Custom/Wireframe"的shader,包含了一些属性,如纹理、颜色和线宽等。然后,其中的SubShader定义了在透明渲染队列中使用Lambert模型的表面着色方法,使用vert方法对顶点进行处理,使用surf方法设置表面输出。 该源码中添加了用于绘制线框的wireframe渲染部分。它通过获取相邻像素点的颜色并与当前像素点的颜色进行比较,来确定物体的边缘并在边缘进行绘制。 以上是一个简单的wireframe shader 源码示例,实际使用时可以根据需求进行修改和优化。 ### 回答3: Wireframe shader是一种用于在图形渲染中呈现物体边线的着色器。它可以在实时渲染中创建线框效果,使物体的形状更加清晰可见。以下是一个简述Wireframe shader源码的回答: Wireframe shader的源码包含若干主要部分: 1. 顶点着色器(Vertex Shader): 这是Wireframe shader的第一个部分,它用于处理顶点的位置和变换。它将输入的顶点位置进行与相机视角相关的变换,以便在屏幕上正确显示物体。在此之后,它将顶点位置传递给下一阶段(片段着色器)。 2. 片段着色器(Fragment Shader): 这是Wireframe shader的第二个部分,它用于计算每个像素的颜色。在Wireframe shader中,它的主要任务是判断像素是否位于物体的边缘附近。如果一个像素位于边缘附近,它将被绘制为线框,否则将被绘制为背景颜色。为了实现这一点,片段着色器会使用输入的顶点位置信息和附近像素之间的差异来计算边缘。 3. 超采样(Anti-Aliasing): 为了使线框效果更加平滑,Wireframe shader可能还会使用一些超采样技术。这些技术通过对物体的边缘进行抗锯齿处理来减少线条的锯齿状效果。超采样可以通过在片段着色器中使用颜色插值来实现。 总结起来,Wireframe shader的源码主要包含了顶点着色器、片段着色器和超采样处理。这些部分共同协作,将输入的顶点位置和像素信息转换为呈现物体边线的图像。通过使用Wireframe shader,可以增强图形渲染的可视效果,使物体的形状更加清晰可见。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值