【问题标题】:WebGL Normal calculations from position texture基于位置纹理的 WebGL 法线计算
【发布时间】:2015-05-26 09:37:51
【问题描述】:

我正在尝试在 webGL 中通过顶点置换创建一个带有“水波纹”的程序水坑。 我遇到的问题是我得到了我无法解释的噪音。

下面是第一遍顶点着色器,我在其中计算顶点位置,然后将其渲染到纹理中,然后在第二遍中使用。

void main()         {           
            float damping = 0.5;
            vNormal = normal;

            // wave radius
            float timemod = 0.55;
            float ttime = mod(time , timemod);

            float frequency = 2.0*PI/waveWidth;
            float phase = frequency * 0.21;

            vec4 v = vec4(position,1.0);
            // Loop through array of start positions
            for(int i = 0; i < 200; i++){

                float cCenterX = ripplePos[i].x;
                float cCenterY = ripplePos[i].y;
                vec2 center = vec2(cCenterX, cCenterY) ;

                if(center.x == 0.0 && center.y == 0.0)
                    center = normalize(center);

                // wave width
                float tolerance = 0.005;

                radius = sqrt(pow( uv.x - center.x , 2.0) + pow( uv.y -center.y, 2.0));
                // Creating a ripple
                float w_height = (tolerance - (min(tolerance,pow(ripplePos[i].z-radius*10.0,2.0)) )) * (1.0-ripplePos[i].z/timemod) *5.82;

                // -2.07 in the end to keep plane at right height. Trial and error solution
                v.z += waveHeight*(1.0+w_height/tolerance) / 2.0 - 2.07;

                vNormal = normal+v.z;
            }
            vPosition = v.xyz;

            gl_Position = projectionMatrix * modelViewMatrix * v;
        }

以及写入纹理的第一遍片段着色器:

        void main()
        {
            vec3 p = normalize(vPosition);

            p.x = (p.x+1.0)*0.5;
            p.y = (p.y+1.0)*0.5;


            gl_FragColor = vec4(  normalize(p), 1.0);
        }

第二个顶点着色器是标准的直通。

第二遍片段着色器是我尝试计算用于光照计算的法线的地方。

void main() {

            float w = 1.0 / 200.0;
            float h = 1.0 / 200.0;

            // Nearest Nieghbours 
            vec3 p0 = texture2D(rttTexture, vUV).xyz;
            vec3 p1 = texture2D(rttTexture, vUV + vec2(-w,  0)).xyz;
            vec3 p2 = texture2D(rttTexture, vUV + vec2( w,  0)).xyz;
            vec3 p3 = texture2D(rttTexture, vUV + vec2( 0,  h)).xyz;
            vec3 p4 = texture2D(rttTexture, vUV + vec2( 0, -h)).xyz;

            vec3 nVec1 = p2 - p0;
            vec3 nVec2 = p3 - p0;

            vec3 vNormal = cross(nVec1, nVec2);

            vec3 N = normalize(vNormal);

             float theZ =  texture2D(rttTexture, vUV).r;
            //gl_FragColor = vec4(1.,.0,1.,1.);
          //gl_FragColor = texture2D(tDiffuse, vUV);
            gl_FragColor = vec4(vec3(N), 1.0);
        }

结果是这样的:

图像显示的是法线贴图,我指的噪点是蓝色的不一致。

这是一个现场演示: http://oskarhavsvik.se/jonasgerling_water_ripple/waterRTT-clean.html

我感谢任何提示和指示,而不仅仅是解决此问题。但是一般的代码,我是来学习的。

【问题讨论】:

    标签: glsl webgl normals render-to-texture


    【解决方案1】:

    经过简短的查看,您的问题似乎在于存储 x/y 位置。

    gl_FragColor = vec4(vec3(p0*0.5+0.5), 1.0);
    

    无论如何,您都不需要存储它们,因为纹素位置隐含地给出了 x/y 值。只需将您的正常点更改为这样的...

    vec3 p2 = vec3(1, 0, texture2D(rttTexture, vUV + vec2(w, 0)).z);
    

    而不是1, 0,您将希望使用与显示的四边形相对于波高的大小相适应的比例。不管怎样,现在的结果是这样的。

    高度/z 似乎是按距中心的距离缩放的,所以我去找了一个normalize() 并将其删除...

                vec3 p = vPosition;
                gl_FragColor = vec4(p*0.5+0.5, 1.0);
    

    法线现在看起来像这样......

    【讨论】:

    • 好的,非常感谢您抽出宝贵时间,这正是我想要的。你是一个救生员:)我真的很欣赏这个解释。
    猜你喜欢
    • 2012-12-04
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    • 2010-10-15
    • 2012-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多