Shader texture not working in raytracer

So I’ve been dabbling with shadertoy a lot in the past and have succeeded to port some of my shaders into OF as well successfully. About a year ago I dove into the rabbithole that is ‘raytracing’ and followed some tutorials to create a raytrace engine in shadertoy :slight_smile:

In any case, I managed to get some simple primitives (cubes and spheres) done in the raytracer, and also texture them in shadertoy. I also got the textures working in OF, but unfortunately I lost that source code - I only have the executables left :frowning: I’ve checked all the shader examples and followed the ofBook shader introduction as well with no luck this time around (for the record, I can get a texture rendered, but just not in my raytracing shader code). Maybe I’m missing something really obvious? Here’s my setup and draw code:

void ofApp::setup(){


if(img.load("img.jpg")) {
    cout<<"img loaded!"<<endl;


void ofApp::draw(){
// img.getTexture().bind();
float mousePosition = ofMap(mouseX, 0, ofGetWidth(),500, -500, true);

ofDrawRectangle(0, 0, ofGetWidth(), ofGetHeight());

shader.setUniform1f("iTime", ofGetElapsedTimef());
shader.setUniform2f("iResolution", ofGetWidth(), ofGetHeight());
shader.setUniform1f("mouseX", mousePosition);
shader.setUniformTexture("tex0", img.getTexture(), 1);
img.draw(0, 0);



vert shader:
#version 330
uniform mat4 modelViewProjectionMatrix;
in vec4 position;
in vec2 texcoord;
out vec2 texCoordVarying;

uniform float mouseX;

void main(){
//texCoordVarying = texcoord;
texCoordVarying = vec2(texcoord.x + mouseX, texcoord.y);//texcoord;
gl_Position = modelViewProjectionMatrix * position;

frag shader:
#version 330
uniform sampler2DRect tex0;
uniform float iTime;
uniform vec2 iResolution;
out vec4 outputColor;

in vec2 texCoordVarying;

#define MAX_STEPS 100
#define MAX_DIST 100.
#define SURF_DIST .001

mat2 Rot(float a) {
float s = sin(a);
float c = cos(a);
return mat2(c, -s, s, c);

float dBox(vec3 p, vec3 s) {
p = abs(p)-s;
return length(max(p, 0.))+min(max(p.x, max(p.y, p.z)), 0.);

float GetDist(vec3 p) {
float t = iTime;
// ground plane
float pd = p.y;

// rotating box
vec3 bp = vec3(p.x, p.y, p.z)*.5;
bp -= vec3(0, 0, 0);        // translation

float c = 1.; // multiplier size
vec3 l = vec3(1.); // clamp value - is 3x3
vec3 bq = bp-c*clamp(round(bp/c),-l,l);

float bt = iTime*1.;
vec3 dp = vec3(1);

float box = dBox(bq, dp);

float d = box*.5;
return d; // resize this to get rid of artefacts (step size)


float RayMarch(vec3 ro, vec3 rd) {
float dO=0.;

for(int i=0; i<MAX_STEPS; i++) {
    vec3 p = ro + rd*dO;
    p.xz *= Rot(iTime*.3);      // rotation
    float dS = abs( GetDist(p) );
    dO += dS;
    if(dO>MAX_DIST || dS<SURF_DIST) break;
return dO;


vec3 GetNormal(vec3 p) {
float d = GetDist(p);
vec2 e = vec2(.001, 0);

vec3 n = d - vec3(
return normalize(n);


vec3 R(vec2 uv, vec3 p, vec3 l, float z) {
vec3 f = normalize(l-p),
r = normalize(cross(vec3(0,1,0), f)),
u = cross(f,r),
c = p+fz,
i = c + uv.x
r + uv.y*u,
d = normalize(i-p);
return d;

void main()
vec2 uv = vec2(gl_FragCoord.x-.5iResolution.x, gl_FragCoord.y-.5iResolution.y)/iResolution.y ;
vec2 m = vec2(-1.,1.);//iMouse.xy/iResolution.xy;

vec3 col = vec3(0);

vec3 ro = vec3(0, -9 , 8);//6,-5
ro.yz *= Rot(-m.y+.4);
ro.xz *= Rot(-m.x); // rotate around whole scene

vec3 rd = R(uv, ro, vec3(0,0,0), .7); // point cam at origin
float d = RayMarch(ro, rd);

if(d<MAX_DIST) {
    vec3 p = ro + rd * d;
    p.xz *= Rot(iTime*.3);  //same as object...
    vec3 n = GetNormal(p);

   vec3 colXY = texture(tex0, p.xy*.1+.5).rgb;
   vec3 colXZ = texture(tex0, p.xz*.1+.5).rgb;
   vec3 colYZ = texture(tex0, p.yz*.1+.5).rgb;
    n = abs(n);
    col = colXY*n.z + colXZ*n.y + colYZ*n.x;

outputColor = vec4(col,1.0);

// outputColor = texture(tex0, texCoordVarying); // test directly of texture onscreen


Hey @Maker_Bob , maybe try multiplying by iResolution before sampling tex0 in main():

   vec3 colXY = texture(tex0, iResolution *  p.xy*.1+.5).rgb;
   vec3 colXZ = texture(tex0, iResolution * p.xz*.1+.5).rgb;
   vec3 colYZ = texture(tex0, iResolution * p.yz*.1+.5).rgb;

sampler2DRect tex0 should have non-normalized coordinates, and vec3 p looks like it gets calculated from things that have been normalized.

Also, remember that vec2 texcoord comes into the vertex shader from OF, which happens you call .draw() on something that has texture coordinates. So there should be some provided by img.draw(0, 0), which will also send img into the shader as tex0.

1 Like

That did the trick, thanks!