游戏开发论坛

 找回密码
 立即注册
搜索
查看: 6063|回复: 13

[求助]如何使用ShadingLanguage给海面上色?

[复制链接]

29

主题

157

帖子

163

积分

注册会员

Rank: 2

积分
163
发表于 2006-8-12 17:31:00 | 显示全部楼层 |阅读模式
      我今年3月才接触的OpenGL(之前没有接触过计算机图形方面的东西), 一个月前才知道GPU也能编程和有shadinglanguage. 本来想暂时用不上,以后再学(目前OpenGL的基本功能都没有精通呢),结果没想到这么快就被逼得必须要用了. 由于基础太差(计算机图形学, 数学, 英语很差, GPU的硬件结构, 管线都不了解),所以看了两天<<OpenGL Shading Language>>还是不太清楚,但又急着用,所以希望大家不吝赐教,并且尽可能通俗一些,呵呵.
      如果大家谁有关于GPU硬件原理, 工作原理的资料( 如:一般有哪些寄存器, 名字叫什么, 掌管什么功能等等),  还望可以给我一份, 或者直接解答.

      我需要制作一个比较仿真的海面, 使用傅立叶变换 + P-M频谱 + 视点相关LOD来生成可以振动的海面网格, 目前这个工作已经完成了, 但是最后的给海水赋予颜色(或纹理)的工作却遇到了麻烦, 如果海水是单一的颜色,那么就看不出有振动的效果, 所以必须使海水有明暗变化和反射效果, 由于组成海面的网格较大(比一个像素大多了),所以如果使用传统的OpenGL功能渲染,就会出现颜色一块一块的现象(使用了GL_SMOOTH也不行), 在网上看别人都是使用GPU编程来逐像素渲染颜色的, 效果很不错, 所以也想使用, 但目前存在以下不明白的地方:

       1:网上查的时候有人使用CubeTex和Normal map(使用Direct 3D作的), 这是什么东西?
CubeBox我没听过;  Normal Map 是不是 像Bump map 和Phong shding (以前看过相关理论的文章)中使用的那种里面储存着向量的纹理? 可是这些数据是怎么写到图片里去的? Direct中有.DDS格式来存储这种图, OpenGL里面怎么办?

       2:具体的渲染流程应该怎么组织呢? 我现在的设想是:

      (1). 使用VP(或VS)计算每个网格顶点的法线(这个工作如果让CPU作的话, 法线的标准化将会是一个很大的工作量).
      但是求法线需要知道这个顶点所在的平面上的两条过这个顶点的向量, 这两条向量一般是用当前顶点相邻的两个顶点减去当前顶点得到的, 我看书上VP(或VS)中可以知道当前点的坐标, 但是怎么才能知道另外两个点的坐标呢? 莫非是通过Uniform每一帧都传依次参数?

       (2). 通过视点到网格上每个顶点的的入射"光"线 和上一步求出的法线, 求出出射"光"线. 再求出出射"光"线与海面上方某个平面的交点(这个虚拟的平面就相当于天空的纹理), 求出该纹理这一点的颜色, 与网格顶点的原有颜色融合.
        但是在VP(或VS)中似乎不能处理纹理, 那怎么求得纹理某点的颜色呢?

        (3). 在FP(或PS)中进行逐像素上色时,每个像素的颜色使用该像素所在三角面的三个顶点的颜色值进行插值.
         但是这个也存在着(1)中的问题, 怎么获取这3个顶点的颜色值呢? 不会也用Uniform参数传吧.

         综上所述, 我觉的自己的设想应该是错误的,可能不符合GPU编程提供的功能和图形渲染的机制. 可能只能使用什么CubeTex 和 Normal Map了, 但又不会, 不知各位大虾有没有什么好的方法并教教我.


      



      

29

主题

157

帖子

163

积分

注册会员

Rank: 2

积分
163
 楼主| 发表于 2006-8-12 17:32:00 | 显示全部楼层

Re:[求助]如何使用ShadingLanguage给海面上色?

不好意思, 问题一次有点多, 呵呵

139

主题

2005

帖子

2057

积分

金牌会员

Rank: 6Rank: 6

积分
2057
QQ
发表于 2006-8-13 03:07:00 | 显示全部楼层

Re:[求助]如何使用ShadingLanguage给海面上色?

( 如:一般有哪些寄存器, 名字叫什么, 掌管什么功能等等) 这个东西要是有就好了,这东西不像CPU,不公开的。

5

主题

686

帖子

697

积分

高级会员

Rank: 4

积分
697
QQ
发表于 2006-8-13 09:05:00 | 显示全部楼层

Re:[求助]如何使用ShadingLanguage给海面上色?

FFT都做出来了,居然会卡在HLSL上……
硬件细节是不需要知道的,也不可能知道,那是驱动程序做的事情,跟你无关
DX10之前的硬件,法线是不大可能在GPU中动态计算的,就算用VTF来模拟,那也是很变态的方法……
至于Cubemap和Normalmap,那都是很简单的东西,不介意的话可以去看看DX的文档,原理都是一样的,OGL在Help这方面做得很差

29

主题

157

帖子

163

积分

注册会员

Rank: 2

积分
163
 楼主| 发表于 2006-8-13 10:14:00 | 显示全部楼层

Re:[求助]如何使用ShadingLanguage给海面上色?

哦, 谢谢.
昨天看<<OpenGL Shading Language>>的时候, 根据里面的描述, Cubemap 好像就是我们平时说的中点在原点上的方形的天空盒, 不知我的理解对不对?

用CPU求法线慢,主要是慢在法线的归一化上面(里面要开平方根), 但是似乎可以只用CPU求出法线, 归一化的工作可以用GPU的Normalize函数完成. 我想问的在VS里的那个Normalize函数是固化在GPU中的吗? 还是调用了CPU求出来的?

至于FFT能作出来...呵呵... 这种东西只要上网上搜一下"实时海浪模拟", 就能搜出N多博士或硕士的论文来, 就算看不懂, 只要把它们里面的公式代码化了就行. 但是用GPU渲染海浪的文章就很少很少, 估计搞科研的人们不屑于研究这种技术含量高于理论含量的东西吧.  所以我也就傻了. 呵呵~

139

主题

2005

帖子

2057

积分

金牌会员

Rank: 6Rank: 6

积分
2057
QQ
发表于 2006-8-13 13:16:00 | 显示全部楼层

Re:[求助]如何使用ShadingLanguage给海面上色?

昨天看<<OpenGL Shading Language>>的时候, 根据里面的描述, Cubemap 好像就是我们平时说的中点在原点上的方形的天空盒, 不知我的理解对不对?
----------------------差不多,效果上是一样的.本质上有一点不同,但是无关紧要

用CPU求法线慢,主要是慢在法线的归一化上面(里面要开平方根), 但是似乎可以只用CPU求出法线, 归一化的工作可以用GPU的Normalize函数完成. 我想问的在VS里的那个Normalize函数是固化在GPU中的吗? 还是调用了CPU求出来的?
------------------驱动相关 [em10]

5

主题

686

帖子

697

积分

高级会员

Rank: 4

积分
697
QQ
发表于 2006-8-13 13:37:00 | 显示全部楼层

Re:[求助]如何使用ShadingLanguage给海面上色?

不光是Normalize,每帧都要遍历整个模型,Lock/Unlock都是很恶心的事,一般动态用CPU求法线都是不会Normalize了,这种操作当然要交给GPU了,Normalize在SM2.0的硬件上是有专门的指令,在1.0的硬件上可以用dp3+sqrt来完成,不是很费时的

29

主题

157

帖子

163

积分

注册会员

Rank: 2

积分
163
 楼主| 发表于 2006-8-13 20:15:00 | 显示全部楼层

Re:[求助]如何使用ShadingLanguage给海面上色?

嗯, 谢谢
再问个问题, 我已经写好了vs和fs文件, 在OpenGL程序中将它们读入, 编译并且连接, 然后在使用的时候使用glUseProgramObjectARB(...)函数, 但是这样的话, GPU中的程序就会影响所有的像素, 把我不想用shading language 的部分都给处理了, 我尝试着用
glDisable(GL_VERTEX_SHADER_ARB)和glEnable(GL_VERTEX_SHADER_ARB)控制它的作用范围,但是却没有用, 事实上我在任何地方都不使用glEnable(GL_VERTEX_SHADER_ARB)函数, 它依然可以起作用.

所以请问有哪个函数可以在我不想用shading language 的时候让GPU中还原呢? 总不能我每一帧都重新编译连接, 用完后有delete调吧?

29

主题

157

帖子

163

积分

注册会员

Rank: 2

积分
163
 楼主| 发表于 2006-8-13 20:27:00 | 显示全部楼层

Re:[求助]如何使用ShadingLanguage给海面上色?

还有请问要使用uniform sampler的时候外部应用程序的步骤是怎样的啊?
比如我现在要使用uniform sampler2D EnvMap  //EnvMap为第0层纹理
那么我在外部的应用程序是不是得有一下步骤呢?
(1).  读入纹理
glBindTexture(GL_TEXTURE_2D, EnvMap);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, pImage->sizeX, pImage->sizeY, 0,
                GL_RGB, GL_UNSIGNED_BYTE, pImage->data);

(2).在绘制需要使用Shading language的模型之前, 绑定该纹理:
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, EnvMap);

(3).传入参数:
uniformLoc = glGetUniformLocationARB(progObj[1], "EnvMap");
if (uniformLoc != -1)
{
    glUniform1iARB(uniformLoc, 0);
}

请问是这样吗? 我是这样做的, 但是在连接的时候总是出错, 我把fs中有关纹理的代码屏蔽掉后,
就能通过了,是不是我哪里写错了?

29

主题

157

帖子

163

积分

注册会员

Rank: 2

积分
163
 楼主| 发表于 2006-8-13 20:30:00 | 显示全部楼层

Re:[求助]如何使用ShadingLanguage给海面上色?

这里附上我程序中fs中的代码, 这里应该不会出错的, 这段代码是我直接从<<OpenGL Shading
Language>>中的Env Map章节粘贴过来的.

const vec3 Xunitvec = vec3(1.0, 0.0, 0.0);
const vec3 Yunitvec = vec3(0.0, 1.0, 0.0);

uniform vec3  BaseColor;
uniform float MixRatio;

uniform sampler2D EnvMap; // = 4

varying vec3 Normal;

varying vec3  EyeDir;
varying float LightIntensity;

void main()
{
    // Compute reflection vector

    vec3 reflectDir = reflect(EyeDir, Normal);

    // Compute altitude and azimuth angles

    vec2 index;

    index.t = dot(normalize(reflectDir), Yunitvec);
    reflectDir.y = 0.0;
    index.s = dot(normalize(reflectDir), Xunitvec) * 0.5;

    // Translate index values into proper range

    if (reflectDir.z >= 0.0)
        index = (index + 1.0) * 0.5;
    else
    {
        index.t = (index.t + 1.0) * 0.5;
        index.s = (-index.s) * 0.5 + 1.0;
    }

    // if reflectDir.z >= 0.0, s will go from 0.25 to 0.75
    // if reflectDir.z < 0.0, s will go from 0.75 to 1.25, and
    // that's OK, because we've set the texture to wrap.

    // Do a lookup into the environment map.

    vec3 envColor = vec3(texture2D(EnvMap, index));

    // Add lighting to base color and mix

    vec3 base = LightIntensity * BaseColor;
    envColor = mix(envColor, base, MixRatio);

    gl_FragColor = vec4(envColor, 1.0);
}
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-25 03:42

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表