I’m using the image from a second camera as a texture.
To compensate for affine mapping (like this):
I’ve added the following line to the render shader:
gl_Position /= gl_Position.w;
which “works” giving this:
but the texture disappears and I get this visual artifact when the texture is almost outside the camera’s view
instead of this
Anyone have any idea what’s happening and how to fix it (I’m all out of ideas)?
TIA
For completeness:
Vertex shader:
attribute vec3 aPosition;
attribute vec2 aCorners;
attribute vec2 aUv0;
uniform mat4 matrix_model;
uniform mat4 matrix_viewProjection;
varying vec2 vCorners;
varying vec2 vUv0;
uniform float height;
uniform float width;
void main(void) {
vUv0 = aUv0 / vec2(width, height);
vCorners = aCorners;
gl_Position = matrix_viewProjection * matrix_model * vec4(aPosition, 1.0);
gl_Position /= gl_Position.w;
}
Frag shader
precision highp float;
uniform sampler2D uColorBuffer;
uniform float height;
uniform float width;
varying vec2 vUv0;
varying vec2 vCorners;
void main() {
vec2 UVs = vec2(vUv0.x, 1. - vUv0.y);
gl_FragColor = texture2D(uColorBuffer, UVs);
}
Hi @CarlBateman,
I haven’t done something similar before, but it may be the case when doing the perspective division by .w in the vertex shader, when some of the vertices are off screen are clipped incorrectly.
If it’s possible, store the w
component in a varying and do the division in the fragment shader?
vec2 affineUV = vUv0 / vClipW;
Hope it helps.
you can also try sampling your texture using texture2DProj
1 Like
@mvaligursky
Alas
Failed to compile fragment shader:
ERROR: 0:16: 'texture2DProj' : no matching overloaded function found
I strongly suspect the error is on the JavaScript side.
I calculate the on-screen co-ordinates like so:
let toWorldTransform = this.entity.getWorldTransform();
let pos = new pc.Vec3(positions[i], positions[i + 1], positions[i + 2]);
let worldPosition = toWorldTransform.transformPoint(pos);
let screenPosition = camera.worldToScreen(worldPosition);
But one pair of co-ordinates (the right-most) switch sign
Correct
-7280069.912593271, 3877427.9896068643
-7280069.912593273, -3678760.1932197637
231.346458528, 1078.7000162930
231.346458528, -79.3996963762
Wrong
10884949.03334061, -5795229.547305286
10884949.03334061, 5500072.461739768
231.09154364, 1078.829860845
231.09154364, -79.463184058
After extensive testing, the problem is definitely not on the JavaScript side.
So, yeah, not a clue what’s going on. 
bump
I’ve recently returned to this and gone over everything again but still no joy.
So I am again begging for help.
The only other thing I can think of is to try is implementing perspective correct interpolation in the fragment shader, but
- I’m not sure how to do this.
- Supposedly “Modern graphics hardware does this for you without even being asked!”
I’m not entirely sure what you’re trying to do, but if just place a texture you rendered by another camera, there should be no custom shader needed. Here’s an example: PlayCanvas Examples
simply set your texture as an emissive map
The custom shader is to crop out a portion of the source texture and apply it to the target.
to crop out a texture you can use offset and tiling from the texture transform of the material
but I guess even better would be to adjust the FOV / texture resolution when you render the texture, to avoid rendering things outside of the rectangle you need.
Would this work when the target is angled and appears trapezoidal?

yes, same as the example I sent.
Based on your scene I guess you are already following this tutorial, but just in case you are not check this out:
It’s a pretty nice and in depth explanation on how to create portals.
Texture Mapping
should be the relevant chapter for you to get the mapping fixed.
I guess the most difficult thing will be the oblique projection for the camera
Yes. That is one of the primary sources I’m using.
Oblique projection hasn’t really been an issue.
The issue I have is that as the viewer turns the render area suddenly jumps (see the animation below).

Would you mind posting a link to your project, so we can have a look at your implementation?
My project can be found here.
https://playcanvas.com/project/1302512/overview/portal-experiments-review
The particular shader/JS files I’m working on are ApplyAndCropTextureBlue.js, render-target-blue.vert and render-target-blue.frag.
Setting the texture as an emissive map (PlayCanvas | HTML5 Game Engine) gives me this:
I’m unclear as to proceed with either the offset and tiling or FOV / texture resolution approaches.
Do you have any pointers?