swift - SCNProgram 不影响 SCNFloor

标签 swift glsl shader opengl-es-2.0 scenekit

在我使用着色器修改器的实验中,我发现数组数据无法传输到着色器。

Scenekit giving buffer size error while passing array data to uniform array in openGL shader

出于这个原因,我决定尝试 SCNProgram。但是现在我意识到我使用 SCNProgram 添加的着色器在 SCNFloor 上不起作用。

这个问题有什么特别的原因吗?

我用于测试的 super 简单的着色器;

顶点着色器

precision highp float;
attribute vec3 vertex;
uniform mat4 ModelViewProjectionMatrix;

void main()
{
    gl_Position = ModelViewProjectionMatrix * vec4(vertex, 1.0);
}

片段着色器

precision mediump float;

void main( void )
{   
    gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
}

最佳答案

您可以尝试制作自己的垂直和碎片着色器来做同样的事情。我用 webgl/glsl es2 做了类似的事情,或者只是把它涂成实心,给现有的地板着色:

uniform mat4 uCameraWM;  //camera world matrix
uniform vec2 uCamAspFov; //x:aspect ratio y:tan(fov/2) 


varying vec3 vVDw; //view direction

void main(){

//construct frustum, scale and transform a unit quad

vec4 viewDirWorld = vec4(
    position.x * uCamAspFov.x,
    position.y,
    -uCamAspFov.y, //move it to where 1:aspect fits
    0.
);

vVDw = ( uCameraWM * viewDirWorld ).xyz; //transform to world


gl_Position = vec4( position.xy , 0. , 1. ); //draw a full screen quad

}

片段: (无视cruft,重点是将view direction ray与一个平面相交,贴图,可以在天空部分查一个cubemap而不是丢掉)

uniform float uHeight;


uniform sampler2D uTexDiff;
uniform sampler2D uTexNorm;
uniform sampler2D uTexMask;

varying vec2 vUv;

varying vec3 vVDw;

struct Plane
{
    vec3 point;
    vec3 normal;
    float d;
};


bool rpi( in Plane p , in vec3 p0 , in vec3 vd , out vec3 wp )
{

    float t;

    t = -( dot( p0 , p.normal ) + p.d ) / dot( vd , p.normal );

    wp = p0 + t * vd;

    return t > 0. ? true : false;

}

void main(){


    Plane plane;

    plane.point = vec3( 0. , uHeight , 0. );
    plane.normal = vec3( 0. , 1. , .0 );
    plane.d = -dot( plane.point , plane.normal );



    vec3 ld = normalize( vec3(1.,1.,1.) );

    vec3 norm = plane.normal;
    float ndl = dot( norm , ld ) ;



    vec2 uv;
    vec3 wp;
    vec3 viewDir = normalize( vVDw );

    vec3 h = normalize((-viewDir + ld));

    float spec = clamp( dot( h , norm ) , .0 , 1. );

    // spec = pow( spec , 5. ); 

    if( dot(plane.normal , cameraPosition) < 0. ) discard;

    if( !rpi( plane , cameraPosition , viewDir , wp ) ) discard;

    uv = wp.xz;

    vec2 uvm = uv * .0105;
    vec2 uvt = uv * .2;

    vec4 tmask = texture2D( uTexMask , uvm );

    vec2 ch2Scale = vec2(1.8,1.8);
    vec2 ch2Scale2 = vec2(1.6,1.6);

    vec2 t1 = uvt * ch2Scale2 - vec2(tmask.z , -tmask.z) ;
    // vec2 t2 = uvt * ch2Scale + tmask.z ;
    // vec2 t3 = uvt + vec2(0. , mask.z-.5) * 1.52;


    vec3 diffLevels = ( texture2D( uTexDiff , t1 ) ).xyz;

    // vec3 diffuse2 = ( texture2D( uTexDiff, fract(t1) * vec2(.5,1.) + vec2(.5,.0) ) ).xyz;
    // vec3 diffuse1 = ( texture2D( uTexDiff, fract(t2) * vec2(.5,1.) ) ).xyz;


    // vec4 normalMap2 = texture2D( uTexNorm, fract(t1) * vec2(.5,1.) + vec2(.5,.0) );
    // vec4 normalMap1 = texture2D( uTexNorm, fract(t2) * vec2(.5,1.) );

    float diffLevel = mix(diffLevels.y, diffLevels.x, tmask.x);
    diffLevel = mix( diffLevel , diffLevels.z, tmask.y );

    // vec3 normalMix = mix(normalMap1.xyz, normalMap2.xyz, tmask.x);


    // vec2 g = fract(uv*.1) - .5;

    // float e = .1;
    // g = -abs( g ) + e;

    float fog = distance( wp.xz , cameraPosition.xz );

    // float r = max( smoothstep( 0.,e,g.x) , smoothstep( 0.,e,g.y) );

    gl_FragColor.w = 1.;

    gl_FragColor.xyz = vec3(tmask.xxx);
    gl_FragColor.xyz = vec3(diffLevel) * ndl + spec * .5;

}

但总的来说,更好的建议是放弃 scenekit 并为自己省去一大堆挫折。

关于swift - SCNProgram 不影响 SCNFloor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41776793/

相关文章:

ios - 一次关闭 2 个 View Controller

javascript - 在 JavaScript 中计算 Canvas 数组中位数的有效方法

c++ - GLSL 隔行扫描似乎在 3DTV 上甚至跳过了行

opengl - 计算着色器中的图像原子加法

c - OpenGL 着色器变量传递

ios - Swift 3/Xcode 8 端口后的 Swift 编译器段错误

swift - 选择时更改 uicollectionviewcell 背景,同时将其他单元格背景变为清晰

swift - Spritekit 坐标系意外定位

glsl - GLSL-长度函数